ludwig 输出序列标注器概率错误

oxcyiej7  于 2个月前  发布在  其他
关注(0)|答案(8)|浏览(30)

描述bug

在Ludwig 0.1.x和0.2.x版本中,当使用标注器(如https://ludwig-ai.github.io/ludwig-docs/examples/#natural-language-understanding示例)进行输出特征时,所有不同的槽位都被正确地标记,并且对于每个槽位,您都会看到一个表示每个可能的槽位置信度的数组。
在0.4.0(以及0.3.x版本中也发生)的情况下,您会看到一个固定长度的置信度数组,长度为max_sequence_length,每个槽位有一个值。
我希望在每个输出槽位上有多个置信度数组,就像之前的版本一样,或者,如果这是有意的更改,我希望这个数组长度与输出标签长度相匹配(在您只想为每个槽位输出最大置信度值的情况下,我认为这不是情况)。

重现

像https://ludwig-ai.github.io/ludwig-docs/examples/#natural-language-understanding中展示的那样训练一个模型
对一句话进行推理
观察预测字段 slots_predictions 并注意其长度
观察预测字段 slots_probabilities 并注意其长度(总是设置为可能的最大输出值,并且对于未使用的标签有一个奇怪的默认值,没有表示每个槽位置信度的所有子数组)
Python 3.6和3.9
Ludwig 0.3.x、0.4.0、git+master当前版本
请注意:Ludwig 0.3.3具有不同的 slots_probabilities 输出格式。在0.4.0中,数组中出现了奇怪的"
",就像它正在被解析的文本一样,而在0.3.3中,它被正确地解析为数组。
还有一件事: slots_probability 应该是对所有被预测的槽位的整体置信度,但它经常是负值(这本不应该发生)。

kmpatx3s

kmpatx3s1#

移除所有概率的原因是因为输出Tensor会变得非常大(想象一下,批量大小为x,单词数为256,类别数为1000),在某些情况下,这会导致问题。
所以在这里我看到两件事我们可能想要做:

  1. 首先确保输出概率中表示最高概率的部分具有与输入相同的长度(这应该是一个简单的修复)
  2. 也许可以添加一个选项来获取完整的概率
c9x0cxw0

c9x0cxw02#

在我的使用场景中,我只需要与所选标签相关的概率,但我理解这种困境。
生成器是否有用?它不应该示例化对象,除非实际读取操作(我认为这是完美的使用场景,但我不知道如何将其整合)
无论如何,还有其他事情隐藏在那个东西后面......在概率数组中,我现在看到了转义的换行符(
),好像某种方式被转换/格式化为字符串。不知道这是否有趣...
感谢回复!

lvmkulzt

lvmkulzt3#

花了一点时间才看到这个,但我在这里 :)
这是我在解析话语时得到的slots_probabilities数组:
it is a nice day :
我原本以为会得到一个只显示5个值的数组,每个槽位一个,输出每个槽位的概率。
此外,这是相同话语的slots_probability:
-0.0029234159737825394
我肯定没想到这里有一个负值。
由于现在需要快速修复并使用它,我会进一步研究这个问题,希望我能找到罪魁祸首!
非常感谢任何帮助!

klsxnrf1

klsxnrf14#

...我似乎已经追踪到了@tgaddair一年前在这里做的一次提交中发生的变化:
651db58#diff-7e8779090e112c98d6b3730e70529a77a4bbc44d84ce469c2c066f7120df0752
尚未验证在此之前是否没有发生这种情况,但看到代码后,似乎正是从三维变为二维的地方发生了变化,但在值的聚合过程中出了问题 :)
这个函数可能有问题:
https://github.com/ludwig-ai/ludwig/blob/tf-legacy/ludwig/features/sequence_feature.py#L470-L483

iyfamqjs

iyfamqjs5#

花了一点时间才看到这个,但我在这里 :) 这是解析话语时得到的slots_probabilities数组:it is a nice day : [0.99996495, 0.9998147 , 0.99985003, 0.9999442 , 0.99750584,\n 0.38254768, 0.38254768, 0.38254768, 0.38254768, 0.38254768,\n 0.38254768, 0.38254768, 0.38254768, 0.38254768, 0.38254768,\n 0.38254768, 0.38254768, 0.38254768, 0.382547] 我原本以为会得到一个只显示5个值的数组,每个槽位一个,输出每个槽位的概率。
此外,这是相同话语的slots_probability:-0.0029234159737825394 我肯定没想到这里有负值。
我会进一步研究这个问题,因为现在这是我需要快速修复并使用的东西,希望我能找到罪魁祸首 :) 任何帮助都非常感谢!
嘿 @carlogrisetti !我相信这里的问题是我们正在采用的命名约定和一些隐含的事情没有明确说明。@justinxzhao 在这里标记你是因为你最近在这方面工作过,这样我们可以直接在代码中解决这个问题,或者/或者更好地记录这个问题。
关于slots_probabilities,我现在最好的直觉是告诉我,向量长度是训练集中槽位的固定长度,或者是批处理内的最大长度或指定的最大序列长度预处理参数。
这在实践中意味着只有前k个概率是相关的,其他槽位是被修剪掉的PAD。在你的例子中,前5.90+个概率与每个单词相关联,其余的应该被忽略。我认为我们也应该返回LENGTHS,这样人们就可以使用它们来识别每个向量的长度,比如slot_probabilities[:slot_length]。
我们的问题是我们需要修复这个问题并修剪到正确的长度吗?@justinxzhao wdyt?
关于slots_probability为负数,实际上报告的是整个序列的对数概率,所以它可能是负数。你可以将其指数化以获得常规概率,但整个序列的概率通常非常非常低(因为词汇量很大,序列中的每个元素有很多选项),所以通常更喜欢使用对数概率,因为它可以用来对多个可能的序列进行排序,而且不会受到潜在下溢问题的影响,而常规概率可能会受到这些问题的影响。
在这里,我们可能需要:1)验证对数概率仅考虑序列的前LENGTH个令牌计算;2)在文档中明确说明这是一个对数概率。
......我似乎已经追踪到了一年前@tgaddair所做的更改:651db58#diff-7e8779090e112c98d6b3730e70529a77a4bbc44d84ce469c2c066f7120df0752
还没有验证在此之前是否发生过这种情况,但从代码来看,这正是从三维变为二维的地方出了问题,但在聚合值时出现了问题 :)
这可能是这个函数出了问题:https://github.com/ludwig-ai/ludwig/blob/tf-legacy/ludwig/features/sequence_feature.py#L470-L483
返回3d概率(所有序列中所有可能元素的概率)可能会在许多情况下出现问题,例如如果有一个生成器和一个10000个词的词汇表,它将返回batch_size x sequence length x 10000。但是,对于大多数标注用例(而不是生成用例),词汇量并不是那么大。
所以我们可以做几件事:

  1. 为跟踪器额外返回3d概率。我们应该找到一个更好的命名方式,比如each_token_probabilties、best_sequence_rpobabilties、sequence_logprobability等,用户可以选择关闭。
  2. 为生成器添加一个可选标志,也返回3d概率(默认为false,但用户可以打开)
    你觉得这样可以吗?
    @tgaddair@justinxzhao 你们觉得呢?
    此外@jimthompson5802以前有过这样的经验,所以可能有意见
nwlls2ji

nwlls2ji6#

你好,@carlogrisetti 和 @w4nderlust ,

@geoffreyangus 可能在 Ludwig 0.5.dev 上遇到了一个相关(也许相同)的问题,Geoffrey 在 master 上修复了计算序列概率的问题(#1904)。

据我所知,原始代码(来自 tf-legacy)存在 bug,因为列表和 np.arrays 之间的项目分配不同,如果输入是 np.array,则概率计算不正确。

@carlogrisetti,你能尝试升级到 Ludwig 0.5 并看看这种糟糕/奇怪的行为是否已经得到解决吗?

8ftvxx2r

8ftvxx2r7#

哈哈...在当前项目实现中,我无法真正做到这一点,因为它接近于在生产环境中发布,当检查最后一个兼容版本时,这个问题已经出现了。
我可以尝试在不同的测试环境中使用0.5来确认问题是否已解决,但需要以某种方式回溯到tf-legacy。
谢谢!

wgx48brx

wgx48brx8#

你好,@carlogrisetti,0.5版本的更新是否解决了这个问题?

相关问题