简体   繁体   中英

How to evaluate a multi input/output model in keras?

I've followed the description on this guide by keras to build the following model with multi-input and multi-output.

## define the model
EMBEDDING_SIZE = 128
HIDDEN_LAYER_SIZE = 64
BATCH_SIZE = 32
NUM_EPOCHS = 10

# first input model
main_input = Input(shape=(50,), dtype='int32', name='main_input')
embedding = Embedding(MAX_NB_WORDS, EMBEDDING_SIZE,
                    input_length=MAX_SEQUENCE_LENGTH)(main_input)
lstm_out = LSTM(HIDDEN_LAYER_SIZE)(embedding)
auxiliary_output = Dense(4, activation='sigmoid', name='aux_output')(lstm_out)
# second input model
auxiliary_input = Input(shape=(5,), name='aux_input')
x = concatenate([lstm_out, auxiliary_input])

x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)

main_output = Dense(4, activation='sigmoid', name='main_output')(x)

model = Model(inputs=[main_input, auxiliary_input], outputs=[main_output, auxiliary_output])

model.compile(optimizer='rmsprop',
              loss={'main_output': 'categorical_crossentropy', 'aux_output': 'categorical_crossentropy'},
              loss_weights={'main_output': 1., 'aux_output': 0.2})

model.fit([x1train, x2train], [ytrain, ytrain],
                    epochs=NUM_EPOCHS, batch_size=BATCH_SIZE,
                    validation_data=([x1test, x2test], [ytest, ytest]))

In the next step, I want to evaluate my model as well. I suggested running this code for it:

score, acc = model.evaluate(x={'main_input': x1test, 'aux_input': x2test},
                            y={'main_output': ytest, 'aux_output': ytest},
                            batch_size=BATCH_SIZE)

But with that code I am getting the error "ValueError: too many values to unpack (expected 2)"

So I thought I maybe get a score and accuracy for both outputs and tried this code, too:

score1, score2, acc1, acc2 = model.evaluate(x={'main_input': x1test, 'aux_input': x2test},
                            y={'main_output': ytest, 'aux_output': ytest},
                            batch_size=BATCH_SIZE)

but now I am getting the error "ValueError: not enough values to unpack (expected 4, got 3)"

So what am I doing wrong? I am just interested in the accuracy of my main_output to be honest.

From keras documentation for evaluate the can be found here

Returns

Scalar test loss (if the model has a single output and no metrics) or list of scalars (if the model has multiple outputs and/or metrics). The attribute model.metrics_names will give you the display labels for the scalar outputs.

According to your model, if you do print(model.metrics_names) you will get ['loss', 'main_output_loss', 'aux_output_loss'] .

The model.evaluate produces a scalar of this format, which indicates what each of those numbers you see in the output of evaluate method corresponds to.

Hence your code,

score1, score2, acc1, acc2 = model.evaluate(x={'main_input': x1test, 'aux_input': x2test},
                            y={'main_output': ytest, 'aux_output': ytest},
                            batch_size=BATCH_SIZE)

will result in an error because there are only 3 indices in the scalar and the code expects to find 4 .

Also,

score, acc = model.evaluate(x={'main_input': x1test, 'aux_input': x2test},
                            y={'main_output': ytest, 'aux_output': ytest},
                            batch_size=BATCH_SIZE)

will result in an error due to the fact there are more values returned by the evaluate .

You can do something like this if you want to unpack the result of evaluate in your model directly.

loss, main_loss, aux_loss = model.evaluate(x={'main_input': x1test, 'aux_input': x2test},
                            y={'main_output': ytest, 'aux_output': ytest},
                            batch_size=BATCH_SIZE)

Also in your code, I can see acc1 and acc2 which makes me assume that you are expecting to evaluate the model accuracy.

Having said that, I can see that you have not used any metrics for compilation of the model. If you want to evaluate acc of the model then compile your model like this.

model.compile(optimizer='rmsprop',
              loss={'main_output': 'categorical_crossentropy', 'aux_output': 'categorical_crossentropy'},
              loss_weights={'main_output': 1., 'aux_output': 0.2}, metrics=['acc'])

Then on model.evaluate() you will get a scalar corresponding to

['loss',
 'main_output_loss',
 'aux_output_loss',
 'main_output_acc',
 'aux_output_acc']

Hence, you can unpack it like this,

loss, main_loss, aux_loss, main_acc, aux_acc = model.evaluate(x={'main_input': x1test, 'aux_input': x2test},
                                y={'main_output': ytest, 'aux_output': ytest},
                                batch_size=BATCH_SIZE)

You haven't defined in the model compile that you want accuracy, so when you use evaluate the function will return the loss. You have 3 losses here which evaluate returns:

  • (1) Weighted averaged loss of (2) and (3), in your case: 1. * (2) + 0.2 * (3)
  • (2) Loss of main_output - categorical_crossentropy
  • (3) Loss of aux_output - categorical_crossentropy

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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