Reputation: 5201
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)
Upvotes: 2
Views: 2701
Reputation: 11553
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?
Upvotes: 1