如何在 Tensorflow Estimator 的输入中提供更多模型参数?
How to feed further model parameters along the inputs to Tensorflow Estimator?
短版:
我有一个带有层的自定义模型,该层可以通过值 sigma
.
进行参数化
我正在将此模型与 Tensorflow Estimator 一起使用:
classifier = tf.estimator.Estimator(model_fn=model_fun)
例如训练声明如下:
# Train the model
train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
classifier.train(input_fn=train_input_fn,max_steps=nSteps)
在此设置中,如何将 sigma
传递给我的自定义 Estimator,以便可以使用不同的值对其进行训练/评估?
更长的版本:
我正在研究这个 DNN 自动编码器,为此我有一个层,通过考虑来自已知标准偏差 sigma 分布的 random_normal() 值来添加高斯噪声。
这是一个通信系统模型,使用 model.predict() 函数检索输出 logits(来自最后一层),我的指标即误码率由自定义函数计算在张量流 1.5 中,Python 3.5,Windows 10。
问题如下:
我想为sigma=sigma1训练系统,并检索输出logits。(这部分没问题,我能够得到想要的输出。)
我还想预测 sigma=sigma2、sigma=sigma3、sigma=sigma4 等的输出,使用定义的相同 Estimator(在同一程序中)。
我的 DNN 看起来像这样并在模型函数中定义:
输入层 - 此处提供一个热编码值。
密集+ReLU
密集+线性
归一化层
Addition of Noise:这里我在上一层的输出上加了一个tf.random_normal(stddev=sigma)。在这里,我希望能帮助您理解如何为每个 运行(train/test) 使用不同的西格玛。我想你可以说 sigma 应该是一个参数,每个测试可以有不同的值 运行.
gnoise=tf.random_normal(mean=0,stddev=sigma)
Then the layer's output=norm(which is the prev layer's output)+gnoise
密集+RELU
Softmax-输出为 Logits
我将估算器定义为:
classifier = tf.estimator.Estimator(model_fn=model_fun)
并且训练声明如下:
# Train the model
train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
classifier.train(input_fn=train_input_fn,max_steps=nSteps)
预测函数的声明和调用如下:
pred_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": test_data},
batch_size=batch_size, num_epochs=nEpochs, shuffle=False)
pred_results = classifier.predict(input_fn=pred_input_fn)
你应该让你的 sigma 成为你层的参数,然后在运行时通过你的 features
将它的值提供给你的模型(使用列键区分 x
和 sigma
).
没有你的高斯层代码很难准确回复,但假设你的模型是这样定义的:
import tensorflow as tf
def gaussian_noise_layer(x):
# Currently, your sigma is probably fixed somewhere here, e.g.
sigma = 1
dist = tf.distributions.Normal(loc=0., scale=sigma)
# Build Gaussian kernel from dist:
# gaussian_kernel = ...
return tf.nn.depthwise_conv2d(x, gaussian_kernel, [1, 1, 1, 1], padding='SAME')
def model_fun(features, labels, mode, params):
# Get input x from features:
x = tf.feature_column.input_layer(features, params.feature_column)
# ... building your model here, adding at some point the gaussian layer, e.g.
# ... net = f(x)
net = gaussian_noise_layer(net)
# ... predictions = f'(net)
# ...
return tf.estimator.EstimatorSpec(
mode=mode,
predictions=predictions,
loss=loss,
train_op=train_op,
eval_metric_ops=eval_metric_ops
)
with tf.Session() as sess:
# ...
# Specifying your params and inputs:
params = tf.contrib.training.HParams(
# ... other hyperparameters,
# Define feature column for input x of shape "shape_x" (e.g. (64, 64, 3)):
feature_column=tf.feature_column.numeric_column(key="x", shape=shape_x)
)
classifier = tf.estimator.Estimator(model_fn=model_fun, params=params)
# For training:
train_input_fn = tf.estimator.inputs.numpy_input_fn(x={"x": train_data},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
classifier.train(input_fn=train_input_fn, max_steps=nSteps)
...那么您需要像这样编辑它:
import tensorflow as tf
def gaussian_noise_layer(x, sigma):
# sigma is now a parameter
dist = tf.distributions.Normal(loc=0., scale=sigma)
# Build Gaussian kernel from dist:
# gaussian_kernel = ...
return tf.nn.depthwise_conv2d(x, gaussian_kernel, [1, 1, 1, 1], padding='SAME')
def model_fun(features, labels, mode, params):
# Get input x from features:
x = tf.feature_column.input_layer(features, params.input_feature_column)
# Get sigma from features:
sigma = tf.feature_column.input_layer(features, params.sigma_feature_column)
# ... building your model here, adding at some point the gaussian layer, e.g.
# ... net = f(x)
net = gaussian_noise_layer(net, sigma)
# ... predictions = f'(net)
# ...
return tf.estimator.EstimatorSpec(
mode=mode,
predictions=predictions,
loss=loss,
train_op=train_op,
eval_metric_ops=eval_metric_ops
)
with tf.Session() as sess:
# ...
# We now specify which columns contain the actual inputs (x), and which columns contain other parameters (sigma):
params = tf.contrib.training.HParams(
# ... other hyperparameters,
# Define feature column for input x of shape "shape_x" (e.g. (64, 64, 3)):
input_feature_column=tf.feature_column.numeric_column(key="x", shape=shape_x),
# Define feature column for input sigma of shape () i.e. scalar (default shape):
sigma_feature_column=tf.feature_column.numeric_column(key="sigma")
)
classifier = tf.estimator.Estimator(model_fn=model_fun, params=params)
# Train:
num_train_elements = train_data.shape[0]
sigma = [1] * num_train_elements # or e.g. sigma = [1, 1, 2, 1, 3, ...]
# We can now feed sigma along x:
train_input_fn = tf.estimator.inputs.numpy_input_fn(
x={"x": train_data, "sigma": numpy.array(sigma)},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
classifier.train(input_fn=train_input_fn, max_steps=nSteps)
# ...
# Predict:
sigma = [2] * num_train_elements # or e.g. sigma = [1, 1, 2, 1, 3, ...]
pred_input_fn=tf.estimator.inputs.numpy_input_fn(
x={"x": train_data, "sigma": numpy.array(sigma)},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
pred_results = classifier.predict(input_fn=pred_input_fn)
短版:
我有一个带有层的自定义模型,该层可以通过值 sigma
.
我正在将此模型与 Tensorflow Estimator 一起使用:
classifier = tf.estimator.Estimator(model_fn=model_fun)
例如训练声明如下:
# Train the model
train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
classifier.train(input_fn=train_input_fn,max_steps=nSteps)
在此设置中,如何将 sigma
传递给我的自定义 Estimator,以便可以使用不同的值对其进行训练/评估?
更长的版本:
我正在研究这个 DNN 自动编码器,为此我有一个层,通过考虑来自已知标准偏差 sigma 分布的 random_normal() 值来添加高斯噪声。
这是一个通信系统模型,使用 model.predict() 函数检索输出 logits(来自最后一层),我的指标即误码率由自定义函数计算在张量流 1.5 中,Python 3.5,Windows 10。
问题如下:
我想为sigma=sigma1训练系统,并检索输出logits。(这部分没问题,我能够得到想要的输出。)
我还想预测 sigma=sigma2、sigma=sigma3、sigma=sigma4 等的输出,使用定义的相同 Estimator(在同一程序中)。
我的 DNN 看起来像这样并在模型函数中定义:
输入层 - 此处提供一个热编码值。
密集+ReLU
密集+线性
归一化层
Addition of Noise:这里我在上一层的输出上加了一个tf.random_normal(stddev=sigma)。在这里,我希望能帮助您理解如何为每个 运行(train/test) 使用不同的西格玛。我想你可以说 sigma 应该是一个参数,每个测试可以有不同的值 运行.
gnoise=tf.random_normal(mean=0,stddev=sigma) Then the layer's output=norm(which is the prev layer's output)+gnoise
密集+RELU
Softmax-输出为 Logits
我将估算器定义为:
classifier = tf.estimator.Estimator(model_fn=model_fun)
并且训练声明如下:
# Train the model
train_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": train_data},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
classifier.train(input_fn=train_input_fn,max_steps=nSteps)
预测函数的声明和调用如下:
pred_input_fn=tf.estimator.inputs.numpy_input_fn(x={"x": test_data},
batch_size=batch_size, num_epochs=nEpochs, shuffle=False)
pred_results = classifier.predict(input_fn=pred_input_fn)
你应该让你的 sigma 成为你层的参数,然后在运行时通过你的 features
将它的值提供给你的模型(使用列键区分 x
和 sigma
).
没有你的高斯层代码很难准确回复,但假设你的模型是这样定义的:
import tensorflow as tf
def gaussian_noise_layer(x):
# Currently, your sigma is probably fixed somewhere here, e.g.
sigma = 1
dist = tf.distributions.Normal(loc=0., scale=sigma)
# Build Gaussian kernel from dist:
# gaussian_kernel = ...
return tf.nn.depthwise_conv2d(x, gaussian_kernel, [1, 1, 1, 1], padding='SAME')
def model_fun(features, labels, mode, params):
# Get input x from features:
x = tf.feature_column.input_layer(features, params.feature_column)
# ... building your model here, adding at some point the gaussian layer, e.g.
# ... net = f(x)
net = gaussian_noise_layer(net)
# ... predictions = f'(net)
# ...
return tf.estimator.EstimatorSpec(
mode=mode,
predictions=predictions,
loss=loss,
train_op=train_op,
eval_metric_ops=eval_metric_ops
)
with tf.Session() as sess:
# ...
# Specifying your params and inputs:
params = tf.contrib.training.HParams(
# ... other hyperparameters,
# Define feature column for input x of shape "shape_x" (e.g. (64, 64, 3)):
feature_column=tf.feature_column.numeric_column(key="x", shape=shape_x)
)
classifier = tf.estimator.Estimator(model_fn=model_fun, params=params)
# For training:
train_input_fn = tf.estimator.inputs.numpy_input_fn(x={"x": train_data},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
classifier.train(input_fn=train_input_fn, max_steps=nSteps)
...那么您需要像这样编辑它:
import tensorflow as tf
def gaussian_noise_layer(x, sigma):
# sigma is now a parameter
dist = tf.distributions.Normal(loc=0., scale=sigma)
# Build Gaussian kernel from dist:
# gaussian_kernel = ...
return tf.nn.depthwise_conv2d(x, gaussian_kernel, [1, 1, 1, 1], padding='SAME')
def model_fun(features, labels, mode, params):
# Get input x from features:
x = tf.feature_column.input_layer(features, params.input_feature_column)
# Get sigma from features:
sigma = tf.feature_column.input_layer(features, params.sigma_feature_column)
# ... building your model here, adding at some point the gaussian layer, e.g.
# ... net = f(x)
net = gaussian_noise_layer(net, sigma)
# ... predictions = f'(net)
# ...
return tf.estimator.EstimatorSpec(
mode=mode,
predictions=predictions,
loss=loss,
train_op=train_op,
eval_metric_ops=eval_metric_ops
)
with tf.Session() as sess:
# ...
# We now specify which columns contain the actual inputs (x), and which columns contain other parameters (sigma):
params = tf.contrib.training.HParams(
# ... other hyperparameters,
# Define feature column for input x of shape "shape_x" (e.g. (64, 64, 3)):
input_feature_column=tf.feature_column.numeric_column(key="x", shape=shape_x),
# Define feature column for input sigma of shape () i.e. scalar (default shape):
sigma_feature_column=tf.feature_column.numeric_column(key="sigma")
)
classifier = tf.estimator.Estimator(model_fn=model_fun, params=params)
# Train:
num_train_elements = train_data.shape[0]
sigma = [1] * num_train_elements # or e.g. sigma = [1, 1, 2, 1, 3, ...]
# We can now feed sigma along x:
train_input_fn = tf.estimator.inputs.numpy_input_fn(
x={"x": train_data, "sigma": numpy.array(sigma)},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
classifier.train(input_fn=train_input_fn, max_steps=nSteps)
# ...
# Predict:
sigma = [2] * num_train_elements # or e.g. sigma = [1, 1, 2, 1, 3, ...]
pred_input_fn=tf.estimator.inputs.numpy_input_fn(
x={"x": train_data, "sigma": numpy.array(sigma)},
batch_size=batch_size, num_epochs=nEpochs, shuffle=True)
pred_results = classifier.predict(input_fn=pred_input_fn)