我正在尝试实现具有从解码器生成采样输出的功能的seq2seq,即在每一步,而不是从先前状态获取输出logits的argmax,它应根据logit分布和使用从它们中采样作为下一步的输入。
在我四处寻找之后,我发现seq2seq.py中的loop_function是一个很有希望的起点。看起来我必须编写一个看起来像这样的循环函数(从提取argmax +嵌入的文件中修改):
def _extract_sample_and_embed(embedding, output_projection=None,
update_embedding=True):
def loop_function(prev, _):
if output_projection is not None:
prev = nn_ops.xw_plus_b(prev, output_projection[0], output_projection[1])
prev_symbol = math_ops.sample(prev) #<------- Need this op but it does not exist ?
emb_prev = embedding_ops.embedding_lookup(embedding, prev_symbol)
if not update_embedding:
emb_prev = array_ops.stop_gradient(emb_prev)
return emb_prev
return loop_function
然后我在seq2seq_embedding_with_attention模型中使用这个循环函数生成器。但是,操作我需要来自张量浮点数的样本在tensorflow中不存在,所以我需要编写自己的吗?我该怎么做?
在搜索指导时,我发现在tensorflow / tensorflow / python / ops / candidate_sampling_ops中有一个引用:
from tensorflow.python.ops import gen_candidate_sampling_ops
但我找不到这个文件。我猜它是从某个地方自动生成的。在哪里?
答案 0 :(得分:4)
目前,您还可以使用the gumbel max trick for directe distributions:
按以下方式执行此操作[900, 332, 432, 145]
此刻Tensorflows问题跟踪器上还有一个discussion。我想迟早会将多项式样本函数添加到Tensorflow中。 LeavesBreathe还在Github页面上发布了一个解决方案,这在我看来并不完全正确:
def batch_gumbel_max_sample(a, max_gumbel_noise = 1.0):
matrix_U = -1.0*tf.log(-1.0*tf.log(tf.random_uniform(tf.shape(a),
minval = 0.0, maxval = max_gumbel_noise)))
return tf.argmax(tf.sub(a, matrix_U), dimension = 1)
答案 1 :(得分:1)
我今天遇到同样的问题,我的解决方案是:
替换线
prev_symbol = math_ops.sample(prev)
同
prev_symbol = squeeze(multinomial(prev, 1), axis=1)
函数tf.multinomial()从多项分布中提取样本。它采用了形状[batch_size,num_classes]和0-D标量“num_samples”作为输入的2-D Tensor“logits”。并输出绘制的形状样本[batch_size,num_samples]。
同时,math_ops.sample()输出shape [batch_size]的样本,因此我们需要tf.squeeze()来减少维度。
这种实现更简单。