Python機器學習應用之基于BP神經(jīng)網(wǎng)絡的預測篇詳解
一、Introduction
1 BP神經(jīng)網(wǎng)絡的優(yōu)點
- 非線性映射能力:BP神經(jīng)網(wǎng)絡實質(zhì)上實現(xiàn)了一個從輸入到輸出的映射功能,數(shù)學理論證明三層的神經(jīng)網(wǎng)絡就能夠以任意精度逼近任何非線性連續(xù)函數(shù)。這使得其特別適合于求解內(nèi)部機制復雜的問題,即BP神經(jīng)網(wǎng)絡具有較強的非線性映射能力。
- 自學習和自適應能力:BP神經(jīng)網(wǎng)絡在訓練時,能夠通過學習自動提取輸入、輸出數(shù)據(jù)間的“合理規(guī)則”,并自適應地將學習內(nèi)容記憶于網(wǎng)絡的權值中。即BP神經(jīng)網(wǎng)絡具有高度自學習和自適應的能力。
- 泛化能力:所謂泛化能力是指在設計模式分類器時,即要考慮網(wǎng)絡在保證對所需分類對象進行正確分類,還要關心網(wǎng)絡在經(jīng)過訓練后,能否對未見過的模式或有噪聲污染的模式,進行正確的分類。也即BP神經(jīng)網(wǎng)絡具有將學習成果應用于新知識的能力。
2 BP神經(jīng)網(wǎng)絡的缺點
- 局部極小化問題:從數(shù)學角度看,傳統(tǒng)的 BP神經(jīng)網(wǎng)絡為一種局部搜索的優(yōu)化方法,它要解決的是一個復雜非線性化問題,網(wǎng)絡的權值是通過沿局部改善的方向逐漸進行調(diào)整的,這樣會使算法陷入局部極值,權值收斂到局部極小點,從而導致網(wǎng)絡訓練失敗。加上BP神經(jīng)網(wǎng)絡對初始網(wǎng)絡權重非常敏感,以不同的權重初始化網(wǎng)絡,其往往會收斂于不同的局部極小,這也是每次訓練得到不同結果的根本原因
- BP 神經(jīng)網(wǎng)絡算法的收斂速度慢:由于BP神經(jīng)網(wǎng)絡算法本質(zhì)上為梯度下降法,它所要優(yōu)化的目標函數(shù)是非常復雜的,因此,必然會出現(xiàn)“鋸齒形現(xiàn)象”,這使得BP算法低效;又由于優(yōu)化的目標函數(shù)很復雜,它必然會在神經(jīng)元輸出接近0或1的情況下,出現(xiàn)一些平坦區(qū),在這些區(qū)域內(nèi),權值誤差改變很小,使訓練過程幾乎停頓;BP神經(jīng)網(wǎng)絡模型中,為了使網(wǎng)絡執(zhí)行BP算法,不能使用傳統(tǒng)的一維搜索法求每次迭代的步長,而必須把步長的更新規(guī)則預先賦予網(wǎng)絡,這種方法也會引起算法低效。以上種種,導致了BP神經(jīng)網(wǎng)絡算法收斂速度慢的現(xiàn)象。
- BP 神經(jīng)網(wǎng)絡結構選擇不一:BP神經(jīng)網(wǎng)絡結構的選擇至今尚無一種統(tǒng)一而完整的理論指導,一般只能由經(jīng)驗選定。網(wǎng)絡結構選擇過大,訓練中效率不高,可能出現(xiàn)過擬合現(xiàn)象,造成網(wǎng)絡性能低,容錯性下降,若選擇過小,則又會造成網(wǎng)絡可能不收斂。而網(wǎng)絡的結構直接影響網(wǎng)絡的逼近能力及推廣性質(zhì)。因此,應用中如何選擇合適的網(wǎng)絡結構是一個重要的問題。
二、實現(xiàn)過程
1 Demo
#%% 基礎數(shù)組運算庫導入 import numpy as np # 畫圖庫導入 import matplotlib.pyplot as plt # 導入三維顯示工具 from mpl_toolkits.mplot3d import Axes3D # 導入BP模型 from sklearn.neural_network import MLPClassifier # 導入demo數(shù)據(jù)制作方法 from sklearn.datasets import make_classification from sklearn.metrics import classification_report, confusion_matrix import seaborn as sns import warnings from sklearn.exceptions import ConvergenceWarning #%%模型訓練 # 制作五個類別的數(shù)據(jù),每個類別1000個樣本 train_samples, train_labels = make_classification(n_samples=1000, n_features=3, n_redundant=0,n_classes=5, n_informative=3, n_clusters_per_class=1,class_sep=3, random_state=10) # 將五個類別的數(shù)據(jù)進行三維顯示 fig = plt.figure() ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=20, azim=20) ax.scatter(train_samples[:, 0], train_samples[:, 1], train_samples[:, 2], marker='o', c=train_labels) plt.title('Demo Data Map')
#%% 建立 BP 模型, 采用sgd優(yōu)化器,relu非線性映射函數(shù) BP = MLPClassifier(solver='sgd',activation = 'relu',max_iter = 500,alpha = 1e-3, hidden_layer_sizes = (32,32),random_state = 1) # 進行模型訓練 with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=ConvergenceWarning, module="sklearn") BP.fit(train_samples, train_labels) # 查看 BP 模型的參數(shù) print(BP) #%% 進行模型預測 predict_labels = BP.predict(train_samples) # 顯示預測的散點圖 fig = plt.figure() ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=20, azim=20) ax.scatter(train_samples[:, 0], train_samples[:, 1], train_samples[:, 2], marker='o', c=predict_labels) plt.title('Demo Data Predict Map with BP Model') # 顯示預測分數(shù) print("預測準確率: {:.4f}".format(BP.score(train_samples, train_labels))) # 可視化預測數(shù)據(jù) print("真實類別:", train_labels[:10]) print("預測類別:", predict_labels[:10]) # 準確率等報表 print(classification_report(train_labels, predict_labels)) # 計算混淆矩陣 classes = [0, 1, 2, 3] cofusion_mat = confusion_matrix(train_labels, predict_labels, classes) sns.set() figur, ax = plt.subplots() # 畫熱力圖 sns.heatmap(cofusion_mat, cmap="YlGnBu_r", annot=True, ax=ax) ax.set_title('confusion matrix') # 標題 ax.set_xticklabels([''] + classes, minor=True) ax.set_yticklabels([''] + classes, minor=True) ax.set_xlabel('predict') # x軸 ax.set_ylabel('true') # y軸 plt.show()
#%%# 進行新的測試數(shù)據(jù)測試 test_sample = np.array([[-1, 0.1, 0.1]]) print(f"{test_sample} 類別是: ", BP.predict(test_sample)) print(f"{test_sample} 類別概率分別是: ", BP.predict_proba(test_sample)) test_sample = np.array([[-1.2, 10, -91]]) print(f"{test_sample} 類別是: ", BP.predict(test_sample)) print(f"{test_sample} 類別概率分別是: ", BP.predict_proba(test_sample)) test_sample = np.array([[-12, -0.1, -0.1]]) print(f"{test_sample} 類別是: ", BP.predict(test_sample)) print(f"{test_sample} 類別概率分別是: ", BP.predict_proba(test_sample)) test_sample = np.array([[100, -90.1, -9.1]]) print(f"{test_sample} 類別是: ", BP.predict(test_sample)) print(f"{test_sample} 類別概率分別是: ", BP.predict_proba(test_sample))
2 基于BP神經(jīng)網(wǎng)絡的乳腺癌分類預測
#%%基于BP神經(jīng)網(wǎng)絡的乳腺癌分類 #基本庫導入 # 導入乳腺癌數(shù)據(jù)集 from sklearn.datasets import load_breast_cancer # 導入BP模型 from sklearn.neural_network import MLPClassifier # 導入訓練集分割方法 from sklearn.model_selection import train_test_split # 導入預測指標計算函數(shù)和混淆矩陣計算函數(shù) from sklearn.metrics import classification_report, confusion_matrix # 導入繪圖包 import seaborn as sns import matplotlib.pyplot as plt # 導入三維顯示工具 from mpl_toolkits.mplot3d import Axes3D # 導入乳腺癌數(shù)據(jù)集 cancer = load_breast_cancer() # 查看數(shù)據(jù)集信息 print('breast_cancer數(shù)據(jù)集的長度為:',len(cancer)) print('breast_cancer數(shù)據(jù)集的類型為:',type(cancer)) # 分割數(shù)據(jù)為訓練集和測試集 cancer_data = cancer['data'] print('cancer_data數(shù)據(jù)維度為:',cancer_data.shape) cancer_target = cancer['target'] print('cancer_target標簽維度為:',cancer_target.shape) cancer_names = cancer['feature_names'] cancer_desc = cancer['DESCR'] #分為訓練集與測試集 cancer_data_train,cancer_data_test = train_test_split(cancer_data,test_size=0.2,random_state=42)#訓練集 cancer_target_train,cancer_target_test = train_test_split(cancer_target,test_size=0.2,random_state=42)#測試集
#%%# 建立 BP 模型, 采用Adam優(yōu)化器,relu非線性映射函數(shù) BP = MLPClassifier(solver='adam',activation = 'relu',max_iter = 1000,alpha = 1e-3,hidden_layer_sizes = (64,32, 32),random_state = 1) # 進行模型訓練 BP.fit(cancer_data_train, cancer_target_train) #%% 進行模型預測 predict_train_labels = BP.predict(cancer_data_train) # 可視化真實數(shù)據(jù) fig = plt.figure() ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=20, azim=20) ax.scatter(cancer_data_train[:, 0], cancer_data_train[:, 1], cancer_data_train[:, 2], marker='o', c=cancer_target_train) plt.title('True Label Map') plt.show() # 可視化預測數(shù)據(jù) fig = plt.figure() ax = Axes3D(fig, rect=[0, 0, 1, 1], elev=20, azim=20) ax.scatter(cancer_data_train[:, 0], cancer_data_train[:, 1], cancer_data_train[:, 2], marker='o', c=predict_train_labels) plt.title('Cancer with BP Model') plt.show()
#%% 顯示預測分數(shù) print("預測準確率: {:.4f}".format(BP.score(cancer_data_test, cancer_target_test))) # 進行測試集數(shù)據(jù)的類別預測 predict_test_labels = BP.predict(cancer_data_test) print("測試集的真實標簽:\n", cancer_target_test) print("測試集的預測標簽:\n", predict_test_labels) #%% 進行預測結果指標統(tǒng)計 統(tǒng)計每一類別的預測準確率、召回率、F1分數(shù) print(classification_report(cancer_target_test, predict_test_labels))
#%% 計算混淆矩陣 confusion_mat = confusion_matrix(cancer_target_test, predict_test_labels) # 打印混淆矩陣 print(confusion_mat) # 將混淆矩陣以熱力圖的方式顯示 sns.set() figure, ax = plt.subplots() # 畫熱力圖 sns.heatmap(confusion_mat, cmap="YlGnBu_r", annot=True, ax=ax) # 標題 ax.set_title('confusion matrix') # x軸為預測類別 ax.set_xlabel('predict') # y軸實際類別 ax.set_ylabel('true') plt.show()
注:之前還做過基于BP神經(jīng)網(wǎng)絡的人口普查數(shù)據(jù)預測,有需要的猿友私信
三、Keys
BP神經(jīng)網(wǎng)絡的要點在于前向傳播和誤差反向傳播,來對參數(shù)進行更新,使得損失最小化。
它是一個迭代算法,基本思想是:
- 先計算每一層的狀態(tài)和激活值,直到最后一層(即信號是前向傳播的);
- 計算每一層的誤差,誤差的計算過程是從最后一層向前推進的(反向傳播);
- 更新參數(shù)(目標是誤差變?。?。迭代前面兩個步驟,直到滿足停止準則(比如相鄰兩次迭代的誤差的差別很小)。
886~~~
到此這篇關于Python機器學習應用之基于BP神經(jīng)網(wǎng)絡的預測篇詳解的文章就介紹到這了,更多相關Python BP神經(jīng)網(wǎng)絡內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
python 實現(xiàn)德洛內(nèi)三角剖分的操作
這篇文章主要介紹了python 實現(xiàn)德洛內(nèi)三角剖分的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04利用PyInstaller將python程序.py轉(zhuǎn)為.exe的方法詳解
這篇文章主要給大家介紹了利用PyInstaller將python程序.py轉(zhuǎn)為.exe的方法,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。2017-05-05關于Torch?torchvision?Python版本對應關系說明
這篇文章主要介紹了關于Torch?torchvision?Python版本對應關系說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05