2

I wanted to train a single layered neural network using the cifar data set and the keras framework. Since each image for the data set is 32 by 32 by 3 I wasn't quite sure how to process the image using a single layered network with no convolution. I think that flattening each image to have a data set of shape N by 32*32*3 is the right thing to do. Thus I did the following:

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

then I just made a single layered network that matched the input dimension:

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

the code seems to compile fine and everything. Thus, is this the correct way to train a single layered Neural Network on an image data set without convolution? I guess the main thing that is throwing me off is that the image is a 3D tensor but a singled layer net would just treat it as a 1D vector regardless of its shape. Right?

Also, since Keras provided a flatten() function it seemed unclear to me if that was a preferred method to use due to efficiency or some other reason. However, I wasn't able to make that one work.

Also, this goes without saying but the softmax layer doesn't really count as another layer. Right? I want it to be single layer.


whole code:

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

1 回答 1

1

You're doing everything right, this is the way if you only want one dense layer. It accepts only 1D tensors so you did well to reshape.

The softmax isn't considered as a layer because it doesnt have any weights or parameters to train.

Just out of curiosity, why do you use relu on the inputs? Aren't they already supposed to be between 0 and 1?

于 2017-02-24T06:17:26.397 回答