为边界框回归制定一个平均交并比的自定义损失函数。

3
我试图逐个迭代批次来计算平均交并比。但是fit函数显示了以下错误:
“错误: 操作的梯度为None。请确保所有操作都定义了梯度(即可微分)。没有梯度的常见操作: K.argmax、K.round、K.eval。”
由于我是keras的新手,请帮忙解决问题。
#y_true shape: (None, 4)
import keras.backend as K
def iou(y_true, y_pred):
    # determine the (x, y)-coordinates of the intersection rectangle
    iou = 0
    for i in range(K.int_shape(y_pred)[0]):
        boxA = y_pred[i]
        boxB = y_true[i]
        xA = K.max(boxA[0], boxB[0])
        yA = K.max(boxA[2], boxB[2])
        xB = K.min(boxA[1], boxB[1])
        yB = K.min(boxA[3], boxB[3])

        interArea = K.max(0, xB - xA + 1) * K.max(0, yB - yA + 1)

        boxAArea = (boxA[1] - boxA[0] + 1) * (boxA[3] - boxA[2] + 1)
        boxBArea = (boxB[1] - boxB[0] + 1) * (boxB[3] - boxB[2] + 1)

        iou += interArea / float(boxAArea + boxBArea - interArea)
    #MEAN
    mean = iou/K.int_shape(y_pred)[0]
    return 1-mean

model.compile(optimizer='adam', loss=iou, metrics=['accuracy'])
model.fit(x_train, y_train, epochs=20, batch_size = 50)

我的模型使用均方误差作为损失函数表现良好。模型:

input_shape = (180, 240, 3)
model = Sequential([
    Conv2D(32, (3, 3), input_shape=input_shape, padding='same',activation='relu'),
    MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
    BatchNormalization(),

    Conv2D(64, (3, 3), activation='relu', padding='same'),
    MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
    BatchNormalization(),

    Conv2D(128, (3, 3), activation='relu', padding='same',),

    Conv2D(256, (3, 3), activation='relu', padding='same',),
    MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),

    Conv2D(128, (3, 3), activation='relu', padding='same',),
    MaxPooling2D(pool_size=(2, 2), strides=(2, 2)),
    BatchNormalization(),
    Flatten(),
    Dense(4096, activation='relu'),
    Dense(4096, activation='relu'),
    Dense(4, activation='relu')
])

你的 model 定义在哪里?loss=iou 是什么意思(在 Keras 中不存在)?你定义的函数在哪里使用? - desertnaut
糟糕!那是一个打错字了,函数名应该是iou。已经修改。 - Aakash kumar Goryan
1个回答

0

这意味着你自定义的损失函数内的所有操作都应该是可微分的,否则优化过程无法执行。为此,你只需要逐个检查代码中哪些操作不可微分,并将其替换为Keras可微分后端模拟或找到其他替代方法。

考虑到提供的代码片段,可能有几种建议可以使其正常工作:

  • for循环应该向量化
  • 由于你使用max(0, ...)来获取交集面积,可能会出现它始终为0且没有梯度可用的情况,因此请检查是否卡在那里
  • 对于均值计算,有一个现成的Keras后端函数K.mean
  • 限制值的范围以改善优化是一个好习惯(例如,将其限制在(0,1)范围内)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接