张量流中具有多个输出的自定义损失函数

数据挖掘 机器学习 神经网络 深度学习 张量流
2022-02-14 03:30:14

我的网络有两个输出和一个输入。我正在尝试编写自定义损失函数

Loss=Loss1(y1true,y1pred)+Loss2(y2true,y2pred)
我能够为单个输出编写自定义损失函数。但是对于多个输出,我很震惊。下面我写了一个我试过的mwe

def model(input_shape=4, output_shape=3, lr=0.0001):
    """
    single input and multi-output
    loss = custom_loss(out_1_true, out_1_pred)+mse(out_2_true, out_2_pred))
    """
    input_layer = Input(input_shape)
    layer_1 = Dense(units=32, activation='elu', kernel_initializer='he_uniform')(input_layer)
    #outputs
    y_1 = Dense(units=output_shape, activation='softmax', kernel_initializer='he_uniform')(layer_1)
    y_2 = Dense(units=1, activation='linear', kernel_initializer='he_uniform')(layer_1)
    
    def custom_loss(y_true, y_pred):

        # both true value of out_1, out_2 are encoded in y_true
        y_true_1     = y_true[:, :1+output_shape]
        y_true_2     = y_true[:, 1+output_shape:]

        #(this part is wrong...I dont know how)
        y_pred_1, y_pred_2 =  y_pred[:, :1+output_shape], y_pred[:, 1+output_shape:]

        #custorm loss for y_pred_1
        entropy_loss = -y_pred_1 * K.log(y_true_1 + 1e-10)

        #mse for y_pred_2
        mse          = -K.mean(K.square(y_pred_2 - y_true_2))

        #net loss
        loss = entropy_loss + C * mse
        return loss

    Network_model = Model(inputs = input_layer, outputs = [y_1, y_2])
    Network_model.compile(loss = custom_loss, optimizer=RMSprop(lr=lr))

    return Network_model

我认为,主要问题在于吐出y_pred张量。

PS:出于mwe的目的,我在上面的代码中使用了正常的交叉熵损失和mse损失函数。但是,我有不同的成本函数。

1个回答
def model(input_shape=4, output_shape=3, lr=0.0001):
    """
    single input and multi-output
    loss = custom_loss(out_1_true, out_1_pred)+mse(out_2_true, out_2_pred))
    """
    input_layer = Input(input_shape)
    layer_1 = Dense(units=32, activation='elu', kernel_initializer='he_uniform')(input_layer)

    # STEP-1:   name your outputs
    y_1 = Dense(units=output_shape, activation='softmax', kernel_initializer='he_uniform', name='actions')(layer_1)
    y_2 = Dense(units=1, activation='linear', kernel_initializer='he_uniform', name='values')(layer_1)
    
    # STEP-2:    Define the custom custom_loss. Note that the args should be y_true, y_pred
    def custom_loss(y_true, y_pred):
        entropy_loss = -y_pred * K.log(y_true + 1e-10)
        return entropy_loss

    # STEP-3:   Define the dicts for loss and lossweights with keys as the name of the output layers
    LossFunc    =     {'actions':custom_loss, 'values':'mse'}
    lossWeights =     {'actions':0.5, 'values':0.5}


    Network_model = Model(inputs = input_layer, outputs = [y_1, y_2])

    # STEP-4:   complie using LossFunc and lossWeights dicts
    Network_model.compile(optimizer=RMSprop(lr=lr), loss=LossFunc, loss_weights=lossWeights, metrics=["accuracy"])

    return Network_model

#training example:

#model
Network_model = model(4,2)
# input
S = np.reshape([1.,2.,3.,4.], (1, -1))
#true outputs
action, value = np.reshape([0.1], (1, -1)), np.reshape([0.1, 0.9] , (1, -1))
Y = [action, value]


Network_model.fit(S, [A_t, V_t])


1/1 [==============================] - 0s 2ms/step - loss: 6.7340 - actions_loss: 1.1512 - values_loss: 12.3169 - actions_accuracy: 0.0000e+00 - values_accuracy: 1.0000