簡體   English   中英

在Keras的Conv2D和Dense期間,數據如何變化?

[英]How does data shape change during Conv2D and Dense in Keras?

正如標題所說。 此代碼僅適用於:

x = Flatten()(x)

在卷積層和密集層之間。

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)

否則,我收到此錯誤:

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)

為什么輸出有4個尺寸而沒有flatten()層?

根據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)

錯誤說明(編輯,感謝@Marcin)

使用Dense層將4D張量(shape =(100,row,col,32))鏈接到2D(tens =(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)

並且當輸出4D張量和目標2D張量之間的不匹配發生時將發生錯誤。

這就是為什么你需要一個Flatten層來將它從4D平移到2D。

參考

Conv2D Dense

Dense文檔中可以看出,如果對Dense的輸入具有兩個以上的維度 - 它僅應用於最后一個維度 - 並且保留所有其他維度:

# 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)

這就是預期4d目標的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM