Задача: Учитывая случайный порядковый номер {0,1,2,3,4}, обучаем нейронную сеть, чтобы найти индекс положения числа «2». Эта сеть имитирует медианный фильтр, который находит индекс медианного числа вместо самого медианного числа. Например, учитывая ввод [3,1,0,2,4], вывод / метка будет «3» (или [0,0,0,1,0]).
Я могу построитьпростая нейронная сеть вручную, задавая ядро и веса смещения, чтобы сделать работу. И это отлично сработало. Код keras выглядит следующим образом:
val_len = 5
def GetModel():
inputs_img = keras.layers.Input(shape=(val_len, 1), name='rank')
net = keras.layers.Conv1D(1, 1, activation='tanh', name='layer1', trainable=True, kernel_initializer=keras.initializers.RandomUniform(-5, 5), bias_initializer=keras.initializers.RandomUniform(-5, 5))(inputs_img)
net = keras.layers.Lambda(lambda x: K.abs(x))(net)
net = keras.layers.Conv1D(1, 1, activation='relu', name='layer2', trainable=True, kernel_initializer=keras.initializers.RandomUniform(-5, 5), bias_initializer=keras.initializers.RandomUniform(-5, 5))(net)
net = keras.layers.Flatten()(net)
net = keras.layers.Dense(units=val_len, name = 'mid_pos', activation='softmax', trainable=True, kernel_initializer=keras.initializers.RandomUniform(-5, 5), bias_initializer=keras.initializers.RandomUniform(-5, 5))(net)
model = keras.models.Model(inputs=[inputs_img], outputs=[net])
return model
model = GetModel()
# do 2 - x
model.get_layer('layer1').set_weights([np.array([[[-1]]], dtype=np.float32), np.array([2], dtype=np.float32)])
# do 1 - x
model.get_layer('layer2').set_weights([np.array([[[-1]]], dtype=np.float32), np.array([1], dtype=np.float32)])
# do 1-to-1 connection
model.get_layer('mid_pos').set_weights([np.array([[1,0,0,0,0],
[0,1,0,0,0],
[0,0,1,0,0],
[0,0,0,1,0],
[0,0,0,0,1]], dtype=np.float32),
np.array([0,0,0,0,0], dtype=np.float32)])
Однако эта простая модель не может выучить веса на примерах (я пробовал много оптимизаторов). Наилучшая точность, которую он может достичь, составляет 0,2, что является случайным выбором из 5 категорий. Модель может начать изучать «layer1», если мы вручную назначим веса для «layer2» и «mid_pos» layer.
Мой вопрос: 1. почему эта простая модель не может научиться на примере? 2. как улучшить свои способности к обучению? Спасибо за ваши комментарии. (Кстати, обобщенный CNN не является решением)