相信肯定很多小伙伴都对GPT-2高性能感兴趣,但是看了它原著的代码有点望而却步...
本人也是为这个数据最终的流动困扰了几天,今天把它整理一个思维导图,分好几个层级 希望对大家有帮助
GPT-2 generate_unconditional_samples.py+sample.py 中数据流动示意图这里主要解释了 在模型中 context prev output past 这几个变量的流动 以及模型生成的 logits 和present 如何使用的。
模型中的 hparams.json 用于定义模型结构 encoder.json 用于word embedding词典 bpe词典在上篇文章中有介绍
第一步: 就是拿到context(上下文信息),因为是无采样 直接将其设置成“<|endoftext|>”,如果有采样时 会将其跟输入绑定
# start_token context 参数只能二选一
if start_token is None:
assert context is not None, 'Specify exactly one of start_token and context!'
else:
assert context is None, 'Specify exactly one of start_token and context!'
context = tf.fill([batch_size, 1], start_token)
#构建输出目标。
output = sample.sample_sequence(
hparams=hparams, length=length,
start_token=enc.encoder['<|endoftext|>'],
batch_size=batch_size,
temperature=temperature, top_k=top_k, top_p=top_p
)[:, 1:]
第二部: 将 context 带入到 model 计算中 其充当 prev 和 output部分 (past 在第一运行完以后才有)
past, prev, output = body(None, context, context)
第三部: 拿到 logits(输出值) present (hiddenstate)两个值 进行后续计算 拿到 past prev output 这三个值
next_outputs = step(hparams, prev, past=past)
logits = next_outputs['logits'][:, -1, :] / tf.to_float(temperature)
logits = top_k_logits(logits, k=top_k)
logits = top_p_logits(logits, p=top_p)
#取最大值
samples = tf.multinomial(logits, num_samples=1, output_dtype=tf.int32)
return [
next_outputs['presents'] if past is None else tf.concat([past, next_outputs['presents']], axis=-2),
samples,
tf.concat([output, samples], axis=1)
]
第四部: 根据目标句子长度循环
_, _, tokens = tf.while_loop(
cond=cond, body=body,
maximum_iterations=length - 1,
loop_vars=[
past,
prev,
output
],
shape_invariants=[
tf.TensorShape(model.past_shape(hparams=hparams, batch_size=batch_size)),
tf.TensorShape([batch_size, None]),
tf.TensorShape([batch_size, None]),
],
back_prop=False,
)
文中没有详细讲解 encoder 以及 transformer 的attention机制 这部分都有很不错的讲解,目测改造模型的话只要在最后输出的token后面加一个dense层 做softmax就可以 目前还没有测试 预计很快更新。