您好,登錄后才能下訂單哦!
不懂keras中自定義二分類任務評價指標metrics的用法?其實想解決這個問題也不難,下面讓小編帶著大家一起學習怎么去解決,希望大家閱讀完這篇文章后大所收獲。
對于二分類任務,keras現有的評價指標只有binary_accuracy,即二分類準確率,但是評估模型的性能有時需要一些其他的評價指標,例如精確率,召回率,F1-score等等,因此需要使用keras提供的自定義評價函數功能構建出針對二分類任務的各類評價指標。
keras提供的自定義評價函數功能需要以如下兩個張量作為輸入,并返回一個張量作為輸出。
y_true:數據集真實值組成的一階張量。
y_pred:數據集輸出值組成的一階張量。
tf.round()可對張量四舍五入,因此tf.round(y_pred)即是預測值張量。
1-tf.round(y_pred)即是預測值張量取反。
1-y_true即是真實值張量取反。
tf.reduce_sum()可對張量求和。
由此可以根據定義構建出四個基礎指標TP、TN、FP、FN,然后進一步構建出進階指標precision、recall、F1score,最后在編譯階段引用上述自定義評價指標即可。
keras中自定義二分類任務常用評價指標及其引用的代碼如下
import tensorflow as tf #精確率評價指標 def metric_precision(y_true,y_pred): TP=tf.reduce_sum(y_true*tf.round(y_pred)) TN=tf.reduce_sum((1-y_true)*(1-tf.round(y_pred))) FP=tf.reduce_sum((1-y_true)*tf.round(y_pred)) FN=tf.reduce_sum(y_true*(1-tf.round(y_pred))) precision=TP/(TP+FP) return precision #召回率評價指標 def metric_recall(y_true,y_pred): TP=tf.reduce_sum(y_true*tf.round(y_pred)) TN=tf.reduce_sum((1-y_true)*(1-tf.round(y_pred))) FP=tf.reduce_sum((1-y_true)*tf.round(y_pred)) FN=tf.reduce_sum(y_true*(1-tf.round(y_pred))) recall=TP/(TP+FN) return recall #F1-score評價指標 def metric_F1score(y_true,y_pred): TP=tf.reduce_sum(y_true*tf.round(y_pred)) TN=tf.reduce_sum((1-y_true)*(1-tf.round(y_pred))) FP=tf.reduce_sum((1-y_true)*tf.round(y_pred)) FN=tf.reduce_sum(y_true*(1-tf.round(y_pred))) precision=TP/(TP+FP) recall=TP/(TP+FN) F1score=2*precision*recall/(precision+recall) return F1score #編譯階段引用自定義評價指標示例 model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy', metric_precision, metric_recall, metric_F1score])
補充知識:keras sklearn下兩分類/多分類的技術雜談(交叉驗證和評價指標)
一.前言
這篇博客是為了記錄論文補充實驗中所遇到的問題,以及解決方法,主要以程序的形式呈現。
二.對象
深度學習框架:keras
研究對象:兩分類/多分類
三.技術雜談
1.K-FOLD交叉驗證
1.概念
對一個模型進行K次訓練,每次訓練將整個數據集分為隨機的K份,K-1作為訓練集,剩余的1份作為驗證集,每次訓練結束將驗證集上的性能指標保存下來,最后對K個結果進行平均得到最終的模型性能指標。
2.優缺點
優點:模型評估更加魯棒
缺點:訓練時間加大
3.代碼
① sklearn與keras獨立使用
from sklearn.model_selection import StratifiedKFold import numpy seed = 7 # 隨機種子 numpy.random.seed(seed) # 生成固定的隨機數 num_k = 5 # 多少折 # 整個數據集(自己定義) X = Y = kfold = StratifiedKFold(n_splits=num_k, shuffle=True, random_state=seed) # 分層K折,保證類別比例一致 cvscores = [] for train, test in kfold.split(X, Y): # 可以用sequential或者function的方式建模(自己定義) model = model.compile() # 自定義 # 模型訓練 model.fit(X[train], Y[train], epochs=150, batch_size=10, verbose=0) # 模型測試 scores = model.evaluate(X[test], Y[test], verbose=0) print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100)) # 打印出驗證集準確率 cvscores.append(scores[1] * 100) print("%.2f%% (+/- %.2f%%)" % (numpy.mean(cvscores), numpy.std(cvscores))) # 輸出k-fold的模型平均和標準差結果
② sklearn與keras結合使用
from keras.wrappers.scikit_learn import KerasClassifier # 使用keras下的sklearn API from sklearn.cross_validation import StratifiedKFold, cross_val_score import numpy as np seed = 7 # 隨機種子 numpy.random.seed(seed) # 生成固定的隨機數 num_k = 5 # 多少折 # 整個數據集(自己定義) X = Y = # 創建模型 def model(): # 可以用sequential或者function的方式建模(自己定義) model = return model model = KerasClassifier(build_fn=model, epochs=150, batch_size=10) kfold = StratifiedKFold(Y, n_folds=num_k, shuffle=True, random_state=seed) results = cross_val_score(model, X, Y, cv=kfold) print(np.average(results)) # 輸出k-fold的模型平均結果
補充:引入keras的callbacks
只需要在①②中的model.fit中加入一個arg:callbacks=[keras.callbacks.ModelCheckpoint()] # 這樣可以保存下模型的權重,當然了你也可以使用callbacks.TensorBoard保存下訓練過程
2.二分類/多分類評價指標
1.概念
二分類就是說,一個目標的標簽只有兩種之一(例如:0或1,對應的one-hot標簽為[1,0]或[0,1])。對于這種問題,一般可以采用softmax或者logistic回歸來完成,分別采用cross-entropy和mse損失函數來進行網絡訓練,分別輸出概率分布和單個的sigmoid預測值(0,1)。
多分類就是說,一個目標的標簽是幾種之一(如:0,1,2…)
2.評價指標
主要包含了:準確率(accuracy),錯誤率(error rate),精確率(precision),召回率(recall)= 真陽率(TPR)= 靈敏度(sensitivity),F1-measure(包含了micro和macro兩種),假陽率(FPR),特異度(specificity),ROC(receiver operation characteristic curve)(包含了micro和macro兩種),AUC(area under curve),P-R曲線(precision-recall),混淆矩陣
① 準確率和錯誤率
accuracy = (TP+TN)/ (P+N)或者accuracy = (TP+TN)/ (T+F)
error rate = (FP+FN) / (P+N)或者(FP+FN) / (T+F)
accuracy = 1 - error rate
可見:準確率、錯誤率是對分類器在整體數據上的評價指標。
② 精確率
precision=TP /(TP+FP)
可見:精確率是對分類器在預測為陽性的數據上的評價指標。
③ 召回率/真陽率/靈敏度
recall = TPR = sensitivity = TP/(TP+FN)
可見:召回率/真陽率/靈敏度是對分類器在整個陽性數據上的評價指標。
④ F1-measure
F1-measure = 2 * (recall * precision / (recall + precision))
包含兩種:micro和macro(對于多類別分類問題,注意區別于多標簽分類問題)
1)micro
計算出所有類別總的precision和recall,然后計算F1-measure
2)macro
計算出每一個類的precison和recall后計算F1-measure,最后將F1-measure平均
可見:F1-measure是對兩個矛盾指標precision和recall的一種調和。
⑤ 假陽率
FPR=FP / (FP+TN)
可見:假陽率是對分類器在整個陰性數據上的評價指標,針對的是假陽。
⑥ 特異度
specificity = 1- FPR
可見:特異度是對分類器在整個陰性數據上的評價指標,針對的是真陰。
⑦ ROC曲線和AUC
作用:靈敏度與特異度的綜合指標
橫坐標:FPR/1-specificity
縱坐標:TPR/sensitivity/recall
AUC是ROC右下角的面積,越大,表示分類器的性能越好
包含兩種:micro和macro(對于多類別分類問題,注意區別于多標簽分類問題)
假設一共有M個樣本,N個類別。預測出來的概率矩陣P(M,N),標簽矩陣L (M,N)
1)micro
根據P和L中的每一列(對整個數據集而言),計算出各閾值下的TPR和FPR,總共可以得到N組數據,分別畫出N個ROC曲線,最后取平均
2)macro
將P和L按行展開,然后轉置為兩列,最后畫出一個ROC曲線
⑧ P-R曲線
橫軸:recall
縱軸:precision
評判:1)直觀看,P-R包圍的面積越大越好,P=R的點越大越好;2)通過F1-measure來看
比較ROC和P-R: 當樣本中的正、負比例不平衡的時候,ROC曲線基本保持不變,而P-R曲線變化很大,原因如下:
當負樣本的比例增大時,在召回率一定的情況下,那么表現較差的模型必然會召回更多的負樣本,TP降低,FP迅速增加(對于性能差的分類器而言),precision就會降低,所以P-R曲線包圍的面積會變小。
⑨ 混淆矩陣
行表示的是樣本中的一種真類別被預測的結果,列表示的是一種被預測的標簽所對應的真類別。
3.代碼
注意:以下的代碼是合在一起寫的,有注釋。
from sklearn import datasets import numpy as np from sklearn.preprocessing import label_binarize from sklearn.linear_model import LogisticRegression from sklearn.metrics import confusion_matrix, precision_score, accuracy_score,recall_score, f1_score,roc_auc_score, precision_recall_fscore_support, roc_curve, classification_report import matplotlib.pyplot as plt iris = datasets.load_iris() x, y = iris.data, iris.target print("label:", y) n_class = len(set(iris.target)) y_one_hot = label_binarize(y, np.arange(n_class)) # alpha = np.logspace(-2, 2, 20) #設置超參數范圍 # model = LogisticRegressionCV(Cs = alpha, cv = 3, penalty = 'l2') #使用L2正則化 model = LogisticRegression() # 內置了最大迭代次數了,可修改 model.fit(x, y) y_score = model.predict(x) # 輸出的是整數標簽 mean_accuracy = model.score(x, y) print("mean_accuracy: ", mean_accuracy) print("predict label:", y_score) print(y_score==y) print(y_score.shape) y_score_pro = model.predict_proba(x) # 輸出概率 print(y_score_pro) print(y_score_pro.shape) y_score_one_hot = label_binarize(y_score, np.arange(n_class)) # 這個函數的輸入必須是整數的標簽哦 print(y_score_one_hot.shape) obj1 = confusion_matrix(y, y_score) # 注意輸入必須是整數型的,shape=(n_samples, ) print('confusion_matrix\n', obj1) print(y) print('accuracy:{}'.format(accuracy_score(y, y_score))) # 不存在average print('precision:{}'.format(precision_score(y, y_score,average='micro'))) print('recall:{}'.format(recall_score(y, y_score,average='micro'))) print('f1-score:{}'.format(f1_score(y, y_score,average='micro'))) print('f1-score-for-each-class:{}'.format(precision_recall_fscore_support(y, y_score))) # for macro # print('AUC y_pred = one-hot:{}\n'.format(roc_auc_score(y_one_hot, y_score_one_hot,average='micro'))) # 對于multi-class輸入必須是proba,所以這種是錯誤的 # AUC值 auc = roc_auc_score(y_one_hot, y_score_pro,average='micro') # 使用micro,會計算n_classes個roc曲線,再取平均 print("AUC y_pred = proba:", auc) # 畫ROC曲線 print("one-hot label ravelled shape:", y_one_hot.ravel().shape) fpr, tpr, thresholds = roc_curve(y_one_hot.ravel(),y_score_pro.ravel()) # ravel()表示平鋪開來,因為輸入的shape必須是(n_samples,) print("threshold: ", thresholds) plt.plot(fpr, tpr, linewidth = 2,label='AUC=%.3f' % auc) plt.plot([0,1],[0,1], 'k--') # 畫一條y=x的直線,線條的顏色和類型 plt.axis([0,1.0,0,1.0]) # 限制坐標范圍 plt.xlabel('False Postivie Rate') plt.ylabel('True Positive Rate') plt.legend() plt.show() # p-r曲線針對的是二分類,這里就不描述了 ans = classification_report(y, y_score,digits=5) # 小數點后保留5位有效數字 print(ans)
感謝你能夠認真閱讀完這篇文章,希望小編分享關于keras中自定義二分類任務評價指標metrics的用法內容對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,遇到問題就找億速云,詳細的解決方法等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。