Search code examples
pythonarchitectureconv-neural-networkvalueerror

Convolutional Neural Net Architecture - correct?


I am trying to train a convolutional neural net. Therefore I am using a datset of 646 images/license plates which contains 8 characters (0-9, A-Z; without letter 'O' and blank spaces, in total 36 possible characters). These are my training data X_train. Their shape is (646, 40, 200, 3) with color code 3. I resized them to the same shape.

I also have a dataset which contains the labels of this images, which I one-hot-encoded to a numpy array of shape (646, 8, 36). This data is my y_train data.

Now, I am trying to apply a Neural Network which looks like this: Architecture The architecture is taken from this paper: https://ieeexplore.ieee.org/abstract/document/8078501

I excluded the batch normalization part, because this part is not the most interesting one for me. But I am very unsure regarding the top of the layer. That means the part after the last pooling layer beginning with model.add(Flatten())...

model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), input_shape = (40, 200, 3), activation = "relu"))
model.add(Conv2D(32, kernel_size=(3, 3), activation = "relu"))
model.add(Conv2D(32, kernel_size=(3, 3), activation = "relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, kernel_size=(3, 3), activation = "relu"))
model.add(Conv2D(64, kernel_size=(3, 3), activation = "relu"))
model.add(Conv2D(64, kernel_size=(3, 3), activation = "relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, kernel_size=(3, 3), activation = "relu"))
model.add(Conv2D(128, kernel_size=(3, 3), activation = "relu"))
model.add(Conv2D(128, kernel_size=(3, 3), activation = "relu"))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(16000, activation = "relu"))
model.add(Dense(128, activation = "relu"))
model.add(Dense(36, activation = "relu"))
model.add(Dense(8*36, activation="Softmax"))
model.add(keras.layers.Reshape((8, 36)))

Thank you very much in advance!


Solution

  • Assuming the image below matches your model architecture, the code can be used to create the model. Ensure you have some padding for the input images.

    Model Architecture

    import tensorflow as tf
    from tensorflow.keras.models import Sequential, Model
    from tensorflow.keras.layers import Conv2D, Flatten, MaxPooling2D, Dense, Input, Reshape, Concatenate
    
    def create_model(input_shape = (40, 200, 3)):
        input_img = Input(shape=input_shape)
        model = Conv2D(32, kernel_size=(3, 3), input_shape = (40, 200, 3), activation = "relu")(input_img)
        model = Conv2D(32, kernel_size=(3, 3), padding="same", activation = "relu")(model)
        model = Conv2D(32, kernel_size=(3, 3), padding="same", activation = "relu")(model)
        model = MaxPooling2D(pool_size=(2, 2))(model)
        model = Conv2D(64, kernel_size=(3, 3), padding="same", activation = "relu")(model)
        model = Conv2D(64, kernel_size=(3, 3), padding="same", activation = "relu")(model)
        model = Conv2D(64, kernel_size=(3, 3), padding="same", activation = "relu")(model)
        model = MaxPooling2D(pool_size=(2, 2))(model)
        model = Conv2D(128, kernel_size=(3, 3), padding="same", activation = "relu")(model)
        model = Conv2D(128, kernel_size=(3, 3), padding="same", activation = "relu")(model)
        model = Conv2D(128, kernel_size=(3, 3), padding="same", activation = "relu")(model)
        model = MaxPooling2D(pool_size=(2, 2))(model)
        backbone = Flatten()(model)
    
        branches = []
        for i in range(8):
            branches.append(backbone)
            branches[i] = Dense(16000, activation = "relu", name="branch_"+str(i)+"_Dense_16000")(branches[i])
            branches[i] = Dense(128, activation = "relu", name="branch_"+str(i)+"_Dense_128")(branches[i])
            branches[i] = Dense(36, activation = "softmax", name="branch_"+str(i)+"_output")(branches[i])
        
        output = Concatenate(axis=1)(branches)
        output = Reshape((8, 36))(output)
        model = Model(input_img, output)
    
        return model