我问这个问题是因为我觉得自己错过了某些基本的东西。
现在大多数人都知道MNIST图像是28×28像素的。Keras的文档告诉了我关于Dense的信息:
输入形状为nD张量,形状为:(batch_size, …, input_dim)。最常见的情况是形状为(batch_size, input_dim)的2D输入。
所以像我这样的新手会认为图像可以作为28×28的矩阵输入到模型中。然而,我找到的每个教程都通过各种方法将图像转换为一个784长的特征向量。
有时候通过
num_pixels = X_train.shape[1] * X_train.shape[2]model.add(Dense(num_pixels, input_dim=num_pixels, activation='...'))
或者
num_pixels = np.prod(X_train.shape[1:])model.add(Dense(512, activation='...', input_shape=(num_pixels,)))
或者
model.add(Dense(units=10, input_dim=28*28, activation='...'))history = model.fit(X_train.reshape((-1,28*28)), ...)
甚至是:
model = Sequential([Dense(32, input_shape=(784,)), ...),])
所以我的问题很简单 – 为什么?Dense不能直接接受图像,或者如果需要的话,是否可以“在幕后”处理它?如果像我猜测的那样,必须进行这种处理,这些方法(或其他方法)中是否有任何一种方法本质上更可取?
回答:
根据原帖者的请求,我将提到我在评论中给出的答案并进一步详细说明。
Dense不能直接接受图像,或者如果需要的话,是否可以“在幕后”处理它?
答案是不能!这是因为目前Dense层是在最后一个轴上应用的。因此,如果你输入一个形状为(height, width)
或(height, width, channels)
的图像,Dense层只会在最后一个轴(即宽度或通道)上应用。然而,当图像被展平时,Dense层中的所有单元将应用于整个图像,每个单元与所有像素以不同的权重连接。为了进一步澄清这一点,请考虑这个模型:
model = models.Sequential()model.add(layers.Dense(10, input_shape=(28*28,)))model.summary()
模型摘要:
Layer (type) Output Shape Param # =================================================================dense_2 (Dense) (None, 10) 7850 =================================================================Total params: 7,850Trainable params: 7,850Non-trainable params: 0_________________________________________________________________
如你所见,Dense层中有7850个参数:每个单元都连接到所有像素(28*28*10 + 10个偏置参数 = 7850)。现在考虑这个模型:
model = models.Sequential()model.add(layers.Dense(10, input_shape=(28,28)))model.summary()
模型摘要:
_________________________________________________________________Layer (type) Output Shape Param # =================================================================dense_3 (Dense) (None, 28, 10) 290 =================================================================Total params: 290Trainable params: 290Non-trainable params: 0_________________________________________________________________
在这种情况下,Dense层中只有290个参数。这里,Dense层中的每个单元也连接到所有像素,但不同的是权重在第一个轴上是共享的(28*10 + 10个偏置参数 = 290)。这就像是从图像的每一行提取特征,与前一个模型相比,前一个模型是从整个图像中提取特征。因此,这种权重共享对于你的应用可能有用,也可能没用。