python - 跳过 bidirectional_dynamic_rnn 中的值
问题描述
我想在整个文档上使用 BERT 嵌入来实现 NER。一个文档由几个句子组成,每个句子由标记组成并且长度可变。现在,我使用 BERT 为每个句子创建词嵌入并填充每个句子。然后我想用双向 LSTM 对文档的所有标记执行 NER,而不仅仅是句子。
如果我在没有微调 BERT(提取像 ElMo 嵌入这样的特征)的情况下这样做,那么我可以在将它们输入双向 LSTM 之前删除填充的标记并连接所有句子。
但是我怎样才能在微调设置中做到这一点呢?
我的输入具有以下形状:[文档、句子、标记]
对于 BERT,我将输入重塑为:[文档 * 句子、标记]
然后我想把 BERT 的输出放到一个 bidirectional_dynamic_rnn 中,形状为 [documents, sentence * tokens]。不幸的是,这些句子包含填充标记(零),bidirectional_rnn 应该跳过它们。
我不能使用 bidirectional_dynamic_rnn 的 sequence_length 参数,因为填充的标记可能在序列内。例如,一个文档由两个句子组成:
s1=[1, 2, 3, 0, 0]
s1=[10, 20, 30, 40, 50]
如果我连接我得到的句子
s1+s2=[1, 2, 3, 0, 0, 10, 20, 30, 40, 50]
bidirectional_dynamic_rnn 现在应该跳过零。
我怎样才能做到这一点?
解决方案
我编写了一个小例子来将填充值排序到列表的末尾。我不确定该解决方案的效率如何,但我希望它会有所帮助。
import tensorflow as tf
vec = tf.convert_to_tensor([[1, 2, 3, 0, 0, 10, 20, 30, 40, 50], [1, 2, 3, 4, 5, 0, 0, 0, 7, 0]])
number_mask = tf.cast(tf.not_equal(vec, 0), dtype=tf.int32)
pad_mask = 1 - number_mask
index_list = tf.cumsum(tf.ones_like(number_mask), axis=-1) - 1
fill_values = tf.reduce_max(index_list, axis=-1, keep_dims=True) + 1
content = index_list * number_mask + pad_mask * fill_values
pad = index_list * pad_mask - number_mask
content_sort = tf.sort(content, axis=1)
pad_sort = tf.sort(pad, axis=1)
content_sort_mask = tf.cast(tf.less(content_sort, fill_values), tf.int32)
pad_sort_mask = tf.cast(tf.greater(pad_sort, -1), tf.int32)
result_index = content_sort * content_sort_mask + pad_sort * pad_sort_mask
result = tf.batch_gather(vec, result_index)
with tf.Session() as sess:
print(sess.run([result]))
# [array([[ 1, 2, 3, 10, 20, 30, 40, 50, 0, 0],
[ 1, 2, 3, 4, 5, 7, 0, 0, 0, 0]], dtype=int32)]
推荐阅读
- python - 如何避免被 ReCAPTCHA V2 识别?
- html - 域上的反应项目显示空白页面
- go - 您如何使用 Go 驱动程序从机器人发送直接消息?
- html - 如何在 iframe 中打开页面?
- hash - 用于等长十六进制字符串列表的简单且良好的哈希函数
- python - 将多个 plotly.express.bar 图形添加到一个窗口中
- java - 如果出现异常,我如何以编程方式重新启动我的 Spring 应用程序?
- sql - 在 where 子句中不知道 LHS 和 RHS 的情况下编写 SQL 查询
- c# - 从一组控件中的选定控件中获取数据行
- autodesk-forge - 如何在悬停时获取覆盖几何的位置?