Keras model.summary() 结果 - 了解参数的数量

Posted

技术标签:

【中文标题】Keras model.summary() 结果 - 了解参数的数量【英文标题】:Keras model.summary() result - Understanding the # of Parameters 【发布时间】:2016-08-25 02:33:50 【问题描述】:

我有一个简单的 NN 模型,用于检测使用 Keras(Theano 后端)用 python 编写的 28x28px 图像中的手写数字:

model0 = Sequential()

#number of epochs to train for
nb_epoch = 12
#amount of data each iteration in an epoch sees
batch_size = 128

model0.add(Flatten(input_shape=(1, img_rows, img_cols)))
model0.add(Dense(nb_classes))
model0.add(Activation('softmax'))
model0.compile(loss='categorical_crossentropy', 
         optimizer='sgd',
         metrics=['accuracy'])

model0.fit(X_train, Y_train, batch_size=batch_size, nb_epoch=nb_epoch,
      verbose=1, validation_data=(X_test, Y_test))

score = model0.evaluate(X_test, Y_test, verbose=0)

print('Test score:', score[0])
print('Test accuracy:', score[1])

这运行良好,我的准确率约为 90%。然后我执行以下命令,通过执行print(model0.summary()) 来获取我的网络结构的摘要。这将输出以下内容:

Layer (type)         Output Shape   Param #     Connected to                     
=====================================================================
flatten_1 (Flatten)   (None, 784)     0           flatten_input_1[0][0]            
dense_1 (Dense)     (None, 10)       7850        flatten_1[0][0]                  
activation_1        (None, 10)          0           dense_1[0][0]                    
======================================================================
Total params: 7850

我不明白他们是如何达到 7850 个总参数的,这实际上意味着什么?

【问题讨论】:

快速说明:nb_classes 应该是 10(这是一个有 10 个类的多类问题)。 OP 中没有在这里提到它,但在这个问题的答案中的其他地方有几个地方提到了它。 【参考方案1】:

参数数量为 7850,因为对于每个隐藏单元,您有 784 个输入权重和一个带偏差的连接权重。这意味着每个隐藏单元都会为您提供 785 个参数。您有 10 个单位,因此总计为 7850。

这个附加偏差项的作用非常重要。它显着增加了模型的容量。您可以阅读详细信息,例如这里Role of Bias in Neural Networks。

【讨论】:

快速说明我们如何拥有 784. 784 = 28x28,因为图像大小为 28*28。【参考方案2】:

对于密集层:

output_size * (input_size + 1) == number_parameters 

对于转换层:

output_channels * (input_channels * window_size + 1) == number_parameters

考虑下面的例子,

model = Sequential([
Conv2D(32, (3, 3), activation='relu', input_shape=input_shape),
Conv2D(64, (3, 3), activation='relu'),
Conv2D(128, (3, 3), activation='relu'),
Dense(num_classes, activation='softmax')
])

model.summary()
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 222, 222, 32)      896       
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 220, 220, 64)      18496     
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 218, 218, 128)     73856     
_________________________________________________________________
dense_9 (Dense)              (None, 218, 218, 10)      1290      
=================================================================

计算参数,

assert 32 * (3 * (3*3) + 1) == 896
assert 64 * (32 * (3*3) + 1) == 18496
assert 128 * (64 * (3*3) + 1) == 73856
assert num_classes * (128 + 1) == 1290

【讨论】:

阅读此答案的任何人请注意:这些层是基于 [28x28x3](RGB 输入)的输入大小而不是具有单个输入通道的 OP 构建的。 @Andrew 你能在这里解释一下输出形状值的计算吗?【参考方案3】:

参数数量是模型中可以更改的数量。从数学上讲,这意味着优化问题的维数。对于作为程序员的你来说,每个参数都是一个浮点数,通常占用 4 字节的内存,让你可以在保存后预测这个模型的大小。

这个数字的公式对于每个神经网络层类型都不同,但对于密集层来说很简单:每个神经元都有一个偏置参数和每个输入一个权重: N = n_neurons * ( n_inputs + 1).

【讨论】:

【参考方案4】:

计算一层中神经元数量的最简单方法是: 参数值/(单位数*4)

单元数在predictivemodel.add(Dense(514,...)中 参数值是model.summary()函数中的参数

例如Paul Lo的回答中,一层的神经元个数是264710 / (514 * 4) = 130

【讨论】:

【参考方案5】:

我将 514 维实值输入提供给 Keras 中的 Sequential 模型。 我的模型是按以下方式构建的:

    predictivemodel = Sequential()
    predictivemodel.add(Dense(514, input_dim=514, W_regularizer=WeightRegularizer(l1=0.000001,l2=0.000001), init='normal'))
    predictivemodel.add(Dense(257, W_regularizer=WeightRegularizer(l1=0.000001,l2=0.000001), init='normal'))
    predictivemodel.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])

当我打印 model.summary() 时,我得到以下结果:

Layer (type)    Output Shape  Param #     Connected to                   
================================================================
dense_1 (Dense) (None, 514)   264710      dense_input_1[0][0]              
________________________________________________________________
activation_1    (None, 514)   0           dense_1[0][0]                    
________________________________________________________________
dense_2 (Dense) (None, 257)   132355      activation_1[0][0]               
================================================================
Total params: 397065
________________________________________________________________ 

对于 dense_1 层,参数数量为 264710。 得到为:514(输入值)* 514(第一层中的神经元)+ 514(偏差值)

对于dense_2层,参数数量为132355。 得到:514(输入值)* 257(第二层神经元)+ 257(第二层神经元的偏差值)

【讨论】:

【参考方案6】:

形状中的“无”表示它没有预定义的数字。例如,它可以是您在训练期间使用的批量大小,并且您希望通过不为其分配任何值来使其灵活,以便您可以更改批量大小。模型将根据图层的上下文推断形状。

要让节点连接到每一层,您可以执行以下操作:

for layer in model.layers:
    print(layer.name, layer.inbound_nodes, layer.outbound_nodes)

【讨论】:

以上是关于Keras model.summary() 结果 - 了解参数的数量的主要内容,如果未能解决你的问题,请参考以下文章

model.summary() 在使用子类模型时无法打印输出形状

获取keras中间层输出模型保存与加载

Keras:找出层数

Tensorflow TextVectorization 在 model.summary() 中带来 None 形状

keras中Convolution1D的使用

Tensorflow tf.keras.models.load_model() 打开h5文件失败