2017-08-21 85 views
5

Szkolę prosty model w kamerze dla zadania NLP z następującym kodem. Nazwy zmiennych są oczywiste dla zestawu do pociągu, testu i walidacji. Ten zbiór danych zawiera 19 klas, więc końcowa warstwa sieci ma 19 wyjść. Etykiety są również kodowane za jednym razem.Keras: model.evaluate vs model.predict Różnica dokładności w zadaniu NLP z wieloma klasami

nb_classes = 19 
model1 = Sequential() 
model1.add(Embedding(nb_words, 
        EMBEDDING_DIM, 
        weights=[embedding_matrix], 
        input_length=MAX_SEQUENCE_LENGTH, 
        trainable=False)) 
model1.add(LSTM(num_lstm, dropout=rate_drop_lstm, recurrent_dropout=rate_drop_lstm)) 
model1.add(Dropout(rate_drop_dense)) 
model1.add(BatchNormalization()) 
model1.add(Dense(num_dense, activation=act)) 
model1.add(Dropout(rate_drop_dense)) 
model1.add(BatchNormalization()) 

model1.add(Dense(nb_classes, activation = 'sigmoid')) 


model1.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) 
#One hot encode all labels 
ytrain_enc = np_utils.to_categorical(train_labels) 
yval_enc = np_utils.to_categorical(val_labels) 
ytestenc = np_utils.to_categorical(test_labels) 

model1.fit(train_data, ytrain_enc, 
      validation_data=(val_data, yval_enc), 
      epochs=200, 
      batch_size=384, 
      shuffle=True, 
      verbose=1) 

Po pierwszej epoki, to daje mi tych wyjść.

Epoch 1/200 
216632/216632 [==============================] - 2442s - loss: 0.1427 - acc: 0.9443 - val_loss: 0.0526 - val_acc: 0.9826 

Potem oceniać mojego modelu na zbiorze testowym i to też pokazuje mi dokładność około 0,98.

model1.evaluate(test_data, y = ytestenc, batch_size=384, verbose=1) 

Jednak etykiety są kodowane jeden gorący, więc muszę przewidywania wektor klas tak, że można generować nieporozumień matrycy itd Więc używam,

PREDICTED_CLASSES = model1.predict_classes(test_data, batch_size=384, verbose=1) 
temp = sum(test_labels == PREDICTED_CLASSES) 
temp/len(test_labels) 
0.83 

To pokazuje, że całkowite przewidywane zajęcia były 83% dokładne, jednak model1.evaluate pokazuje 98% celność !! Co ja tu robię źle? Czy moja funkcja straty jest w porządku z kategoriami klasowymi? Czy mój wybór funkcji aktywacji sigmoid dla warstwy predykcji jest prawidłowy? lub jest różnica w sposobie, w jaki keras ocenia model? Proszę zasugerować, co może być nie tak. To moja pierwsza próba stworzenia głębokiego modelu, więc nie mam zbyt wiele zrozumienia, co jest nie tak.

+1

użyć ' 'softmax'' i'' categorical_crossentropy'' zamiast ' 'sigmoid'' i'' binary_crossentropy''. Używając tych dwóch ostatnich, traktujesz problem jako problem wielolabelowy, a nie problem wieloklasowy. –

+0

Dziękuję za odpowiedź. Spróbuję tego i zaktualizuję odpowiednio. –

Odpowiedz

7

Znalazłem problem. metrics=['accuracy'] oblicza dokładność automatycznie z funkcji kosztu. Zatem używanie binary_crossentropy pokazuje dokładność binarną, a nie kategoryczną dokładność. Korzystanie z categorical_crossentropy automatycznie przełącza się na dokładność kategoryczną, a teraz jest to to samo, co obliczane ręcznie przy użyciu model1.predict(). Yu-Yang słusznie zwrócił uwagę na funkcję kosztów i funkcję aktywacji dla problemu wielorakiego.

P.S: Można dostać zarówno kategoryczne i dokładność binarny używając metrics=['binary_accuracy', 'categorical_accuracy']

+0

Świetne połowy (+1) - niestety musiałem ponownie odkryć i zrozumieć ten problem od zera - zobacz https://stackoverflow.com/questions/41327601/why-is-binary-crossentropy-more-accurate-than- categorical-crossentropy-for-multi/46004661 # 46004661 i https://stackoverflow.com/questions/42081257/keras-binary-crossentropy-vs-categorical-crossentropy-performance/46038271#46038271 - mimo to zaktualizowałem swoje odpowiedzi na link do Twojego... – desertnaut