我在Keras中训练了两个卷积神经网络。第一个网络如下
def VGG1(weights_path): model = Sequential() model.add(Convolution2D(nb_filters, nb_conv, nb_conv, border_mode='valid', input_shape=(1, img_rows, img_cols))) model.add(Activation('relu')) model.add(Convolution2D(nb_filters, nb_conv, nb_conv)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(128)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(nb_classes)) model.add(Activation('softmax')) if weights_path: model.load_weights(weights_path) return model
第二个网络
def VGG2(weights_path): model = Sequential() model.add(Convolution2D(nb_filters, nb_conv, nb_conv, border_mode='valid', input_shape=(1, img_rows, img_cols))) model.add(Activation('relu')) model.add(Convolution2D(nb_filters, nb_conv, nb_conv)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool))) model.add(Dropout(0.25)) model.add(Convolution2D(64, nb_conv, nb_conv, border_mode='valid')) model.add(Activation('relu')) model.add(Convolution2D(64, nb_conv, nb_conv)) model.add(Activation('relu')) model.add(MaxPooling2D(pool_size=(nb_pool, nb_pool))) model.add(Dropout(0.25)) model.add(Flatten()) model.add(Dense(256)) model.add(Activation('relu')) model.add(Dropout(0.5)) model.add(Dense(nb_classes)) model.add(Activation('softmax')) if weights_path: model.load_weights(weights_path) return model
当我调用model.count_params()
方法时,第一个网络的结果是604035个参数,而第二个网络的结果是336387个参数。
这是怎么可能的?第二个网络更深,应该包含更多的参数。有什么错误吗?
回答:
是的,更深的神经网络可以拥有更少的参数。这与它们是否是卷积神经网络无关。你可能会感到困惑,因为在图形表示中,人们往往关注神经元。然而,真正被学习的是权重,这些权重位于神经元之间的边上。
除了链接到“深度残差学习用于图像识别”(请为Midos的回答投票),我想给出一个多层感知机(MLP)的玩具示例。
玩具示例:瓶颈特征
第一个MLP有一个输入层,包含784个神经元,两个隐藏层,每层包含2000个神经元,以及一个输出层,包含10个神经元(简称784:2000:2000:10)。这导致了一个网络,包含个神经元。现在考虑一个网络,架构为784:2000:50:2000:10。这个网络包含
个神经元。
这意味着添加另一层,即使没有减少任何层的尺寸,也将网络的大小减少到了之前的32%!