LINUX.ORG.RU

Не распознается текст капчи переменной длины

 , , ,


0

1

Есть нейронная сеть для распознавания текста с капчи. Если вся капча имеет одинаковую длину, то сеть обучается и распознает текст со 100% результатом. Но с переменной длиной сеть уже не обучается и соответственно не распознает текст. Что я только не пробовал ничего не помогает. Код не весь, а только важные моменты:

char_to_num = keras.layers.StringLookup(vocabulary=chars, invert=False)
blank_char_index = len(char_to_num.get_vocabulary())

encoded_labels = keras.preprocessing.sequence.pad_sequences(
    encoded_labels, maxlen=max_label_length, padding='post', value=blank_char_index
)

# CTC loss
class CTCLayer(keras.layers.Layer):
    def __init__(self, name=None):
        super().__init__(name=name)

    def call(self, y_true, y_pred):
        # Количество примеров в батче
        batch_len = tf.cast(tf.shape(y_true)[0], dtype=tf.int32)
        # Длина последовательности предсказаний (временные шаги)
        input_length = tf.cast(tf.shape(y_pred)[1], dtype=tf.int32)
        # Создаем тензоры длин для всего батча
        input_length = input_length * tf.ones(shape=(batch_len, 1), dtype=tf.int32)
        # Длина целевой текстовой метки
        label_length = tf.math.reduce_sum(tf.cast(tf.math.not_equal(y_true, blank_char_index), tf.int32), axis=1, keepdims=True)
        
        loss = keras.backend.ctc_batch_cost(y_true, y_pred, input_length, label_length)
        self.add_loss(loss)

        return y_pred

# Входной слой
image_input_layer = keras.layers.Input(shape=(image_width, image_height, 1), name="image_input_layer", dtype=tf.float32)
label_input_layer = keras.layers.Input(shape=(max_label_length,), name="label_input_layer", dtype=tf.int32)

# Слой CNN (извлечение признаков)
x = keras.layers.Conv2D(32, (3, 3), activation="relu", kernel_initializer="he_normal", padding="same")(image_input_layer)
x = keras.layers.MaxPooling2D((2, 2))(x)

x = keras.layers.Conv2D(64, (3, 3), activation="relu", kernel_initializer="he_normal", padding="same")(x)
x = keras.layers.MaxPooling2D((2, 2))(x)

# Преобразование в последовательность для RNN
new_rnn_shape = ((image_width // 4), (image_height // 4) * 64)
x = keras.layers.Reshape(target_shape=new_rnn_shape)(x)
x = keras.layers.Dense(64, activation="relu")(x)
x = keras.layers.Dropout(0.2)(x)

# Слой RNN (обработка последовательности)
x = keras.layers.Bidirectional(keras.layers.LSTM(128, return_sequences=True, dropout=0.25))(x)
x = keras.layers.Bidirectional(keras.layers.LSTM(64, return_sequences=True, dropout=0.25))(x)

# Выходной слой
output_layer = keras.layers.Dense(blank_char_index + 1, activation="softmax", name="output_layer")(x)

# CTC loss
ctc_loss_output = CTCLayer(name="ctc_loss_output")(label_input_layer, output_layer)

# Модель
model = keras.models.Model(inputs=[image_input_layer, label_input_layer], outputs=ctc_loss_output)
model.compile(optimizer=keras.optimizers.Adam())
model.summary()

0: доба_вим раскраски(малютке):


#k=keras
kl=keras.layers
encoded_labels = keras.preprocessing.sequence.pad_sequences(    encoded_labels, maxlen=max_label_length, padding='post', value=(bci:= len((c2n:= kl.StringLookup(vocabulary=chars, invert=False)).get_vocabulary())) )
class CTCLayer(kl.Layer):
    def __init__(self, name=None):
        super().__init__(name=name)
    def call(self, yt, yp):
        self.add_loss(
            l:=keras.backend.ctc_batch_cost(
                yt,
                yp,
                il:=tf.cast(
                    tf.shape(yp)[1],
                    dtype=tf.int32)*tf.ones(
                                        shape=(
                                            bl:=tf.cast(
                                                tf.shape(yt)[0],
                                                dtype=tf.int32),
                                            1),
                                        dtype=tf.int32),
                ll:=tf.math.reduce_sum(
                    tf.cast(
                        tf.math.not_equal(
                            yt,
                            bci),
                        tf.int32),
                    axis=1,
                    keepdims=True)))
        return yp
(m:=keras.models.Model(
    inputs=[iil, (
        lil:= kl.Input(
            shape=(max_label_length,),
            name="label_input_layer",
            dtype=tf.int32))],
    outputs=(
        clo:= CTCLayer(name="ctc_loss_output")(
            lil, (
            ol:= kl.Dense(
                bci + 1,
                activation="softmax",
                name="output_layer")(
                    x9:=kl.Bidirectional(
                        kl.LSTM(
                            64,
                            return_sequences=True,
                            dropout=0.25))(
                    x8:=kl.Bidirectional(
                        kl.LSTM(128,
                                return_sequences=True,
                                dropout=0.25))(
                    x7:=kl.Dropout(0.2)(
                    x6:=kl.Dense(64,
                                 activation="relu")(
                    x5:=kl.Reshape(
                        target_shape=(
                            nrs:=((image_width//4),(image_height//4)*64)))(
                    x4:=kl.MaxPooling2D((2, 2))(
                    x3:=kl.Conv2D(64,
                                   (3, 3),
                                   activation="relu",
                                   kernel_initializer="he_normal",
                                   padding="same")(
                    x2:=kl.MaxPooling2D((2, 2))(
                    x1:= kl.Conv2D(32,
                                   (3, 3),
                                   activation="relu",
                                   kernel_initializer="he_normal",
                                   padding="same")(
                                       iil:=kl.Input(
                                           shape=(
                                               image_width,
                                               image_height,
                                               1),
                                           name="image_input_layer",
                                           dtype=tf.float32) 
                                   ))))))))))))))).compile(optimizer=keras.optimizers.Adam())
m.summary()

qulinxao3 ★☆
()