Tensorflow 实现 crf 损失

Posted

技术标签:

【中文标题】Tensorflow 实现 crf 损失【英文标题】:Tensorflow implementing crf loss 【发布时间】:2018-12-08 20:17:04 【问题描述】:

我正在尝试在 Tensorflow 图中使用条件随机场损失。

我正在执行序列标记任务:

我有一个元素序列作为输入[A, B, C, D]。每个元素可以属于 3 个不同类别中的一个。 类以 one-hot 编码方式表示:属于类 0 的元素由向量表示 [1, 0, 0]

我的输入标签 (y) 有大小 (batch_size x sequence_length x num_classes)。

我的网络生成具有相同形状的 logits。

假设我所有的序列长度都是 4。

这是我的代码:

import tensorflow as tf

sequence_length = 4
num_classes = 3
input_y = tf.placeholder(tf.int32, shape=[None, sequence_length, num_classes])
logits = tf.placeholder(tf.float32, shape=[None, None, num_classes])
dense_y = tf.argmax(input_y, -1, output_type=tf.int32)

log_likelihood, _ = tf.contrib.crf.crf_log_likelihood(logits, dense_y, sequence_length)

我收到以下错误:

文件“”,第 1 行,在 文件“/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/crf/python/ops/crf.py”,第 182 行,在 crf_log_likelihood 过渡参数) 文件“/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/crf/python/ops/crf.py”,第 109 行,在 crf_sequence_score false_fn=_multi_seq_fn) 文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/layers/utils.py”,第 206 行,在 smart_cond pred, true_fn=true_fn, false_fn=false_fn, name=name) 文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/smart_cond.py”,第 59 行,在 smart_cond 名称=名称) 文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/util/deprecation.py”,第 432 行,在 new_func 返回函数(*args,**kwargs) 文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/control_flow_ops.py”,第 2063 行,cond orig_res_t, res_t = context_t.BuildCondBranch(true_fn) BuildCondBranch 中的文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/control_flow_ops.py”,第 1913 行 original_result = fn() _single_seq_fn 中的文件“/usr/local/lib/python2.7/dist-packages/tensorflow/contrib/crf/python/ops/crf.py”,第 95 行 array_ops.concat([example_inds, tag_indices], axis=1)) 文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/gen_array_ops.py”,第 2975 行,在gather_nd “GatherNd”,参数 = 参数,索引 = 索引,名称 = 名称) _apply_op_helper 中的文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/op_def_library.py”,第 787 行 op_def=op_def) 文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py”,第 3392 行,在 create_op op_def=op_def) init 中的文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py”,第 1734 行 控制输入​​操作) _create_c_op 中的文件“/usr/local/lib/python2.7/dist-packages/tensorflow/python/framework/ops.py”,第 1570 行 引发 ValueError(str(e)) ValueError:indices.shape[-1] 必须

【问题讨论】:

【参考方案1】:

错误是由于序列长度变量的维度错误。它必须是向量,而不是标量。

import tensorflow as tf

num_classes = 3
input_x = tf.placeholder(tf.int32, shape=[None, None], name="input_x")
input_y = tf.placeholder(tf.int32, shape=[None, sequence_length, num_classes])
sequence_length = tf.reduce_sum(tf.sign(input_x), 1)

# After some network operation you will come up with logits

logits = tf.placeholder(tf.float32, shape=[None, None, num_classes])
dense_y = tf.argmax(input_y, -1, output_type=tf.int32)
log_likelihood, _ = tf.contrib.crf.crf_log_likelihood(logits, dense_y, sequence_length

【讨论】:

如何使用它来训练神经网络进行分割? (例如,当您使用交叉熵 + 正则化和 CRF 损失时)。假设您的代码中的网络输出是“logits”; 'input_y' 是真正的分割掩码(重新整形为 [None, sequence_length, num_classes])。为了评估成本,我将计算: 1) dense_y = tf.argmax(input_y, -1, output_type=tf.int32) 2) crf_loss, _ = tf.contrib.crf.crf_log_likelihood(logits, dense_y, sequence_length) 3 ) loss = cross_entropy + crf_loss 这是正确的吗?我错过了什么?谢谢你:)

以上是关于Tensorflow 实现 crf 损失的主要内容,如果未能解决你的问题,请参考以下文章

TensorFlow学习(十四):条件随机场CRF

CRF++工具包的使用

使用 TensorFlow 实现联合损失的交集

实现二元交叉熵损失给出了与 Tensorflow 不同的答案

在 biLSTM 之上使用 tfa.layers.crf

损失函数tensorflow2实现——Python实战