![](/img/trans.png)
[英]Discrepancy in the results of model.evaluate and model.predict in Keras
[英]How to use model.predict() to reproduce model.evaluate() output in Keras
我有一個 Keras 模型,最后一行是:
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
訓練過程結束后,我想在另一個代碼中加載評估模型。 我正在使用以下方法生成預測和基本事實:
y_predict = model.predict_generator(generator = testing_generator, steps=steps,verbose=0)
y_true = np.asarray(feature_extractor.classes, dtype='float32')
print('predicted {} samples with {} classes'.format(y_predict.shape[0],y_predict.shape[1]))
#Calculate score and error
acc = keras.metrics.binary_accuracy(y_true, y_predict)
err = keras.losses.categorical_crossentropy(tf.convert_to_tensor(y_true, np.float32), tf.convert_to_tensor(y_predict, np.float32))
sess = tf.InteractiveSession()
acc_now = np.mean(acc.eval())
err_now = np.mean(err.eval())
sess.close()
print('Acc and Err from model.predict: {},{}'.format(acc_now,err_now))
print('Model.evaluate output: {}'.format(model.evaluate_generator(generator = testing_generator, steps=steps,verbose=0)))
然后我想評估准確性、錯誤率和混淆矩陣。 我使用predict
而不是evaluate
的原因是我將能夠產生混淆矩陣。 否則,我將不得不同時使用計算成本很高的兩者。
問題是,我得到了不同的值:
來自模型預測的 Acc 和 Err:0.8237550854682922,12.75771713256836
Model.evaluate 輸出:[13.05123828162994, 0.10646823157343649]
准確率從我的方法中的 0.82 下降到模型評估輸出中的 0.1。 我是否根據需要轉換了model.predict()
輸出? 如何使用model.predict()
的結果進行模型評估?
我也關注了這個 github issue並嘗試了設置m=Model(x,x)
的解決方案。 我對y_predict
和y_true
具有相同的形狀和類型。 這種方法仍然產生:
m.evaluate 的分數:[12.757719990861846, 0.11333714980412431]
使用示例代碼:
x = Input(y_predict.shape[1:])
m = Model(x, x)
m.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
scores = m.evaluate(y_predict, y_true, batch_size=256, verbose=0)
print('Scores from m.evaluate: {}'.format(scores))
在這里,准確度很低,但仍然與evaluate()
輸出不同,錯誤與predict()
部分相同。
添加模型定義:
num_rows = data_in[-2]
num_columns = data_in[-1]
num_channels = data_in[-3]
num_labels = data_out[-1]
# Construct model
model = Sequential()
for i in range(cnn_size):
model.add(Conv2D(filters=2**(i)*16, kernel_size=kernel_size, input_shape=(num_channels, num_rows, num_columns), activation='relu'))
model.add(MaxPooling2D(pool_size=pool_size))
model.add(Dropout(dropout_rate))
model.add(GlobalAveragePooling2D())
model.add(Dense(num_labels, activation='softmax'))
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
其中data_in = (1, 40, 180)
和data_out = (1, 10)
順便說一句,我知道我可以為這些統計數據實現我自己的 numpy 解決方案,但我想使用與 Keras 相同的功能來避免實現變化。
我建議看看這篇文章。 它是用德文寫的,但是代碼中的所有注釋和隨附的說明都是英文的,所以應該沒有問題。 他有一種類似的方法,有明確的指示。 只需向下滾動到“Fehleranalysis”部分。
如果您使用帶有'softmax'
和'categorical_crossentropy'
的經典分類問題,您可能需要計算分類准確度,而不是二元准確度。
對於y_true
是單熱編碼的情況(這似乎是您的情況,因為您使用'categorical_crossentropy'
是'categorical_crossentropy'
):
keras.metrics.categorical_accuracy(y_true, y_pred)
對於y_true
是數字標簽(整數)的情況:
keras.metrics.sparse_categorical_accuracy(y_true, y_pred)
您還可以使用以下方法自行計算准確度:
trueLabels = np.argmax(y_true_numpy, axis=-1) #this line only if y_true is one-hot
predLabels = np.argmax(y_pred_numpy, axis=-1)
acc = np.mean(trueLabels == predLabels)
關於損失,我認為您正在向后看結果。 評估損失應該是13.05...
。 您計算出的損失接近於它: 12.75...
現在,如果兩種看似正確的不同方法產生相同的結果,我懷疑evaluate
給出的更大結果可能來自模型中的額外損失。 Keras 評估總結了模型中的所有損失,包括權重正則化,可能是損失權重,手動添加的損失等。
我們需要查看您的整個模型以檢測此處為何存在差異。
關於給定模型定義的損失:
它似乎沒有任何會影響損失的東西,結果應該確實是正確的。
在這種情況下,還有另外兩件事可能會導致差異:
testing_generator
和feature_extractor
工作方式可能不完全相同
yield
類型,Keras 隊列可能讓它在你第二次使用生成器時不在同一點開始evaluate
以查看結果是否完全相同
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.