2017-02-24 140 views
2

我想使用cifar數據集和keras框架來訓練單層神經網絡。由於數據集的每個圖像是32乘3乘3,我不太確定如何使用沒有卷積的單層網絡處理圖像。我認爲將每個圖像展平成具有N by 32*32*3形狀的數據集是正確的選擇。因此,我做了以下內容:如何用Cifar在Keras中訓練單層神經網絡?

#Flatten 
X_train = X_train.reshape((X_train.shape[0],32*32*3)) 
X_test = X_test.reshape((X_test.shape[0],32*32*3)) 

然後我就做匹配的輸入尺寸的單層網:

model.add(Dense(units_single_layer, input_shape=(32*32*3,))) 
model.add(Activation('relu')) 
model.add(Dense(nb_classes)) 
model.add(Activation('softmax')) 

代碼看起來編譯很好,一切。因此,這是在沒有卷積的圖像數據集上訓練單層神經網絡的正確方法嗎?我猜想讓我失望的主要原因是圖像是一個3D張量,但是一個單層網絡將它視爲一維矢量而不管其形狀如何。對?

此外,由於Keras提供了一個flatten()函數,因此似乎不清楚這是否是因效率或其他原因而使用的首選方法。但是,我無法完成這一項工作。

此外,這不言而喻,但softmax層並不真正算作另一層。對?我想想要它是單層。


整個代碼:

from __future__ import print_function 
from keras.datasets import cifar10 
from keras.preprocessing.image import ImageDataGenerator 
from keras.models import Sequential 
from keras.layers import Dense, Dropout, Activation, Flatten 
from keras.layers import Convolution2D, MaxPooling2D 
from keras.utils import np_utils 

batch_size = 32 
nb_classes = 10 
units_single_layer = 100 
nb_epoch = 200 
data_augmentation = False 

# input image dimensions 
img_rows, img_cols = 32, 32 
# The CIFAR10 images are RGB. 
img_channels = 3 
# The data, shuffled and split between train and test sets: 
(X_train, y_train), (X_test, y_test) = cifar10.load_data() 
#Flatten 
X_train = X_train.reshape((X_train.shape[0],32*32*3)) 
X_test = X_test.reshape((X_test.shape[0],32*32*3)) 

# Convert class vectors to binary class matrices. 
Y_train = np_utils.to_categorical(y_train, nb_classes) 
Y_test = np_utils.to_categorical(y_test, nb_classes) 

model = Sequential() 

#model.add(Flatten(input_shape=32*32*3)) 
#model.add(Flatten()) 
#model.add(Flatten(100, input_shape=(32*32*3,))) 
model.add(Dense(units_single_layer, input_shape=(32*32*3,))) 
model.add(Activation('relu')) 
model.add(Dense(nb_classes)) 
model.add(Activation('softmax')) 

# Let's train the model using RMSprop 
model.compile(loss='categorical_crossentropy', 
       optimizer='rmsprop', 
       metrics=['accuracy']) 

X_train = X_train.astype('float32') 
X_test = X_test.astype('float32') 
X_train /= 255 
X_test /= 255 

print('Not using data augmentation.') 
model.fit(X_train, Y_train, 
      batch_size=batch_size, 
      nb_epoch=nb_epoch, 
      validation_data=(X_test, Y_test), 
      shuffle=True) 
+0

你有2層,輸入和輸出。只需指定一個像密集(nb_classes,input_dim =(32 * 32 * 3))。我不認爲你需要指定形狀,因爲它是一維矢量。 – Atirag

+0

你會仍然upvote答案,告訴我如何使用keras平坦。 – Pinocchio

回答

1

你做的一切權利,這就是這樣,如果你只想要一個緻密層。它只接受一維張量,所以你做好了重塑。

softmax不被視爲一個圖層,因爲它沒有任何要訓練的權重或參數。

出於好奇,你爲什麼在輸入上使用relu?他們不是應該在0和1之間嗎?

+0

我把relu的,因爲我想要一些非線性層,否則似乎網絡只能計算平凡的線性事物。我可以使用S形等,但似乎relu有更好的訓練屬性(隨機)梯度下降像方法。 – Pinocchio

+0

relu根本不會混合你的變量,也不會訓練。它不是一個智能層,僅僅因爲它是非線性的,它只會通過將負值替換爲0來修改您的輸入,並且會使所有其他值保持不變。如果你想要更復雜的關係,你只需要添加更多的圖層。 –

+0

我想比較一個單層ReLu網絡與2層ReLu網絡。爲了進行比較,我需要定義至少一層非線性。具有非線性層使其成爲非通用逼近器,因此它仍然能夠表達任何函數。 – Pinocchio