将Keras嵌入层转换为张量流估计器后,是否添加了正则化功能?

时间:2019-04-16 15:55:08

标签: python tensorflow keras tensorflow-estimator

我创建了一个简单的玩具模型来学习在tf.keras中的确定性嵌入。当训练为keras模型时,该模型能够完全学习嵌入。使用Estimator转换为tf.keras.estimator.model_to_estimator后,模型将无法再学习嵌入权重。 为什么tensorflow Estimator在简单的玩具问题上不能重现keras模型的学习性能?

根据下面的实验结果,我怀疑默认情况下Estimator中的嵌入权重可能会经过L2规范化,但是在源代码中看不到有任何影响。

1。创建综合数据集

目标是从对Zy = 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。转换为tf.Estimator并进行训练 转换为估计量并使用相同的超参数进行训练会导致无学习且误差大

# 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。学习的嵌入权重似乎很小,但相互关联 tensorflow估计器的嵌入权重与实际值有些相关:

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模型的结果?

0 个答案:

没有答案