python CNTK 中损失函数的替代方案
Alternatives for loss functions in python CNTK
我在 CNTK 中创建了一个序列模型,并将该模型传递给损失函数,如下所示:
ce = cross_entropy_with_softmax(model, labels)
如前所述here并且由于我有多标签分类器,我想使用适当的损失函数。问题是我找不到任何合适的文档来在 Python 中找到这些损失函数。这个需求有什么建议或者示例代码吗
我应该注意到我在 BrainScript 语言中发现了这些替代方案(逻辑和加权逻辑),但在 Python.
中没有
目前,大多数运算符都在 cntk.ops
包中并记录在案 here。唯一的例外是与序列相关的运算符,它们位于 cntk.ops.sequence
中。
我们计划重组运算符 space(不破坏向后兼容性)以提高可发现性。
对于您的特定情况,cross_entropy_with_softmax
似乎是一个合理的选择,您可以找到它的示例文档 here. Please also check out this Jupyter Notebook 以获得完整的示例。
更新(基于以下评论):如果您使用的是顺序模型,那么您可能有兴趣对每个位置的损失序列中的所有头寸求和位置。 cross_entropy_with_softmax
适用于 per-position 损失,CNTK 将自动计算序列中所有位置的损失值总和。
请注意,这里的术语 multilabel
是 non-standard,因为它通常指的是多个二进制标签的问题。您 link 参考的维基页面指的是与您正在做的不同的情况。
原始答案(对实际的多标签情况有效):您将要使用 binary_cross_entropy 或 weighted_binary_cross_entropy
。 (我们决定在将其移植到 Python 时重命名 Logistic
)。在撰写本文时,这些操作仅支持 {0,1} 标签。如果您的标签在 (0,1) 中,那么您需要像这样定义损失
import cntk as C
my_bce = label*C.log(model)+(1-label)*C.log(1-model)
"my data has more than one label (three label) and each label has more than two values (30 different values)"
我没理解错吗,你有 3 个网络输出和关联的标签,每个都是 30 分之一的分类器?那么你似乎可以只添加三个 cross_entropy_with_softmax()
值。那是你想要的吗?
例如如果模型函数 returns 是一个三元组(以 return combine([z1, z2, z3])
之类的结尾),那么您传递给 Trainer 的标准函数可能如下所示(如果您不使用 Python 3,语法有点不同):
from cntk.layers.typing import Tensor, SparseTensor
@Function
def my_criterion(input : Tensor[input_dim], labels1 : SparseTensor[30],
labels2 : SparseTensor[30], labels3 : SparseTensor[30]):
z1, z2, z3 = my_model(input).outputs
loss = cross_entropy_with_softmax(z1, labels1) + \
cross_entropy_with_softmax(z2, labels2) + \
cross_entropy_with_softmax(z3, labels3)
return loss
learner = ...
trainer = Trainer(None, my_criterion, learner)
# in MB loop:
input_mb, L1_mb, L2_mb, L3_mb = my_next_minibatch()
trainer.train_minibatch(my_criterion.argument_map(input_mb, L1_mb, L2_mb, L3_mb))
我在 CNTK 中创建了一个序列模型,并将该模型传递给损失函数,如下所示:
ce = cross_entropy_with_softmax(model, labels)
如前所述here并且由于我有多标签分类器,我想使用适当的损失函数。问题是我找不到任何合适的文档来在 Python 中找到这些损失函数。这个需求有什么建议或者示例代码吗
我应该注意到我在 BrainScript 语言中发现了这些替代方案(逻辑和加权逻辑),但在 Python.
中没有目前,大多数运算符都在 cntk.ops
包中并记录在案 here。唯一的例外是与序列相关的运算符,它们位于 cntk.ops.sequence
中。
我们计划重组运算符 space(不破坏向后兼容性)以提高可发现性。
对于您的特定情况,cross_entropy_with_softmax
似乎是一个合理的选择,您可以找到它的示例文档 here. Please also check out this Jupyter Notebook 以获得完整的示例。
更新(基于以下评论):如果您使用的是顺序模型,那么您可能有兴趣对每个位置的损失序列中的所有头寸求和位置。 cross_entropy_with_softmax
适用于 per-position 损失,CNTK 将自动计算序列中所有位置的损失值总和。
请注意,这里的术语 multilabel
是 non-standard,因为它通常指的是多个二进制标签的问题。您 link 参考的维基页面指的是与您正在做的不同的情况。
原始答案(对实际的多标签情况有效):您将要使用 binary_cross_entropy 或 weighted_binary_cross_entropy
。 (我们决定在将其移植到 Python 时重命名 Logistic
)。在撰写本文时,这些操作仅支持 {0,1} 标签。如果您的标签在 (0,1) 中,那么您需要像这样定义损失
import cntk as C
my_bce = label*C.log(model)+(1-label)*C.log(1-model)
"my data has more than one label (three label) and each label has more than two values (30 different values)"
我没理解错吗,你有 3 个网络输出和关联的标签,每个都是 30 分之一的分类器?那么你似乎可以只添加三个 cross_entropy_with_softmax()
值。那是你想要的吗?
例如如果模型函数 returns 是一个三元组(以 return combine([z1, z2, z3])
之类的结尾),那么您传递给 Trainer 的标准函数可能如下所示(如果您不使用 Python 3,语法有点不同):
from cntk.layers.typing import Tensor, SparseTensor
@Function
def my_criterion(input : Tensor[input_dim], labels1 : SparseTensor[30],
labels2 : SparseTensor[30], labels3 : SparseTensor[30]):
z1, z2, z3 = my_model(input).outputs
loss = cross_entropy_with_softmax(z1, labels1) + \
cross_entropy_with_softmax(z2, labels2) + \
cross_entropy_with_softmax(z3, labels3)
return loss
learner = ...
trainer = Trainer(None, my_criterion, learner)
# in MB loop:
input_mb, L1_mb, L2_mb, L3_mb = my_next_minibatch()
trainer.train_minibatch(my_criterion.argument_map(input_mb, L1_mb, L2_mb, L3_mb))