【问题标题】:Custom metric in multi-output Keras model多输出 Keras 模型中的自定义指标
【发布时间】:2020-04-12 09:05:10
【问题描述】:

我正在处理一个自定义多位数字识别问题。我只有 1 位和 2 位数字。我正在使用一个 VGG16 模型,每个数字都有两个头,以避免有 100 个类。

模型如下所示:

input_shape = (256,96,3)
base_model = VGG16(weights='imagenet', include_top=False, input_shape = input_shape)
xo = base_model.output
x = base_model.input
flat = Flatten(name = 'flat')(xo)
h1 = Dense(1024, activation='relu', name = 'first_hidden_layer')(flat)
d1 = Dropout(0.5, name = 'first_hidden_dropout')(h1)
h2 = Dense(1024, activation='relu', name = 'second_hidden_layer')(d1)
d2 = Dropout(0.5, name = 'second_hidden_dropout')(h2)

o_digit1 = Dense(11, activation='softmax', name = 'digit1_classification')(d2)
o_digit2 = Dense(11, activation='softmax', name = 'digit2_classification')(d2)

model = Model(inputs = x, outputs = [o_digit1, o_digit2] )
opt = Adam(lr=0.0001)
model.compile(optimizer=opt, 
              loss='categorical_crossentropy',
              metrics={'digit1_classification': 'accuracy', 
                             'digit2_classification': 'accuracy'},
              loss_weights = {'digit1_classification': 0.5, 
                             'digit2_classification': 0.5})

我想构建一个自定义指标以传递给模型。计算实际数字精度的编译。通常,当您构建自己的度量函数时,您会将y_predy_true 传递给它。 例如

def my_metric1(y_true,y_pred):    
    return calculations (y_true, y_pred)

我可以使用my_metric1 来单独计算我想要的每个班级的任何内容,但我想要的是计算实际的完整数字准确度。 类似的东西:

def my_metric2(y_pred1, y_true1, y_pred2, y_true2):
    return calculations2(y_pred1, y_true1, y_pred2, y_true2)

这里的y_pred1, y_true1, y_pred2, y_true2 是每个数字的预测值和真实值。

我怎样才能做到这一点?

【问题讨论】:

  • 是否可以只有一个输出(前两个输出的串联)并为其定义自定义指标/损失?
  • 嗯..这可能是可能的。我需要弄清楚如何进行自定义损失,因为我将无法进行 categorical_crossentropy,因为如果我将两个输出存储到一个向量中,它就不会再进行一次热编码了。
  • 自定义损失就像自定义指标一样,只是它必须是可区分的。

标签: tensorflow keras deep-learning conv-neural-network vgg-net


【解决方案1】:

如果您使用 2 位数字作为单独的输出,那么您可以创建一个类似这样的自定义损失函数 -

import numpy as np

# Define custom loss
# Create a loss function that adds the MSE loss to the mean of all squared activations
def custom_loss(y_pred1, y_true1, y_pred2, y_true2):
    Loss = 0

    def loss1(y_true1,y_pred1):
        return np.square(np.subtract(y_true1,y_pred1)).mean()

    def loss2(y_true2,y_pred2):
        return np.square(np.subtract(y_true2,y_pred2)).mean()

    def finalloss(y_pred1, y_true1, y_pred2, y_true2):
        Loss = loss1(y_pred1, y_true1) + loss2(y_pred2, y_true2)
        if(y_pred1 == y_true1 and y_pred2 == y_true2):
           return(0)
        elif(y_pred1 == y_true1 and y_pred2 != y_true2):
            return(0.5 * Loss)
        elif(y_pred1 != y_true1 and y_pred2 == y_true2):
            return(0.5 * Loss)    
        else:
            return(Loss)

    return finalloss(y_pred1, y_true1, y_pred2, y_true2)

# Compile the model
model.compile(optimizer='adam',
              loss=custom_loss, # Call the loss function 
              metrics=['accuracy'])

# train
model.fit(data, labels)  

更好的是在模型中只为两个数字提供一个输出。像这样的完全连接的 [1x1x2] 层。您可以找到多位检测器文章here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-26
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 2020-02-05
    • 1970-01-01
    • 2017-06-02
    相关资源
    最近更新 更多