Как мне учесть регуляризаторы l1 и l2 в пользовательских циклах обучения тензорного потока? - PullRequest
1 голос
/ 18 июня 2020

Играя с методом model.fit_on_batch и настраиваемыми циклами обучения я понял, что в коде настраиваемого обучения l oop потери и градиент не учитывают регуляризаторы l1-l2 и, следовательно, оптимизатор. apply_gradients метод не учитывает регуляризаторы. Ниже вы можете найти код, чтобы показать это, но идея довольно проста. Итак, у меня вопрос, есть ли способ использовать все эти оптимизаторы в подробностях оптимизатора c способ учесть регуляризаторы. Как это реализовано в Керасе? В связи с этим, model.fit_on_batch возвращает значение, которое указывает не на потерю (как заявлено в строке документации), а на что-то еще. Мне было интересно, знает ли кто-нибудь здесь, что он возвращает.

Код

Чтобы увидеть этот эффект, сначала создайте некоторые данные

x=tf.constant([[1]])
y=tf.constant([[1]])

и создайте функция для создания воспроизводимой модели

def make_model(l1=.01,l2=.01):
    tf.random.set_seed(42)
    np.random.seed(42)
    model=tf.keras.models.Sequential([
        tf.keras.layers.Dense(2,'softmax',
                              use_bias=False,
                              kernel_regularizer=tf.keras.regularizers.l1_l2(l1=l1,l2=l2),
                              input_shape=(1,))
    ])
    return model

Теперь запустите Keras train_on_batch

model=make_model()
loss_object=tf.keras.losses.SparseCategoricalCrossentropy()
optimizer=tf.keras.optimizers.RMSprop()
model.compile(loss=loss_object,optimizer=optimizer)
model.train_on_batch(x,y)

и сравните результаты с пользовательским обучением l oop, как описано в приведенной выше ссылке, а также здесь

model=make_model()
loss_object=tf.keras.losses.SparseCategoricalCrossentropy()
optimizer=tf.keras.optimizers.RMSprop()

@tf.function
def train_step(x,y):

    with tf.GradientTape() as tape:
        predictions  = model(x)
        loss = loss_object(y, predictions)

    gradients = tape.gradient(loss, model.trainable_variables)    
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    return loss

train_step(x,y).numpy()

Вы увидите два разных результата, если l1 == 0 и l2 == 0.

1 Ответ

2 голосов
/ 18 июня 2020

На самом деле я нашел ответ в книге Aurelien Geron enter image description here

Фактически, после того, как я реализовал приведенный ниже код, я обнаружил, что это описано в руководстве tensorflow по индивидуальному обучению (я не знаю, почему его нет в учебных пособиях, упомянутых в вопросе, поскольку это важный момент). Решение здесь более общее, чем упомянутое здесь, но я сохраняю его, поскольку оно проливает немного больше света на то, что происходит.

Это так же просто, как изменение пользовательского обучения l oop на

def add_model_regularizer_loss(model):
    loss=0
    for l in model.layers:
        if hasattr(l,'layers') and l.layers: # the layer itself is a model
            loss+=add_model_loss(l)
        if hasattr(l,'kernel_regularizer') and l.kernel_regularizer:
            loss+=l.kernel_regularizer(l.kernel)
        if hasattr(l,'bias_regularizer') and l.bias_regularizer:
            loss+=l.bias_regularizer(l.bias)
    return loss

def train_step(x,y):

    with tf.GradientTape() as tape:
        predictions  = model(x)
        loss = loss_object(y, predictions)
        loss += add_model_regularizer_loss(model)

    gradients = tape.gradient(loss, model.trainable_variables)    
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    return loss

Чтобы ответить на вторую часть моего вопроса, именно это значение потерь возвращает метод подгонки модели keras.

...