Получают ли слои встраивания Keras дополнительную регуляризацию при преобразовании в оценки тензорного потока? - PullRequest
0 голосов
/ 16 апреля 2019

Я создал простую игрушечную модель для изучения детерминированного встраивания в tf.keras. Модель способна полностью выучить встраивание, когда обучается как модель keras. После преобразования в Estimator с использованием tf.keras.estimator.model_to_estimator модель больше не может узнать веса встраивания. Почему Оценщик тензорного потока не воспроизводит обучающую способность модели керас по простой игрушечной задаче?

Основываясь на результатах эксперимента, приведенного ниже, я подозреваю, что веса встраивания в Estimator могут по умолчанию регулироваться L2, но я ничего не видел в исходном коде.

1. Создать синтетический набор данных

Цель состоит в том, чтобы узнать значения Z из наблюдений линейного преобразования y = Z.dot(b) с b и y, поданными в сеть:

import numpy as np
import pandas as pd

np.random.seed(1234)
n_obs = 200
n_sensors = 50
n_sources  = 5

Z = np.random.randn(n_obs, n_sources)
b = np.random.randn(n_sources, n_sensors)
y = Z.dot(b)

data = []
for t in range(n_obs):
    betas = pd.DataFrame(b).rename(lambda x: 'f_{}'.format(x)).T
    data.append(
        pd.DataFrame({'target': y[t,:], 't': t}).join(betas)
    )

data = pd.concat(data)

2. Определение модели Keras

Создайте входной слой для betas и просмотр таблицы встраивания, чтобы узнать значения Z:

import tensorflow as tf


def build_keras_model():
    betas = tf.keras.layers.Input(shape=(n_sources,), name='betas')
    t = tf.keras.layers.Input(shape=(1,), name='t')

    sources = tf.keras.layers.Embedding(
        input_dim=n_obs,
        output_dim=n_sources,
        name='sources')(t)

    fitted = tf.keras.layers.Dot(axes=-1)([sources, betas])
    net = tf.keras.Model([betas, t], fitted)
    net.compile(optimizer='adadelta', loss='mse')
    return net    

3. Результаты обучения модели Keras

Обучение модели приводит к плавной конвергенции до ок. нулевая ошибка и правильные веса вложения:

net = build_keras_model()
loss = []

hist = net.fit(
    x=[data.filter(like='f_'), data.t],
    y=data.target,
    batch_size=100,
    epochs=200)
loss += hist.history['loss']

Z_hat_keras = net.get_layer('sources').get_weights()
print ((Z_hat_keras - Z) ** 2).mean()
# Out: 8.794945836110652e-05

4. Преобразовать в тф.Эстиматор и поезд Преобразование в оценщик и обучение с одинаковыми гиперпараметрами приводит к отсутствию обучения и большой ошибке

# convert to estimator
estimator = tf.keras.estimator.model_to_estimator(net)

# slice data so estimator can read it
def input_fn(data, batch_size, num_epochs, shuffle):
    ds = tf.data.Dataset.from_tensor_slices((
        {'betas': data.filter(like='f_'), 't': data.t}, data.target
    ))

    if shuffle:
        ds = ds.shuffle(len(data))

    return ds.repeat(num_epochs).batch(batch_size)

train_fn = lambda: input_fn(data, 100, 200, True)
eval_fn = lambda: input_fn(data, 500,1,False)

# run training on estimator
estimator.train(train_fn)

estimator.evaluate(eval_fn)
# Out: {'global_step': 20001, 'loss': 5.0131807}

Z_hat_tensorflow = estimator.get_variable_value('sources/embeddings')

print ((Z_hat_tensorflow - Z) ** 2).mean()
# Out 0.928678746751657

5. Изученные веса встраивания кажутся очень маленькими, но коррелированными Веса вложения оценки тензорного потока несколько коррелируют с фактическими значениями:

print pd.DataFrame(Z_hat_tensorflow).corrwith(pd.DataFrame(Z))
# 0    0.684187
# 1    0.716039
# 2    0.702139
# 3    0.734620
# 4    0.776179

Но значения очень маленькие:

print pd.DataFrame(Z_hat_tensorflow).var()
# 0    0.000128
# 1    0.000229
# 2    0.000156
# 3    0.000184
# 4    0.000183

print pd.DataFrame(Z).var()
# 0    0.781733
# 1    0.983512
# 2    0.830148
# 3    1.065107
# 4    1.072370

Почему оценка тензорного потока не может воспроизвести результаты модели keras?

...