Пытаюсь обучить сиамскую модель в керасе. Я использую очень простой кодировщик только с covnets для кодирования изображения 32x32 RGB в вектор признаков. Кодер кодирует два изображения A и B. Затем MLP сравнивает два вектора и вычисляет оценку между 0 и 1, которая должна быть высокой, если A и B одного класса, и низкой, если они не принадлежат к одному классу.
Я использовал relu в качестве функции активации на всех слоях, но модель научилась кодировать все только в 0-вектор. Я переключился на «tanh» и увидел, что много веса и смещений, а также записи в векторе признаков отрицательны. Итак, теперь я понимаю, почему с relu все было равно нулю. Но почему я получаю отрицательные значения? Вход положительный, выход тоже, а значения y равны 0 или 1. Я думаю, что с моей моделью что-то не так.
Она тоже не очень хорошо работает. Точность составляет около 60%.
Вот моя модель:
def model():
initializer = keras.initializers.random_uniform(minval=0.0001, maxval=0.001)
enc = Sequential()
enc.add(Conv2D(32, (3, 3), padding='same', activation='tanh',kernel_initializer=initializer))
enc.add(Conv2D(32, (3, 3), padding='same', strides=(2, 2), activation='tanh',kernel_initializer=initializer))
enc.add(Conv2D(32, (3, 3), padding='same', activation='tanh',kernel_initializer=initializer))
enc.add(Conv2D(16, (3, 3), padding='same', strides=(2, 2), activation='tanh',kernel_initializer=initializer))
enc.add(Conv2D(32, (3, 3), padding='same', activation='tanh',kernel_initializer=initializer))
enc.add(Conv2D(4, (3, 3), padding='same', strides=(2, 2), activation='tanh',kernel_initializer=initializer))
enc.add(Flatten())
input1 = Input((32, 32, 3))
# enc.build((1,32,32,3))
# enc.summary()
input2 = Input((32, 32, 3))
enc1 = enc(input1)
enc2 = enc(input2)
twin = concatenate([enc1, enc2])
twin = Dense(64, activation='tanh',kernel_initializer=initializer)(twin)
twin = Dense(32, activation='tanh',kernel_initializer=initializer)(twin)
twin = Dense(1, activation='sigmoid',kernel_initializer=initializer)(twin)
twin = Model(inputs=[input1, input2], outputs=twin)
twin.summary()
twin.compile(optimizer=adam(0.0001), loss='binary_crossentropy', metrics=["acc"])
return twin
Редактировать: Я обнаружил, что все в порядке. Просто мои данные были плохими. У меня было только 1/10 образцов одного класса по сравнению с другими. Передискретизация не помогла. На данный момент я удалил класс из набора данных. Это работает. Я мог бы добавить класс обратно с расширенными копиями в качестве дополнительных примеров и посмотреть, как он пойдет.