Модель Keras с проблемой потери нескольких выходов - PullRequest
0 голосов
/ 27 марта 2019

Я создаю модель Keras GAN, которая имеет несколько выходов, поскольку я хотел добавить к ней больше целевых функций.Однако добавление третьей функции вывода и потерь полностью приводит к сбою моего тренировочного процесса, и одна из потерь дает результат NaN, даже если вес этой конкретной функции потерь установлен на 0.

Таким образом, несмотря на два наиболее распространенных выхода и потери, связанные с этим -Бинарная перекрестная энтропия дискриминатора и разность L1 генератора. Я хотел создать один лямбда-слой, соединенный с выходом генератора, чтобы выполнить определение края Собеля.Вывод моей предварительно обученной модели удовлетворителен, поскольку лямбда-слой создает хорошие карты краев, а выходные данные генератора и дискриминатора остаются нетронутыми.Теперь я хочу определить потери - я реализовал функцию потерь L1 для лямбда-слоя так же, как для стандартного выхода генератора.Поскольку я подготовил набор данных с картами истинных краев, проблема должна быть тривиальной, однако во время обучения после первой партии выходной сигнал генератора становится черным, а потери краев равны NaN - даже когда вес потери для краевого слоя установлен на0. Если я правильно понимаю, если при составлении модели вес потери равен 0, то эта конкретная функция потерь не должна влиять на процесс обучения модели.Я дважды и даже трижды проверил, есть ли какие-либо числовые ошибки, но их нет.Сразу после компиляции модели, когда я тестирую ее на тестовой партии, потеря является числовым значением.Он становится NaN, когда тренируется даже в одной партии.

Как видите, вес «края» установлен на 0. Это все равно влияет на тренировку.Удаление линии 'edge' из объявлений дает предыдущие результаты, поэтому модель без слоя Sobel работает нормально.

gen_losses = {
    "gen": L1, 
    "edge": L1,
    "disc": "binary_crossentropy"
}
alpha = 0.3
beta = 0.0
gen_loss_weights = {
    "gen": alpha,
    "edge": beta,
    "disc": 1.0-alpha-beta
}
d_on_g = generator_containing_discriminator(gen, disc)
d_optim = keras.optimizers.Adam(lr=2e-6, beta_1=0.5)
dg_optim = keras.optimizers.Adam(lr=2e-4, beta_1=0.5)
g_optim = keras.optimizers.SGD(lr=2e-7, momentum=0.9, nesterov=True, decay=0)
gen.compile(loss='mean_squared_error', optimizer=g_optim, metrics=['acc'])
d_on_g.compile(loss=gen_losses, loss_weights=gen_loss_weights, optimizer=dg_optim, metrics=['acc'])
make_trainable(disc, True)
disc.compile(loss='binary_crossentropy', optimizer=d_optim, metrics=['acc'])

Это моя функция, которая используется в лямбда-слое.

def sobel_custom(x):
    x = tf.image.rgb_to_grayscale(x)
    x = tf.image.sobel_edges(x)
    x1 = K.pow(x[:, :, :, :, 0], 2)
    x2 = K.pow(x[:, :, :, :, 1], 2)
    x = K.sqrt(x1 + x2)
    x = x/(tf.reduce_max(x) - tf.reduce_min(x)) * 2 - 1  - tf.reduce_min(x)
    return x

Учебная часть - правильные данные передаются в алгоритм обратного распространения.

g_loss = d_on_g.train_on_batch(features, {"gen": np.array(labels),
                                          "disc": np.array([1]*batch_size),                                                      
                                          "edge": np.array(labels_edges)})

Вся часть создания модели.

def generator_containing_discriminator(g, d):
    print("GAN:")
    gan_input = layers.Input(shape=(feature_size, feature_size, 3))
    g._name = "gen"
    d._name = "disc"
    gen_output = g(gan_input)
    edge_output = Lambda(sobel_custom, name="edge")(gen_output)
    make_trainable(d, False)
    disc_output = d(gen_output)
    model = keras.models.Model(inputs=[gan_input], outputs=[gen_output, 
                                                   disc_output, edge_output])
    model.summary()
    plot_model(model, to_file="GAN.png")
    print(model.output_shape)
    return model

Я просто хочу знать, что я делаю не так.Я был уверен, что расчет потерь с несколькими взвешенными функциями потерь принимает вид, подобный L = w1 * l1 + w2 * l2 + ... + wn * ln, но, очевидно, я ошибался, поскольку даже когда один вес равен 0, он все равновлияет на результаты.

Tensorflow 1.12.0 GPU / Python 3.6

...