[英]How to make a custom loss function in Keras properly
我正在制作一种模式,预测是来自 conv 层的矩阵。 我的损失函数是
def custom_loss(y_true, y_pred):
print("in loss...")
final_loss = float(0)
print(y_pred.shape)
print(y_true.shape)
for i in range(7):
for j in range(14):
tl = float(0)
gt = y_true[i,j]
gp = y_pred[i,j]
if gt[0] == 0:
tl = K.square(gp[0] - gt[0])
else:
for l in range(5):
tl = tl + K.square(gp[l] - gt[l])/5
final_loss = final_loss + tl/98
return final_loss
从参数打印出来的形状是
(?, 7, 14, 5)
(?, ?, ?, ?)
标签的形状为 7x14x5。
似乎损失函数被调用以获取一系列预测,而不是一次一个预测。 我对 Keras 比较陌生,不太了解这些东西是如何工作的。
这是我的模型
model = Sequential()
input_shape=(360, 640, 1)
model.add(Conv2D(24, (5, 5), strides=(1, 1), input_shape=input_shape))
model.add(MaxPooling2D((2,4), strides=(2, 2)))
model.add(Conv2D(48, (5, 5), padding="valid"))
model.add(MaxPooling2D((2,4), strides=(2, 2)))
model.add(Conv2D(48, (5, 5), padding="valid"))
model.add(MaxPooling2D((2,4), strides=(2, 2)))
model.add(Conv2D(24, (5, 5), padding="valid"))
model.add(MaxPooling2D((2,4), strides=(2, 2)))
model.add(Conv2D(5, (5, 5), padding="valid"))
model.add(MaxPooling2D((2,4), strides=(2, 2)))
model.compile(
optimizer="Adam",
loss=custom_loss,
metrics=['accuracy'])
print(model.summary())
我收到类似的错误
ValueError:维度 1 的切片索引 7 越界。 对于 'loss/max_pooling2d_5_loss/custom_loss/strided_slice_92' (op: 'StridedSlice') 输入形状:[?,7,14,5], [2], [2], [2] 和计算输入张量: input[ 1] = <0 7>,输入[2] = <1 8>,输入[3] = <1 1>。
我想我知道这是因为在使用 4D 时在许多预测中都给出了损失函数的参数。
我该如何解决? 是我分配损失函数的方式或损失函数的问题。 现在,损失函数的输出是一个浮点数。 但它应该是什么。
为了回答您的一些疑虑,
我没有看到有人在损失函数中使用循环
通常这是一个非常糟糕的做法。 深度网络通常在数百万个样本上进行训练。 因此,使用循环而不是使用矢量化操作会真正降低您的模型性能。
我不确定我是否在损失函数中准确地捕捉到了你想要的东西。 但我很确定它非常接近(如果不是,这就是您所需要的)。 我可以用固定的随机种子将你的损失与我的损失进行比较,看看我是否得到了你的损失函数给出的结果。 但是,由于您的损失不起作用,我不能这样做。
def custom_loss_v2(y_true, y_pred):
# We create MSE loss that captures what's in the else condition -> shape [batch_size, height, width]
mse = tf.reduce_mean((y_true-y_pred)**2, axis=-1)
# We create pred_first_ch tensor that captures what's in the if condition -> shape [batch, height, width]
pred_first_ch = tf.gather(tf.transpose(y_pred**2, [3,0,1,2]),0)
# We create this to get a boolean array that satisfy the conditions in the if else statement
true_first_zero_mask = tf.equal(tf.gather(tf.transpose(y_true, [3,0,1,2]),0), 0)
# Then we use tf.where with reduce_mean to get the final loss
res = tf.where(true_first_zero_mask, pred_first_ch, mse)
return tf.reduce_mean(res)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.