Keras模型.summary()结果 - 理解参数数量

78

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

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个总参数的,以及这实际上意味着什么?


2
一个快速的提示:nb_classes 应该是10(这是一个有10个类别的多类问题)。虽然在 OP 中没有提到,但在回答此问题的其他地方中多次提到。 - edesz
6个回答

50

由于每个隐藏单元都有784个输入权重和一个与偏差相连的权重,因此参数数量为7850。这意味着每个隐藏单元会给出785个参数。由于您有10个单元,因此总共有7850个参数。

这个额外的偏差项的作用非常重要。它显著增加了模型的容量。您可以在这里阅读详细信息:神经网络中偏差的作用


8
关于784的说明。784 = 28x28,因为图像大小是28*28。 - user3282611

28

我在Keras中向一个Sequential模型提供了一个514维的实值输入。 我的模型是按照以下方式构建的:

    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(第二层神经元的偏置值)。

19

对于密集层:

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

6
注意:阅读此回答的任何人都应知道,这些层是基于输入大小为[28x28x3](RGB输入),而不是OP(原帖作者)只有单个输入通道。 - Andrew
2
@Andrew,你能否解释一下这里的输出形状值计算? - Aashish Amber

8

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

要获取连接到每个层的节点,可以执行以下操作:

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

3

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

每种神经网络层类型的参数数量公式都不同,但对于 Dense 层而言,它很简单:每个神经元有一个偏置参数和一个针对输入的权重: N = n_neurons * (n_inputs + 1)


2
计算一个层中神经元数量的最简单方法是: Param value / (number of units * 4)
其中:
- number of units 是在 predictivemodel.add(Dense(514,...) 中的单位数 - Param value 是 model.summary() 函数中的参数值
例如,在 Paul Lo 的答案中,一个层中的神经元数量为 264710 / (514 * 4) = 130。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接