简体   繁体   English

Keras 中的自定义损失和准确性

[英]Custom loss and accuracy in Keras

I want to extend the output of the network to two outputs in this code我想在这段代码中将网络的输出扩展到两个输出

# Model architecture
  input = Input(shape = (max_len,))
  model = Embedding(input_dim = len(words) + 2, output_dim = embedding, input_length = max_len, mask_zero = True)(input)
  model = Bidirectional(LSTM(units = 50, return_sequences=True, recurrent_dropout=0.1))(model)
  model = TimeDistributed(Dense(50, activation="relu"))(model)
  crf = CRF(num_tags+1)  # CRF layer
  out = crf(model)  # output

  model = Model(input, out)
  model.compile(optimizer="rmsprop", loss=crf.loss_function, metrics=[crf.accuracy])

(The original code is at https://github.com/Akshayc1/named-entity-recognition.git ). (原始代码位于https://github.com/Akshayc1/named-entity-recognition.git )。 I want the loss function to be the summation of losses for these two outputs, and accuracy to be mean of accuracy for these two outputs, I followed the available instructions:我希望损失函数是这两个输出的损失总和,并且精度是这两个输出的精度的平均值,我遵循了可用的说明:

model = TimeDistributed(Dense(50, activation="relu"))(model)
model1 = TimeDistributed(Dense(50, activation="relu"))(model)
crf1 = CRF(num_tags+1)  # CRF layer
crf2 = CRF(num_tags+1)
out1 = crf1(model)  # output
out2 = crf2(model1) 

model = Model(input, [out1, out2])

def custom_loss(y_true, y_pred1,  y_pred2):
    loss1 = losses.categorical_crossentropy(y_true,y_pred1)
    loss2 = losses.categorical_crossentropy(y_true,y_pred2)
    return (loss1 + loss2)/2


def Custom_accuracy(y_true, y_pred1,y_pred2, k=10):
    acc1 = K.mean(K.in_top_k(y_pred, K.argmax(y_true, axis=-1), k), axis=-1)
    acc2 = K.mean(K.in_top_k(y_pred1, K.argmax(y_true, axis=-1), k), axis=-1)
    acc = (acc1 + acc2)/2
    return acc
model.compile(optimizer="rmsprop", loss=custom_loss,metrics=Custom_accuracy) 

but this shows the error:但这显示了错误:

TypeError: custom_loss() missing 1 required positional argument: 'y_pred2'

It can be solved by passing two loss functions to loss argument in model.compile than to pass three variables in loss function as described in the documentation and also make classes for custom metric and loss .它可以通过将两个损失函数传递给model.compile loss参数来解决, model.compile不是像文档中描述的那样在损失函数中传递三个变量,并为自定义 metric 和 loss创建类。 Make the following changes -进行以下更改 -

...

crf1 = CRF(num_tags+1,name="out1") <-- # change 1
crf2 = CRF(num_tags+1,name="out2") <-- # change 2
out1 = crf1(model)  
out2 = crf2(model1) 

model = Model(input, [out1, out2])

<define accuracy class and create its object> <-- # change 3
<define loss class and create its object> <-- # change 4

model.compile(optimizer="rmsprop", 
            loss={"out1":<loss_object_1>,"out2":<loss_object_2>},
            metrics={"out1":<accuracy_object_1>,"out2":<accuracy_object_2>}) <-- # change 5 

I think that is because the output of the model is not two outputs values( like o1,o2 ), but a list of two values(like [o1,o2] ).我认为这是因为模型的输出不是两个输出值(如o1,o2 ),而是两个值的列表(如[o1,o2] )。 Try this custom loss function, hopefully it gets the issue gone:试试这个自定义损失函数,希望它可以解决问题:

def custom_loss(y_true, y_predsList):
    y_pred1,  y_pred2 = y_predsList
    loss1 = losses.categorical_crossentropy(y_true,y_pred1)
    loss2 = losses.categorical_crossentropy(y_true,y_pred2)
    return (loss1 + loss2)/2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM