在Keras的Conv2D和Dense期间,数据如何变化?

Mic*_*bie 5 python machine-learning flatten conv-neural-network keras

正如标题所说.此代码仅适用于:

x = Flatten()(x)
Run Code Online (Sandbox Code Playgroud)

在卷积层和密集层之间.

import numpy as np
import keras
from keras.models import Sequential, Model
from keras.layers import Dense, Dropout, Flatten, Input
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD

# Generate dummy data
x_train = np.random.random((100, 100, 100, 3))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)

#Build Model
input_layer = Input(shape=(100, 100, 3))
x = Conv2D(32, (3, 3), activation='relu')(input_layer)
x = Dense(256, activation='relu')(x)
x = Dense(10, activation='softmax')(x)
model = Model(inputs=[input_layer],outputs=[x])

#compile network
sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)

#train network
model.fit(x_train, y_train, batch_size=32, epochs=10)
Run Code Online (Sandbox Code Playgroud)

否则,我收到此错误:

Traceback (most recent call last):

File "/home/michael/practice_example.py", line 44, in <module>
    model.fit(x_train, y_train, batch_size=32, epochs=10)

File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1435, in fit
    batch_size=batch_size)

File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 1315, in _standardize_user_data
    exception_prefix='target')

File "/usr/local/lib/python2.7/dist-packages/keras/engine/training.py", line 127, in _standardize_input_data
    str(array.shape))

ValueError: Error when checking target: expected dense_2 to have 4 dimensions, but got array with shape (100, 10)
Run Code Online (Sandbox Code Playgroud)

为什么输出在没有flatten()图层的情况下有4个尺寸?

fra*_*ang 7

根据keras doc,

Conv2D输出形状

4D张量与形状:(样本,过滤器,new_rows,new_cols)如果data_format ='channels_first'或4D张量与形状:(samples,new_rows,new_cols,filters)如果data_format ='channels_last'.由于填充,行和列值可能已更改.

由于您使用channels_last,图层输出的形状将是:

# shape=(100, 100, 100, 3)

x = Conv2D(32, (3, 3), activation='relu')(input_layer)
# shape=(100, row, col, 32)

x = Flatten()(x)
# shape=(100, row*col*32)    

x = Dense(256, activation='relu')(x)
# shape=(100, 256)

x = Dense(10, activation='softmax')(x)
# shape=(100, 10)
Run Code Online (Sandbox Code Playgroud)

错误说明(编辑,感谢@Marcin)

使用Dense图层将4D张量(shape =(100,row,col,32))与2D图像(shape =(100,256))相关联仍将形成4D张量(shape =(100,row,col,256) )这不是你想要的.

# shape=(100, 100, 100, 3)

x = Conv2D(32, (3, 3), activation='relu')(input_layer)
# shape=(100, row, col, 32)

x = Dense(256, activation='relu')(x)
# shape=(100, row, col, 256)

x = Dense(10, activation='softmax')(x)
# shape=(100, row, col, 10)
Run Code Online (Sandbox Code Playgroud)

并且当输出4D张量和目标2D张量之间的不匹配发生时将发生错误.

这就是为什么你需要一个Flatten层来将它从4D平移到2D.

参考

Conv2D Dense