日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BP人工神经网络的介绍与实现

發布時間:2025/6/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BP人工神经网络的介绍与实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

神經網絡概念與適合領域

神經網絡最早的研究是 40 年代心理學家 Mcculloch 和數學家 Pitts 合作提出的 ,他們提出的MP模型拉開了神經網絡研究的序幕。

神經網絡的發展大致經過 3 個階段:1947~1969 年為初期,在這期間科學家們提出了許多神經元模型和學習規則,如 MP 模型、HEBB 學習規則和感知器等;60 年代末期至 80 年代中期,神經網絡控制與整個神經網絡研究一樣,處于低潮。在此期間,科學家們做了大量的工作,如 Hopfield 教授對網絡引入能量函數的概念,給出了網絡的穩定性判據,提出了用于聯想記憶和優化計算的途徑。1984年,Hiton 教授提出 Bol tzman 機模型;1986年 Kumelhart 等人提出誤差反向傳播神經網絡,簡稱 BP 網絡。目前,BP網絡已成為廣泛使用的網絡。1987年至今為發展期,在此期間,神經網絡受到國際重視,各個國家都展開研究,形成神經網絡發展的另一個高潮。

人工神經網絡(ANN)受到生物學的啟發是生物神經網絡的一種模擬和近似,它從結構、實現機理和功能上模擬生物神經網絡。從系統觀點看,人工神經元網絡是由大量神經元通過極其豐富和完善的連接而構成的自適應非線性動態系統。人工神經網絡,因為生物的學習系統是由相互連接的神經元組成的異常復雜的網絡,其中每一個神經元單元有一定數量的實值輸入,并產生單一的實數值輸出。1960 年威德羅和霍夫率先把神經網絡用于自動控制研究。神經網絡以其獨特的結構和處理信息的方法,在許多實際應用領域中取得了顯著的成效,主要應用如下:自動控制領域、處理組合優化問題、模式識別、圖像處理、傳感器信號處理、機器人控制、信號處理、衛生保健、醫療、經濟、化工領 域、焊接領域、地理領域、數據挖掘、電力系統、交通、軍事、礦業、農業和氣象等領域。

神經網絡基本結構

人工神經網絡由神經元模型構成,這種由許多神經元組成的信息處理網絡具有并行分布結構。每個神經元具有單一輸出,并且能夠與其它神經元連接;存在許多(多重)輸出連接方法,每種連接方法對應一個連接權系數。可把 ANN 看成是以處理單元 PE(processing element) 為節點,用加權有向弧(鏈)相互連接而成的有向圖。令來自其它處理單元(神經元)i的信息為Xi,它們與本處理單元的互相作用強度為 Wi,i=0,1,…,n-1,處理單元的內部閾值為 θ。那么本神經元的輸入為:

而處理單元的輸出為:

式中,xi為第 i 個元素的輸入,wi 為第 i 個元素與本處理單元的互聯權重。f 稱為激發函數(activation function)或作用函數。它決定節點(神經元)的輸出。該輸出為 1 或 0 取決于其輸入之和大于或小于內部閾值 θ。

下圖所示神經元單元由多個輸入Xi,i=1,2,...,n和一個輸出y組成。中間狀態由輸入信號的權和表示,而輸出為:

訓練網絡

神經網絡結構被設計完成,有了輸入、輸出參數后,我們就要對網絡進行訓練。神經網絡的訓練有包括感知器訓練、delta 規則訓練和反向傳播算法等訓練,其中感知器訓練是基礎。

感知器和 delta 訓練規則

理解神經網絡的第一步是從對抽象生物神經開始,本文用到的人工神經網絡系統是以被稱為感知器的單元為基礎,如圖所示。感知器以一個實數值向量作為輸入,計算這些輸入的線性組合,如果結果大于某個閾值,就輸出 1,否則輸出 -1,如果 x 從 1 到 n,則感知器計算公式如下:

其中每個 wi 是一個實數常量,或叫做權值,用來決定輸入 xi 對感知器輸出的貢獻率。特別地,-w0是閾值。

盡管當訓練樣例線性可分時,感知器法則可以成功地找到一個權向量,但如果樣例不是線性可分時它將不能收斂,因此人們設計了另一個訓練法則來克服這個不足,這個訓練規則叫做 delta 規則。感知器訓練規則是基于這樣一種思路--權系數的調整是由目標和輸出的差分方程表達式決定。而 delta 規則是基于梯度降落這樣一種思路。這個復雜的數學概念可以舉個簡單的例子來表示。從給定的幾點來看,向南的那條路徑比向東那條更陡些。向東就像從懸崖上掉下來,但是向南就是沿著一個略微傾斜的斜坡下來,向西象登一座陡峭的山,而北邊則到了平地,只要慢慢的閑逛就可以了。所以您要尋找的是到達平地的所有路徑中將陡峭的總和減少到最小的路徑。在權系數的調整中,神經網絡將會找到一種將誤差減少到最小的權系數的分配方式。這部分我們不做詳細介紹,如有需要大家可參考相關的人工智能書籍。

反向傳播算法

人工神經網絡學習為學習實數值和向量值函數提供了一種實際的方法,對于連續的和離散的屬性都可以使用。并且對訓練數據中的噪聲具有很好的健壯性。反向傳播算法是最常見的網絡學習算法。這是我們所知用來訓練神經網絡很普遍的方法,反向傳播算法是一種具有很強學習能力的系統,結構比較簡單,且易于編程。

魯梅爾哈特(Rumelhart)和麥克萊蘭(Meclelland)于 1985 年發展了 BP 網絡學習算法,實現了明斯基的多層網絡設想。BP網絡不僅含有輸入節點和輸出節點,而且含有一層或多層隱(層)節點。輸入信號先向前傳遞到隱藏節點,經過作用后,再把隱藏節點的輸出信息傳遞到輸出節點,最后給出輸出結果。節點的激發函數一般選用 S 型函數。

反向傳播(back-propagation,BP)算法是一種計算單個權值變化引起網絡性能變化值的較為簡單的方法。由于BP算法過程包含從輸出節點開始,反向地向第一隱含層(即最接近輸入層的隱含層)傳播由總誤差引起的權值修正,所以稱為"反向傳播"。反向傳播特性與所求解問題的性質和所作細節選擇有極為密切的關系。

對于由一系列確定的單元互連形成的多層網絡,反向傳播算法可用來學習這個多層網絡的權值。它采用梯度下降方法試圖最小化網絡輸出值和目標值之間的誤差平方,因為我們要考慮多個輸出單元的網絡,而不是像以前只考慮單個單元,所以我們要重新計算誤差E,以便對所有網絡輸出的誤差求和:

Outpus 是網絡輸出單元的集合,tkd 和 okd 是與訓練樣例 d 和第 k 個輸出單元的相關輸出值.

反向傳播算法的一個迷人特性是:它能夠在網絡內部的隱藏層發現有用的中間表示:

1.訓練樣例僅包含網絡輸入和輸出,權值調節的過程可以自由地設置權值,來定義任何隱藏單元表示,這些隱藏單元表示在使誤差E達到最小時最有效。

2.引導反向傳播算法定義新的隱藏層特征,這些特征在輸入中沒有明確表示出來,但能捕捉輸入實例中與學習目標函數最相關的特征

反向傳播訓練神經元的算法如下:

C++簡單實現與測試

以下C++代碼實現了BP網絡,通過8個3位二進制樣本對應一個期望輸出,訓練BP網絡,最后訓練好的網絡可以將輸入的三位二進制數對應輸出一位十進制數。

//將三位二進制數轉為一位十進制數 #include <iostream> #include <cmath> using namespace std;#define innode 3 //輸入結點數 #define hidenode 10//隱含結點數 #define outnode 1 //輸出結點數 #define trainsample 8//BP訓練樣本數class BpNet { public:void train(double p[trainsample][innode ],double t[trainsample][outnode]);//Bp訓練double p[trainsample][innode]; //輸入的樣本double t[trainsample][outnode]; //樣本要輸出的double *recognize(double *p);//Bp識別void writetrain(); //寫訓練完的權值void readtrain(); //讀訓練好的權值,這使的不用每次去訓練了,只要把訓練最好的權值存下來就OK BpNet();virtual ~BpNet();public:void init();double w[innode][hidenode];//隱含結點權值double w1[hidenode][outnode];//輸出結點權值double b1[hidenode];//隱含結點閥值double b2[outnode];//輸出結點閥值double rate_w; //權值學習率(輸入層-隱含層)double rate_w1;//權值學習率 (隱含層-輸出層)double rate_b1;//隱含層閥值學習率double rate_b2;//輸出層閥值學習率double e;//誤差計算double error;//允許的最大誤差double result[outnode];// Bp輸出 };BpNet::BpNet() {error=1.0;e=0.0;rate_w=0.9; //權值學習率(輸入層--隱含層)rate_w1=0.9; //權值學習率 (隱含層--輸出層)rate_b1=0.9; //隱含層閥值學習率rate_b2=0.9; //輸出層閥值學習率 }BpNet::~BpNet() {}void winit(double w[],int n) //權值初始化 {for(int i=0;i<n;i++)w[i]=(2.0*(double)rand()/RAND_MAX)-1; }void BpNet::init() {winit((double*)w,innode*hidenode);winit((double*)w1,hidenode*outnode);winit(b1,hidenode);winit(b2,outnode); }void BpNet::train(double p[trainsample][innode],double t[trainsample][outnode]) {double pp[hidenode];//隱含結點的校正誤差double qq[outnode];//希望輸出值與實際輸出值的偏差double yd[outnode];//希望輸出值double x[innode]; //輸入向量double x1[hidenode];//隱含結點狀態值double x2[outnode];//輸出結點狀態值double o1[hidenode];//隱含層激活值double o2[hidenode];//輸出層激活值for(int isamp=0;isamp<trainsample;isamp++)//循環訓練一次樣品 {for(int i=0;i<innode;i++)x[i]=p[isamp][i]; //輸入的樣本for(int i=0;i<outnode;i++)yd[i]=t[isamp][i]; //期望輸出的樣本//構造每個樣品的輸入和輸出標準for(int j=0;j<hidenode;j++){o1[j]=0.0;for(int i=0;i<innode;i++)o1[j]=o1[j]+w[i][j]*x[i];//隱含層各單元輸入激活值x1[j]=1.0/(1+exp(-o1[j]-b1[j]));//隱含層各單元的輸出// if(o1[j]+b1[j]>0) x1[j]=1;//else x1[j]=0; }for(int k=0;k<outnode;k++){o2[k]=0.0;for(int j=0;j<hidenode;j++)o2[k]=o2[k]+w1[j][k]*x1[j]; //輸出層各單元輸入激活值x2[k]=1.0/(1.0+exp(-o2[k]-b2[k])); //輸出層各單元輸出// if(o2[k]+b2[k]>0) x2[k]=1;// else x2[k]=0; }for(int k=0;k<outnode;k++){qq[k]=(yd[k]-x2[k])*x2[k]*(1-x2[k]); //希望輸出與實際輸出的偏差for(int j=0;j<hidenode;j++)w1[j][k]+=rate_w1*qq[k]*x1[j]; //下一次的隱含層和輸出層之間的新連接權 }for(int j=0;j<hidenode;j++){pp[j]=0.0;for(int k=0;k<outnode;k++)pp[j]=pp[j]+qq[k]*w1[j][k];pp[j]=pp[j]*x1[j]*(1-x1[j]); //隱含層的校正誤差for(int i=0;i<innode;i++)w[i][j]+=rate_w*pp[j]*x[i]; //下一次的輸入層和隱含層之間的新連接權 }for(int k=0;k<outnode;k++){e+=fabs(yd[k]-x2[k])*fabs(yd[k]-x2[k]); //計算均方差 }error=e/2.0;for(int k=0;k<outnode;k++)b2[k]=b2[k]+rate_b2*qq[k]; //下一次的隱含層和輸出層之間的新閾值for(int j=0;j<hidenode;j++)b1[j]=b1[j]+rate_b1*pp[j]; //下一次的輸入層和隱含層之間的新閾值 } }double *BpNet::recognize(double *p) {double x[innode]; //輸入向量double x1[hidenode]; //隱含結點狀態值double x2[outnode]; //輸出結點狀態值double o1[hidenode]; //隱含層激活值double o2[hidenode]; //輸出層激活值for(int i=0;i<innode;i++)x[i]=p[i];for(int j=0;j<hidenode;j++){o1[j]=0.0;for(int i=0;i<innode;i++)o1[j]=o1[j]+w[i][j]*x[i]; //隱含層各單元激活值x1[j]=1.0/(1.0+exp(-o1[j]-b1[j])); //隱含層各單元輸出//if(o1[j]+b1[j]>0) x1[j]=1;// else x1[j]=0; }for(int k=0;k<outnode;k++){o2[k]=0.0;for(int j=0;j<hidenode;j++)o2[k]=o2[k]+w1[j][k]*x1[j];//輸出層各單元激活值x2[k]=1.0/(1.0+exp(-o2[k]-b2[k]));//輸出層各單元輸出//if(o2[k]+b2[k]>0) x2[k]=1;//else x2[k]=0; }for(int k=0;k<outnode;k++){result[k]=x2[k];}return result; }void BpNet::writetrain() {FILE *stream0;FILE *stream1;FILE *stream2;FILE *stream3;int i,j;//隱含結點權值寫入if(( stream0 = fopen("w.txt", "w+" ))==NULL){cout<<"創建文件失敗!";exit(1);}for(i=0;i<innode;i++){for(j=0;j<hidenode;j++){fprintf(stream0, "%f\n", w[i][j]);}}fclose(stream0);//輸出結點權值寫入if(( stream1 = fopen("w1.txt", "w+" ))==NULL){cout<<"創建文件失敗!";exit(1);}for(i=0;i<hidenode;i++){for(j=0;j<outnode;j++){fprintf(stream1, "%f\n",w1[i][j]);}}fclose(stream1);//隱含結點閥值寫入if(( stream2 = fopen("b1.txt", "w+" ))==NULL){cout<<"創建文件失敗!";exit(1);}for(i=0;i<hidenode;i++)fprintf(stream2, "%f\n",b1[i]);fclose(stream2);//輸出結點閥值寫入if(( stream3 = fopen("b2.txt", "w+" ))==NULL){cout<<"創建文件失敗!";exit(1);}for(i=0;i<outnode;i++)fprintf(stream3, "%f\n",b2[i]);fclose(stream3);}void BpNet::readtrain() {FILE *stream0;FILE *stream1;FILE *stream2;FILE *stream3;int i,j;//隱含結點權值讀出if(( stream0 = fopen("w.txt", "r" ))==NULL){cout<<"打開文件失敗!";exit(1);}float wx[innode][hidenode];for(i=0;i<innode;i++){for(j=0;j<hidenode;j++){fscanf(stream0, "%f", &wx[i][j]);w[i][j]=wx[i][j];}}fclose(stream0);//輸出結點權值讀出if(( stream1 = fopen("w1.txt", "r" ))==NULL){cout<<"打開文件失敗!";exit(1);}float wx1[hidenode][outnode];for(i=0;i<hidenode;i++){for(j=0;j<outnode;j++){fscanf(stream1, "%f", &wx1[i][j]);w1[i][j]=wx1[i][j];}}fclose(stream1);//隱含結點閥值讀出if(( stream2 = fopen("b1.txt", "r" ))==NULL){cout<<"打開文件失敗!";exit(1);}float xb1[hidenode];for(i=0;i<hidenode;i++){fscanf(stream2, "%f",&xb1[i]);b1[i]=xb1[i];}fclose(stream2);//輸出結點閥值讀出if(( stream3 = fopen("b2.txt", "r" ))==NULL){cout<<"打開文件失敗!";exit(1);}float xb2[outnode];for(i=0;i<outnode;i++){fscanf(stream3, "%f",&xb2[i]);b2[i]=xb2[i];}fclose(stream3); }//輸入樣本 double X[trainsample][innode]= {{0,0,0},{0,0,1},{0,1,0},{0,1,1},{1,0,0},{1,0,1},{1,1,0},{1,1,1}}; //期望輸出樣本 double Y[trainsample][outnode]={{0},{0.1429},{0.2857},{0.4286},{0.5714},{0.7143},{0.8571},{1.0000}};int main() {BpNet bp;bp.init();int times=0;while(bp.error>0.0001){bp.e=0.0;times++;bp.train(X,Y);cout<<"Times="<<times<<" error="<<bp.error<<endl;}cout<<"trainning complete..."<<endl;double m[innode]={1,1,1};double *r=bp.recognize(m);for(int i=0;i<outnode;++i)cout<<bp.result[i]<<" ";double cha[trainsample][outnode];double mi=100;double index;for(int i=0;i<trainsample;i++){for(int j=0;j<outnode;j++){//找差值最小的那個樣本cha[i][j]=(double)(fabs(Y[i][j]-bp.result[j]));if(cha[i][j]<mi){mi=cha[i][j];index=i;}}}for(int i=0;i<innode;++i)cout<<m[i];cout<<" is "<<index<<endl;cout<<endl;return 0; }

總結

以上是生活随笔為你收集整理的BP人工神经网络的介绍与实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久久精品人妻无码专区 | 啪啪免费视频网站 | 国产做受麻豆动漫 | 3d动漫精品啪啪一区二区下载 | 国产精品人| 亚洲精品国产精品乱码在线观看 | 国产一区免费观看 | 黄色免费播放 | 风间由美一区二区 | 97人人草| 色综合网站| 国产自在线拍 | 国产不卡a | 久久人人爽 | 成人国产视频在线观看 | 九热这里只有精品 | 美女国产精品 | 国产做受高潮漫动 | 国产v在线观看 | 国产一区二区在线免费观看视频 | 亚洲精品爱爱 | 中文字幕在线观看日韩 | 一边摸上面一边摸下面 | 日韩av一区在线观看 | 久久精品99国产精品日本 | 国产精品18 | 性生生活大片又黄又 | 欧美视频一区二区在线观看 | 国产成人午夜精华液 | 日韩精品在线观看网站 | 狠狠艹狠狠干 | 一级黄色欧美 | 精品黑人一区二区三区在线观看 | 加勒比综合在线 | 免费成人深夜夜国外 | 国产日韩欧美专区 | 91片看 | 免费在线观看污网站 | 亚洲制服丝袜诱惑 | 不卡中文一二三区 | 在线观看一区视频 | 亚洲砖区免费 | 好吊色视频在线观看 | 影音先锋中文在线 | 国产a不卡 | 国产av日韩一区二区三区精品 | 九九精品在线观看 | 久久激情片 | 制服.丝袜.亚洲.中文.综合懂色 | 六月丁香综合网 | 免费在线观看视频 | 亚洲h动漫 | 国产尻逼视频 | 一本到在线观看 | 国产精品国产三级国产专区52 | 久久久夜夜 | 8x8ⅹ成人永久免费视频 | 日本高清免费aaaaa大片视频 | 国产精品视频你懂的 | 日日日夜夜操 | 欧美激情 国产精品 | 日韩中文字幕有码 | 交专区videossex另类 | yjizz国产 | 国产激情精品 | 午夜亚洲成人 | 亚洲字幕 | 特黄aaaaaaa片免费视频 | 中文字幕福利视频 | 日韩精品一区在线视频 | 无码人妻精品中文字幕 | 亚洲av成人无码久久精品 | 岛国毛片在线观看 | 九九五月天 | 国产美女91呻吟求 | 精品人妻一区二区三区香蕉 | 人妻一区二区在线 | 国产成人传媒 | 久久久精品视频在线观看 | 日韩高清不卡在线 | 亚洲福利视频一区 | 欧美色交 | 韩日视频在线观看 | 免费一区二区三区 | 亚洲天堂一区 | 亚洲国产日韩一区无码精品久久久 | 永久av| 国产成人一区二区三区电影 | 日韩av片在线免费观看 | 久久夜色精品国产欧美乱 | 夫妻啪啪呻吟x一88av | 无码日韩人妻精品久久蜜桃 | 深爱激情站| 国产福利在线视频 | 欧美福利在线视频 | 中文字幕亚洲精品 | 91麻豆网站 | 婷婷免费视频 | sm久久捆绑调教精品一区 |