Higher loss penalty for true non-zero predictions

前端 未结 1 1983
一整个雨季
一整个雨季 2021-01-20 04:02

I am building a deep regression network (CNN) to predict a (1000,1) target vector from images (7,11). The target usually consists of about 90 % zeros and on

1条回答
  •  伪装坚强ぢ
    2021-01-20 04:40

    Not sure there is anything better than a custom loss just like you did, but there is a cleaner way:

    def weightedLoss(w):
    
        def loss(true, pred):
    
            error = K.square(true - pred)
            error = K.switch(K.equal(true, 0), w * error , error)
    
            return error 
    
        return loss
    

    You may also return K.mean(error), but without mean you can still profit from other Keras options like adding sample weights and other things.

    Select the weight when compiling:

    model.compile(loss = weightedLoss(0.1), ...)
    

    If you have the entire data in an array, you can do:

    w = K.mean(y_train)
    w = w / (1 - w) #this line compesates the lack of the 90% weights for class 1
    

    Another solution that can avoid using a custom loss, but requires changes in the data and the model is:

    • Transform your y into a 2-class problem for each output. Shape = (batch, originalClasses, 2).

    For the zero values, make the first of the two classes = 1
    For the one values, make the second of the two classes = 1

    newY = np.stack([1-oldY, oldY], axis=-1)    
    

    Adjust the model to output this new shape.

    ...
    model.add(Dense(2*classes))
    model.add(Reshape((classes,2)))
    model.add(Activation('softmax'))
    

    Make sure you are using a softmax and a categorical_crossentropy as loss.

    Then use the argument class_weight={0: w, 1: 1} in fit.

    0 讨论(0)
提交回复
热议问题