请对您的想法进行最少的评论,以便我可以改进我的查询。谢谢。-)
我正在使用MNIST
数据集并编写一些CNN
代码。然而,我对CNN
代码中的一些点感到困惑。如何知道神经网络中的层数?根据我目前的理解,我认为这有6层,其中4层是隐藏层。这是对的吗?如果我需要扩展到10层,该怎么做?
from tensorflow.keras.models import Sequentialfrom tensorflow.keras.layers import Dense, Conv2D, Dropout, Flatten, MaxPooling2Dmodel = 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))
回答:
如果你打印你的模型的.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,394Trainable params: 607,394Non-trainable params: 0print(len(model.layers)) # 6
如你所见,你构建了一个有6层的深度神经网络 – 其中一些是可训练
层,还有一些是不可训练
层。所以,如果有人问你模型的层数,它就是简单的6层。
那么,如何扩展或添加更多层呢?这就像往杯子里加水一样简单。就像这样
import tensorflow as tffrom tensorflow.keras.models import Sequentialfrom 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
官方代码示例。
隐藏层这个术语只是早期经常使用的命名约定(据我所知),主要在全连接层(在CNN
之前)。因此,为了简单起见,我会说就忘记这个术语。我们应该将层称为可训练
和不可训练
,这在现在更有意义。
在你的模型中,第一个CNN
(可训练层),第二个MaxPool2D
(不可训练),第三个Flatten
(不可训练),第四个Dense
(可训练),第五个Dropout
(不可训练),最后是第六个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
层时隐式存在。所以,如果我们严格按照隐藏层的命名约定来看,我们可以说,在你的模型中,有5个隐藏层(从第一个Conv2D
到Dropout
)。输入层隐式存在,输出层是最后一个Dense
层。