2017-02-24 73 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