Термин пользовательской регуляризации Tensorflow, сравнивающий прогноз с истинным значением

Dec 08 2020

Здравствуйте, мне нужен специальный термин регуляризации, который можно добавить к моей функции потерь (бинарная перекрестная энтропия). Может ли кто-нибудь помочь мне с синтаксисом Tensorflow реализовать это? Я максимально упростил все, чтобы мне было легче помочь.

Модель принимает набор данных 10000 из 18 x 18 двоичных конфигураций в качестве входных данных и имеет набор конфигураций 16x16 в качестве выходных. Нейронная сеть состоит всего из 2-х Convlutional слоев.

Моя модель выглядит так:

import tensorflow as tf
from tensorflow.keras import datasets, layers, models
EPOCHS = 10
model = models.Sequential()
model.add(layers.Conv2D(1,2,activation='relu',input_shape=[18,18,1]))
model.add(layers.Conv2D(1,2,activation='sigmoid',input_shape=[17,17,1]))
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3),loss=tf.keras.losses.BinaryCrossentropy())
model.fit(initial.reshape(10000,18,18,1),target.reshape(10000,16,16,1),batch_size = 1000, epochs=EPOCHS, verbose=1)
output = model(initial).numpy().reshape(10000,16,16) 

Теперь я написал функцию, которую хотел бы использовать как дополнительный термин регуляризации, чтобы иметь как термин регуляризации. Эта функция принимает истинное значение и прогноз. По сути, он умножает каждую точку обоих на своего «правильного» соседа. Потом берется разница. Я предположил, что истинный и прогнозируемый член - 16x16 (а не 10000x16x16). Это верно?

def regularization_term(prediction, true):
    order = list(range(1,4))
    order.append(0)
    
    deviation = (true*true[:,order]) - (prediction*prediction[:,order])
    deviation = abs(deviation)**2
    return 0.2 * deviation

Я был бы очень признателен за помощь в добавлении чего-то вроде этой функции в качестве термина регуляризации к моей потере за то, что помогло нейронной сети лучше обучаться этому взаимодействию «правильного соседа». Мне очень сложно использовать настраиваемые функции Tensorflow. Спасибо, очень признателен.

Ответы

2 Nikaido Dec 08 2020 at 21:50

Все очень просто. Вам необходимо указать настраиваемую потерю, в которой вы определяете свой добавляемый срок регуляризации. Что-то вроде этого:

# to minimize!
def regularization_term(true, prediction):
    order = list(range(1,4))
    order.append(0)
    
    deviation = (true*true[:,order]) - (prediction*prediction[:,order])
    deviation = abs(deviation)**2
    return 0.2 * deviation

def my_custom_loss(y_true, y_pred):
    return tf.keras.losses.BinaryCrossentropy()(y_true, y_pred) + regularization_term(y_true, y_pred)


model.compile(optimizer='Adam', loss=my_custom_loss)

Как заявил Керас:

Любой вызываемый объект с подписью loss_fn (y_true, y_pred), который возвращает массив потерь (один из выборок во входном пакете), может быть передан в compile () как потеря. Обратите внимание, что взвешивание выборки автоматически поддерживается для любой такой потери.

Поэтому не забудьте вернуть массив потерь ( EDIT: как я теперь вижу, можно вернуть также простой скаляр. Неважно, используете ли вы, например, функцию уменьшения ). Обычно y_true и y_predicted имеют в качестве первого измерения размер пакета .

здесь подробности: https://keras.io/api/losses/