nce_loss()
要求num_true
的静态int
值。这适用于每个训练示例具有相同数量的标签并且我们事先知道的问题。
当标签具有可变形状[None]
,并且按桶大小进行批处理和/或桶大小.padded_batch()
+.group_by_window()
时,有必要提供可变大小num_true
以习惯所有训练示例。据我所知,这目前不受支持(如果我错了,请纠正我)。
换句话说,假设我们有一个图像数据集,每个图像(狗、猫、鸭子等)都有任意数量的标签,或者有一个文本数据集,每个句子有多个类(class_1、class_2、...、class_n)。类不是互斥的,并且示例之间的大小可能会有所不同。 但是,由于可能的标签数量可能很大 10k-100k,有没有办法进行采样损失以提高性能(与sigmoid_cross_entropy
相比)?
是否有正确的方法来执行此操作或任何其他解决方法?
nce_loss = tf.nn.nce_loss(
weights=nce_weights,
biases=nce_biases,
labels=labels,
inputs=inputs,
num_sampled=num_sampled,
# Something like this:
# `num_true=(tf.shape(labels)[-1])` instead of `num_true=const_int`
# , would be preferable here
num_classes=self.num_classes)
我看到两个问题: 1)使用不同数量的真实值的NCE; 2) 不相互排斥的类。
对于第一个问题,正如@michal所说,人们期望将来包含此功能。我尝试了几乎相同的方法:使用带有shape=(None, None)
的标签,即true_values
维度None
。sampled_values
参数具有相同的问题:true_values
数字必须是固定整数。建议的解决方法是使用表示<PAD>
的类(0
是最好的类)并完成true_values
的数量。就我而言,0
是一个代表<PAD>
的特殊令牌。部分代码在这里:
assert len(labels) <= (window_size * 2)
zeros = ((window_size * 2) - len(labels)) * [0]
labels = labels + zeros
labels.sort()
我对标签进行了排序,因为考虑了另一个建议:
注意:默认情况下,这使用对数均匀(Zipfian)分布 抽样,因此您的标签必须按递减顺序排序 频率以达到良好的效果。
就我而言,特殊标记和更频繁的单词具有较低的索引,否则,不太频繁的单词具有较高的索引。我同时包括了与输入关联的所有标注分类,并以零完成直到true_values
数字。当然,最后必须忽略0
类。