如何防止keras自定义损失函数中的负面预测

时间:2018-07-20 11:37:40

标签: python tensorflow machine-learning keras computer-vision

我正在使用自定义损失函数:

def ratio_loss(y, y0):
   return (K.mean(K.abs(y - y0) / y))

并获得负的预测值-在我的情况下,这不会产生场景(我使用CNN和回归作为最后一层来获取对象的长度)。 我使用除法是为了对真实值相对于预测值相对较小的地方加重惩罚。

我如何防止负面预测?

这是模式(目前是..):

def create_model():
    model = Sequential()
    model.add(Conv2D(128, kernel_size=(3, 3), activation='relu', padding='same', input_shape=(128, 128, 1)))
    model.add(Dropout(0.5))

    model.add(Conv2D(128, kernel_size=(3, 3), activation='relu', padding='same'))
    model.add(Dropout(0.25))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Conv2D(64, kernel_size=(3, 3), activation='relu', padding='same'))
    model.add(Dropout(0.25))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2, 2)))
    #
    #
    model.add(Conv2D(64, kernel_size=(3, 3), activation='relu', padding='same'))
    model.add(Dropout(0.25))
    model.add(BatchNormalization())
    model.add(MaxPooling2D(pool_size=(2, 2)))

    model.add(Flatten())
    model.add(Dense(512, activation='relu'))

    model.add(Dropout(0.15))
    model.add(Dense(1))
    #model.compile(loss=keras.losses.mean_squared_error, optimizer=keras.optimizers.Adadelta(), metrics=[sacc])
    model.compile(loss=ratio_loss, optimizer=keras.optimizers.Adadelta(), metrics=[sacc])
    return model

谢谢, 阿米尔

2 个答案:

答案 0 :(得分:0)

def ratio_loss(y, y0):
    return (K.mean(K.abs(y - y0 / y)))

但是您的预期输出范围是多少?

您可能应该在最后使用一些激活功能,例如:

  • activation ='sigmoid'-从0到1
  • activation = 'tanh'-从-1到+1
  • activation = 'softmax'-如果是只有一个正确类的分类问题
  • actication = 'softplus'-从0到+ inf。

最后一层的用法:

model.add(Dense(1,activation='sigmoid')) #from 0 to 1

#optional, from 0 to 200 after using the sigmoid above
model.add(Lambda(lambda x: 200*x))

提示:如果您是入门者,请避免使用过多的“ relu”,它通常卡在0中,并且必须与精心选择的学习率一起使用。

答案 1 :(得分:0)

您可以继续训练您的神经网络,希望它会学会不做任何低于0的预测(假设所有训练数据的输出都低于0)。然后,您可以在其中添加一个预测后的步骤,然后将其变为。如果预测低于0,则可以将其转换为0。

您可以添加激活功能,如DanielMöller回答。

这将涉及更改

model.add(Dense(1))

model.add(Dense(1, activation='softplus'))

由于您提到您希望注释中的输出在0到〜200之间。 这样可以保证输出不会低于0。