我的目的是实现一个自定义损失函数,以使用TensorFlow作为后端在Keras中训练模型。损失函数W和H分别代表softmax层输出的宽度和高度,N是批处理大小。变量p是FCN为正确类别预测的概率。该损失函数来自本文。在此实现中,N is 4, W is 200 and H is 400。最后一层的输出形状为(None, 400, 200, 2)。单个标签的形状是(400, 200, 2)每个通道代表一个类的位置。迄今为止,一个Numpy的实现:即使这在这种情况下没有用,这也是我想要实现为损失函数的目的。def loss_using_np(y_true, y_pred): ''' Assuming, `y_true` and `y_pred` shape is (400, 200, 2). This might change to (None, 400, 200, 2) while training in batch? ''' dx = 0.0000000000000001 # Very small value to avoid -infinity while taking log y_pred = y_pred + dx class_one_pred = y_pred[:, :, 0] class_two_pred = y_pred[:, :, 1] class_one_mask = y_true[:, :, 0] == 1.0 class_two_mask = y_true[:, :, 1] == 1.0 class_one_correct_prob_sum = np.sum(np.log(class_one_pred[class_one_mask])) class_two_correct_prob_sum = np.sum(np.log(class_two_pred[class_two_mask])) N = 4 H = 400 W = 200 return -1 * ((class_one_correct_prob_sum + class_two_correct_prob_sum) / ( N * H * W))上面的实现给出了预期的输出;不好的是它不能被使用。y_true = np.random.randint(2, size=(400, 200, 2))y_pred = np.random.random((400, 200, 2))loss_using_np(y_true, y_pred)尝试失败01import tensorflow as tf # not a good practice to not use keras.backend?def loss_function(y_true, y_pred): # Not a working solution as it raises # ResourceExhaustedError: OOM when allocating tensor with shape[311146,3,400,2] BUT WHY? N = 4 # batch size W = 200 H = 400 dx = 0.0000000000000001 y_pred = tf.add(y_pred, dx)问题您能告诉我如何在没有任何警告的情况下实现此损失功能吗?我不确定#02是正确的实现。我正在寻找一种优化的解决方案。任何帮助或指针,我们将不胜感激。我试图理解loss_function()使用print语句内部发生的情况,但是在我compile建模时这些语句仅打印一次。有什么办法可以记录此信息?如@ dennis-ec所述,可以tf.Print()用于调试。边注我Keras 2.1.4与TensorFlow 1.4.0-rc1和一起使用Python 3.5.2。
1 回答

沧海一幻觉
TA贡献1824条经验 获得超5个赞
在我看来,作者似乎在使用香草二进制交叉熵损失进行多标签分类。他们也这样命名,但是与在Keras中实现它的方式相比,它们的定义有点奇怪。
基本上,您可以使用binary_crossentropy损失函数并将标签提供为形状数组,(400, 200, 1)其中0表示第一类,而1表示第二类。这样,您的网络输出将具有相同的形状,并sigmoid在每个输出节点处具有激活功能。这就是通常在Keras中实现语义分割模型的方式。有关示例,请参见此回购:
# final layer, sigmoid activations
conv10 = Conv2D(1, 1, activation = 'sigmoid')(conv9)
model = Model(input = inputs, output = conv10)
# binary_crossentropy loss for multi-label classification
model.compile(optimizer = Adam(lr = 1e-4), loss = 'binary_crossentropy', metrics = ['accuracy'])
这应该给出与本文定义的实现完全相同的结果(他们可能未使用Keras)。
添加回答
举报
0/150
提交
取消