请对您的想法添加最少的注释,这样我就可以改进我的查询了。谢谢。-(
我正在处理MNIST
数据集并编写一些CNN
代码。然而,我对CNN
代码的一些要点感到困惑。如何知道神经网络的层数?根据我目前的理解,我认为这有6层和4层隐藏层。是这样吗?如果我需要扩展到10层呢?怎么做?
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Dropout, Flatten, MaxPooling2D
model = Sequential()
model.add(Conv2D(28, kernel_size=(3,3),
input_shape = ...))
model.add(MaxPooling2D(pool_size=(2,2)))
model.add(Flatten())
model.add(Dense(128, activation=tf.nn.relu))
model.add(Dropout(0.2))
model.add(Dense(10, activation=tf.nn.softmax))
在计算神经网络中的层数时,我们通常只计算卷积层和全连接层。池化层与卷积层一起被视为一层,Dropout是一种正则化技术,因此它也不会被视为单独的层。
作为参考,VGG16模式被定义为16层模型。这16层只是卷积层和全连通稠密层。如果计算所有的池化和激活层,它将变为41层模型,而事实并非如此。参考:VGG16、VGG16纸张
因此,根据您的代码,您有3层(1层包含28个神经元的卷积层,1层包含128个神经元的全连接层和1层包含10个神经元的完全连接层(
至于使其成为10层网络,您可以在输出层之前添加更多的卷积层或密集层,但对于MNIST数据集来说,这是不必要的。
如果打印模型的.summary()
,则会得到
Model: "sequential_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d_1 (Conv2D) (None, 26, 26, 28) 280
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 13, 13, 28) 0
_________________________________________________________________
flatten_1 (Flatten) (None, 4732) 0
_________________________________________________________________
dense (Dense) (None, 128) 605824
_________________________________________________________________
dropout (Dropout) (None, 128) 0
_________________________________________________________________
dense_1 (Dense) (None, 10) 1290
=================================================================
Total params: 607,394
Trainable params: 607,394
Non-trainable params: 0
print(len(model.layers)) # 6
正如您所看到的,您构建了一个由6层组成的深度神经网络,其中一些层是trainable
层,另一些是non-trainable
层。因此,如果有人问你模型的层数,答案只是6。
以及如何在其中扩展或添加更多层。这很简单,就像往杯子里加水一样。像这个
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import (Dense, Conv2D, Dropout,
Flatten, MaxPooling2D, BatchNormalization)
model = Sequential()
model.add(Conv2D(16, kernel_size=(3,3),
input_shape = (28,28,1)))
model.add(Conv2D(32, kernel_size=(3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, kernel_size=(3, 3), activation="relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(128, activation=tf.nn.relu))
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Dense(10, activation=tf.nn.softmax))
model.summary()
print(len(model.layers)) # 10
现在,请注意这一点,尽管使用tf. keras
(或像pytorch
这样的另一个框架(我们可以很容易地做这些事情,但我们应该考虑我们正在做什么以及为了什么。我不会对此做太多描述,因为这超出了这个问题的范围。但我强烈建议您查看tf. keras
的官方代码示例。
术语隐藏层只是早期经常使用的命名约定(AFAIK(,主要用于 全连接层在您的模型中,第1个 无论预期的 这仅仅是汇集来自那些 隐藏层简单地指在深度神经网络中位于输入层和输出之间的层。但在您的模型中,第一层CNN
(可训练层(、第2个MaxPool2D
(不可训练(、第3个Flatten
(不可培训(、第4个Dense
(可训练(和第5个Dropout
(不可学习(,最后是第6个Dense
(可培训(。你也可以在model. summary()
中看到Param #
列,那些是不可训练层的人,他们的参数是零——该层中没有可训练变量。比方说,在你的模型中,第一层声明为,model.add(Conv2D(28, kernel_size=(3,3),
input_shape = ...))
input_shape
是什么,都在输入上通过3 x 3
大小的滤波器(总共28
(并进行卷积并产生一些特征图。因此,在这一层的末尾,我们将得到总共28
个特征图。下一层model.add(MaxPooling2D(pool_size=(2,2)))
28
特征图的最大值,而不是其他。所以没有计算运算——这就是为什么参数是不可训练的。Conv2D
是一个隐藏层,它不是输入层。这里,当我们将input_shape
自变量传递给第一个Conv2D
层时,输入层是隐式存在的。因此,如果我们具体采用Hidden Layer命名约定,我们可以说,在您的模型中,有5隐藏层(从第一个Conv2D
到Dropout
(。输入层是隐式存在的,输出层是最后一个Dense
层。