当前位置:  开发笔记 > 编程语言 > 正文

如何计算张量流中RNN的困惑度

如何解决《如何计算张量流中RNN的困惑度》经验,为你挑选了1个好方法。

我正在运行单词RNN的张量流的RNN实现

如何计算RNN的困惑度.

以下是培训中的代码,显示每个时期的培训损失和其他事项:

for e in range(model.epoch_pointer.eval(), args.num_epochs):
        sess.run(tf.assign(model.lr, args.learning_rate * (args.decay_rate ** e)))
        data_loader.reset_batch_pointer()
        state = sess.run(model.initial_state)
        speed = 0
        if args.init_from is None:
            assign_op = model.batch_pointer.assign(0)
            sess.run(assign_op)
            assign_op = model.epoch_pointer.assign(e)
            sess.run(assign_op)
        if args.init_from is not None:
            data_loader.pointer = model.batch_pointer.eval()
            args.init_from = None
        for b in range(data_loader.pointer, data_loader.num_batches):
            start = time.time()
            x, y = data_loader.next_batch()
            feed = {model.input_data: x, model.targets: y, model.initial_state: state,
                    model.batch_time: speed}
            summary, train_loss, state, _, _ = sess.run([merged, model.cost, model.final_state,
                                                         model.train_op, model.inc_batch_pointer_op], feed)
            train_writer.add_summary(summary, e * data_loader.num_batches + b)
            speed = time.time() - start
            if (e * data_loader.num_batches + b) % args.batch_size == 0:
                print("{}/{} (epoch {}), train_loss = {:.3f}, time/batch = {:.3f}" \
                    .format(e * data_loader.num_batches + b,
                            args.num_epochs * data_loader.num_batches,
                            e, train_loss, speed))
            if (e * data_loader.num_batches + b) % args.save_every == 0 \
                    or (e==args.num_epochs-1 and b == data_loader.num_batches-1): # save for the last result
                checkpoint_path = os.path.join(args.save_dir, 'model.ckpt')
                saver.save(sess, checkpoint_path, global_step = e * data_loader.num_batches + b)
                print("model saved to {}".format(checkpoint_path))
    train_writer.close()

Kilian Batzn.. 12

您引用的项目使用sequence_to_sequence_loss_by_example,它返回交叉熵损失.因此,为了计算训练困惑,您只需要像这里解释的那样对失去进行取幂.

train_perplexity = tf.exp(train_loss)

我们必须使用e代替2作为基础,因为TensorFlow使用自然对数(TF文档)测量交叉熵损失.谢谢@Matthias Arro和@Colin Skow的提示.

详细说明

当我们开发基于Q的编码方案时,两个概率分布P和Q的交叉熵告诉我们编码P事件所需的最小平均比特数.因此,P是真正的分布,我们通常不会我知道.我们希望找到一个尽可能接近P的Q,这样我们就可以开发一个很好的编码方案,每个事件的位数尽可能少.

我不应该说比特,因为如果我们在交叉熵的计算中使用基数2,我们只能使用比特作为度量.但是TensorFlow使用自然对数,所以让我们测量nat中的交叉熵.

因此,假设我们有一个糟糕的语言模型,它表示词汇表中的每个标记(字符/单词)同样可能成为下一个标记.对于1000个令牌的词汇表,该模型将具有log(1000)= 6.9 nats的交叉熵.在预测下一个标记时,它必须在每个步骤中均匀地选择1000个标记.

更好的语言模型将确定更接近P的概率分布Q.因此,交叉熵更低 - 我们可能得到3.9个nats的交叉熵.如果我们现在想要测量困惑,我们只需对交叉熵进行取幂:

exp(3.9)= 49.4

因此,对于我们计算损失的样本,良好的模型就像它必须在大约50个令牌中统一和独立地选择一样令人困惑.



1> Kilian Batzn..:

您引用的项目使用sequence_to_sequence_loss_by_example,它返回交叉熵损失.因此,为了计算训练困惑,您只需要像这里解释的那样对失去进行取幂.

train_perplexity = tf.exp(train_loss)

我们必须使用e代替2作为基础,因为TensorFlow使用自然对数(TF文档)测量交叉熵损失.谢谢@Matthias Arro和@Colin Skow的提示.

详细说明

当我们开发基于Q的编码方案时,两个概率分布P和Q的交叉熵告诉我们编码P事件所需的最小平均比特数.因此,P是真正的分布,我们通常不会我知道.我们希望找到一个尽可能接近P的Q,这样我们就可以开发一个很好的编码方案,每个事件的位数尽可能少.

我不应该说比特,因为如果我们在交叉熵的计算中使用基数2,我们只能使用比特作为度量.但是TensorFlow使用自然对数,所以让我们测量nat中的交叉熵.

因此,假设我们有一个糟糕的语言模型,它表示词汇表中的每个标记(字符/单词)同样可能成为下一个标记.对于1000个令牌的词汇表,该模型将具有log(1000)= 6.9 nats的交叉熵.在预测下一个标记时,它必须在每个步骤中均匀地选择1000个标记.

更好的语言模型将确定更接近P的概率分布Q.因此,交叉熵更低 - 我们可能得到3.9个nats的交叉熵.如果我们现在想要测量困惑,我们只需对交叉熵进行取幂:

exp(3.9)= 49.4

因此,对于我们计算损失的样本,良好的模型就像它必须在大约50个令牌中统一和独立地选择一样令人困惑.

推荐阅读
贴进你的心聆听你的世界
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有