I trained a simple classifier to detect whether or not an image contains a lane line.
model = Sequential()
model.add(Reshape((image_size[1], image_size[0], 3), input_shape=input_shape))
model.add(Convolution2D(32, 3, 3,
border_mode='valid'))
model.add(Activation('relu'))
model.add(Convolution2D(32, 3, 3))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=pool_size))
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(2))
model.add(Activation('softmax'))
This classifier converged at an accuracy of 98%. Not bad!
After reading this paper, and some related topics on here, I replaced the fully connected (Dense) layers with convolutional ones.
model = Sequential()
#model.add(Reshape((image_size[1], image_size[0], 3), input_shape=input_shape))
model.add(Convolution2D(32, 3, 3, border_mode='same', input_shape=input_shape,
name='conv1-1', activation='relu'))
model.add(Convolution2D(32, 3, 3, border_mode='same',
name='conv1-2', activation='relu'))
model.add(MaxPooling2D(pool_size=pool_size))
'''
model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(2))
model.add(Activation('softmax'))
'''
model.add(Dropout(0.25))
model.add(Convolution2D(256, 90, 160, activation='relu', name='conv7'))
model.add(Dropout(0.5))
model.add(Convolution2D(2, 1, 1))
model.add(Flatten())
model.add(Activation('softmax'))
This classifier converged at an accuracy of 49%. I would be better off flipping a coin. Based on what I've read, the two should be equivalent - a convolution over the entire input is the same thing as a fully connected layer.
I made three notable changes.
- As stated, convolutionalizing the fully connected layers. I think I understand this but it's entirely possible I didn't implement it properly.
- Removing the Reshape() layer at the beginning. I'm not sure why it was there to begin with - ImageDataGenerator already returns images in the desired format (height, width, channels).
- Changing the neurons in the first fully connected layer / convolution over the entire input from 128 to 256.
Can anyone identify what I did wrong?