Проблема модели распознавания номерного знака без сегментации - PullRequest
0 голосов
/ 01 мая 2020

Наша команда стремится создать модель для распознавания номерного знака без сегментации, со следующей архитектурой:

Model architecture

Мы успешно реализовали большинство из архитектура, но мы боремся с подключением 8 ветвей полностью связанных слоев (каждая из которых для одного символа номерного знака).

Есть ли способ использовать один и тот же вход (тензор 25x5x128) для каждого из 8 ветвей, и пусть они работают независимо и сравнивают свои результаты независимо с соответствующей основной буквой истинности номерного знака и puni sh (функция потерь), на основании которых буквы были неправильными?

Мы пробовали несколько подходов используя модели keras (как последовательный, так и API класса Model), но безуспешно. Ниже наша текущая версия модели. Мы будем очень благодарны за любую помощь.

model = models.Sequential()

model.add(layers.Conv2D(32, (3, 3), use_bias=False, input_shape=(32, 32, 3),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Activation("relu"))
model.add(layers.Conv2D(32, (3, 3), use_bias=False, input_shape=(32, 32, 3),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Activation("relu"))
model.add(layers.Conv2D(32, (3, 3), use_bias=False, input_shape=(32, 32, 3),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Activation("relu"))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(64, (3, 3), use_bias=False, input_shape=(100, 20, 32),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Activation("relu"))
model.add(layers.Conv2D(64, (3, 3), use_bias=False, input_shape=(100, 20, 32),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Activation("relu"))
model.add(layers.Conv2D(64, (3, 3), use_bias=False, input_shape=(100, 20, 32),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Activation("relu"))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(128, (3, 3), use_bias=False, input_shape=(50, 10, 64),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Activation("relu"))
model.add(layers.Conv2D(128, (3, 3), use_bias=False, input_shape=(50, 10, 64),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Activation("relu"))
model.add(layers.Conv2D(128, (3, 3), use_bias=False, input_shape=(50, 10, 64),padding='same'))
model.add(layers.BatchNormalization())
model.add(layers.Activation("relu"))
model.add(layers.MaxPooling2D((2, 2)))


model.add(layers.Flatten())


branch1 = models.Sequential()

branch1 .add(layers.Dense(128, input_shape=(16000,)))
branch1.add(layers.Dense(36, input_shape=(128,)))
branch1.add(layers.Activation("softmax"))

# Another 7 branches follows with exact same definition

final_model = keras.Model(inputs=[model, model, model, model, model, model, model, model],
                          outputs=[branch1, branch2, branch3, branch4, branch5, branch6, branch7, branch8])


final_model.compile(tf.keras.optimizers.Adam(learning_rate=0.001),
        loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
        metrics=['accuracy'])

history = final_model.fit(train_images, train_labels, epochs=80,
                          validation_data=(test_images, test_labels))

1 Ответ

1 голос
/ 02 мая 2020

это фиктивный пример

inp_dim = (32, 32, 3)
x_inp = Input(shape=inp_dim)
x = Conv2D(32, (3, 3), use_bias=False, padding='same')(x_inp)
x = BatchNormalization()(x)
x = Activation("relu")(x)
x = MaxPooling2D((2, 2))(x)
x_out = Flatten()(x)
model = Model(x_inp, x_out)

inp = Input(shape=inp_dim)

branches = []

for _ in range(8):

    init_branch = model(inp)
    x = Dense(128)(init_branch)
    x = Dense(36)(x)
    x = Activation("softmax")(x)

    branches.append(x)

final_model = Model(inputs = inp, outputs = branches)


final_model.compile(tf.keras.optimizers.Adam(learning_rate=0.001),
                loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
                metrics=['accuracy'])

вход - ЕДИНАЯ модель (я использовал упрощенную версию) для всех 8 конечных ветвей. Проверьте входной размер ((32, 32, 3) Я не знаю, правильно ли это)


это мое решение для правильной подгонки (Это мое мнение, я не проверяю его )

import string

# dummy target in the format I expected (7 digits)
train_labels = np.array([['7C24698'], ['7F84698']])
test_label = np.array([['8C24698'], ['8F84698']])

# create dict to encode digits to numbers
y_map = {}
for i,d in enumerate(string.digits+string.ascii_uppercase):
    y_map[d] = i

# utility function for split string in char and encode them
def split_encode(x):
    x = list(x[0])
    x = [y_map[d] for d in x]
    return x

# transform target
train_labels = np.apply_along_axis(split_encode, 1, train_labels)
test_label = np.apply_along_axis(split_encode, 1, test_label)

......

# fit model (this works with 7 output branches, 36 digits output prob, and sparse_catcrossent
final_model.fit(train_images, [train_labels[:,i] for i in range(7)], epochs=80,
            validation_data=(test_images, [test_label[:,i] for i in range(7)]))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...