我正在尝试理解Keras中Flatten
函数的作用。下面是我的代码,这是一个简单的两层网络。它接受形状为(3, 2)的二维数据,并输出形状为(1, 4)的一维数据:
model = Sequential()model.add(Dense(16, input_shape=(3, 2)))model.add(Activation('relu'))model.add(Flatten())model.add(Dense(4))model.compile(loss='mean_squared_error', optimizer='SGD')x = np.array([[[1, 2], [3, 4], [5, 6]]])y = model.predict(x)print y.shape
这会打印出y
的形状为(1, 4)。然而,如果我删除Flatten
这一行,那么它会打印出y
的形状为(1, 3, 4)。
我不明白这是为什么。根据我对神经网络的理解,model.add(Dense(16, input_shape=(3, 2)))
函数创建了一个完全连接的隐藏层,包含16个节点。这些节点中的每一个都连接到3×2输入元素中的每一个。因此,这个第一层的16个输出节点已经是“扁平”的。所以,第一层的输出形状应该是(1, 16)。然后,第二层以此为输入,输出形状为(1, 4)的数据。
那么,如果第一层的输出已经是“扁平”的,并且形状为(1, 16),为什么我还需要进一步扁平化它呢?
回答:
如果你阅读Keras文档中关于Dense
的条目,你会看到这样的调用:
Dense(16, input_shape=(5,3))
会生成一个Dense
网络,具有3个输入和16个输出,这些输出将独立应用于5个步骤。因此,如果D(x)
将3维向量转换为16维向量,你从这一层得到的输出将是一系列向量:[D(x[0,:]), D(x[1,:]),..., D(x[4,:])]
,形状为(5, 16)
。为了达到你指定的行为,你可以先将输入Flatten
成一个15维向量,然后应用Dense
:
model = Sequential()model.add(Flatten(input_shape=(3, 2)))model.add(Dense(16))model.add(Activation('relu'))model.add(Dense(4))model.compile(loss='mean_squared_error', optimizer='SGD')
编辑:由于一些人难以理解,这里有一张解释性的图片: