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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

BP神经网络-- C语言实现

發(fā)布時(shí)間:2025/6/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BP神经网络-- C语言实现 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.


? ? ? 在上一篇文章中,介紹了BP神經(jīng)網(wǎng)絡(luò)的基本模型、模型中的一些術(shù)語(yǔ)并對(duì)模型進(jìn)行了數(shù)學(xué)上的分析,對(duì)它的原理有了初步的認(rèn)識(shí)。那么如何用程序語(yǔ)言來(lái)具體的實(shí)現(xiàn)它,將是我們下一步需要討論的問(wèn)題。本文選取的是C語(yǔ)言來(lái)實(shí)現(xiàn)一個(gè)簡(jiǎn)單的單隱藏層的BP神經(jīng)網(wǎng)絡(luò)(默認(rèn)大家了解了BP神經(jīng)網(wǎng)絡(luò)的基本概念,本文中涉及到些術(shù)語(yǔ)參見上一篇 ?基本模型?),因此對(duì)于其他C類語(yǔ)言(C#、JAVA等)只需對(duì)本文中的代碼稍作修改即可移植。

?

一些數(shù)據(jù)的定義

?? 首先,我們介紹些下文中描述的程序里面的一些重要數(shù)據(jù)的定義。

#define Data 820 #define In 2 #define Out 1 #define Neuron 45 #define TrainC 5500

? ? ? Data 用來(lái)表示已經(jīng)知道的數(shù)據(jù)樣本的數(shù)量,也就是訓(xùn)練樣本的數(shù)量。In 表示對(duì)于每個(gè)樣本有多少個(gè)輸入變量; Out 表示對(duì)于每個(gè)樣本有多少個(gè)輸出變量。Neuron 表示神經(jīng)元的數(shù)量,TrainC 來(lái)表示訓(xùn)練的次數(shù)。再來(lái)我們看對(duì)神經(jīng)網(wǎng)絡(luò)描述的數(shù)據(jù)定義,來(lái)看下面這張圖里面的數(shù)據(jù)類型都是 double 型。

?

圖1

? ? ? d_in[Data][In] 存儲(chǔ) Data 個(gè)樣本,每個(gè)樣本的 In 個(gè)輸入。d_out[Data][Out] 存儲(chǔ) Data 個(gè)樣本,每個(gè)樣本的 Out 個(gè)輸出。我們用鄰接表法來(lái)表示 圖1 中的網(wǎng)絡(luò),w[Neuron][In] ?表示某個(gè)輸入對(duì)某個(gè)神經(jīng)元的權(quán)重,v[Out][Neuron] 來(lái)表示某個(gè)神經(jīng)元對(duì)某個(gè)輸出的權(quán)重;與之對(duì)應(yīng)的保存它們兩個(gè)修正量的數(shù)組 dw[Neuron][In] 和 dv[Out][Neuron]。數(shù)組 o[Neuron] 記錄的是神經(jīng)元通過(guò)激活函數(shù)對(duì)外的輸出,OutputData[Out] ?存儲(chǔ)BP神經(jīng)網(wǎng)絡(luò)的輸出。

?

程序的執(zhí)行過(guò)程

???????? 在這里,先不考慮具體函數(shù)的執(zhí)行細(xì)節(jié),從大體上來(lái)介紹程序的執(zhí)行過(guò)程。用偽代碼來(lái)表示,具體的內(nèi)容后面一步步介紹,如下:

主函數(shù)main{讀取樣本數(shù)據(jù) readData();初始化BP神經(jīng)網(wǎng)絡(luò) initBPNework(){包括數(shù)據(jù)的歸一,神經(jīng)元的初始化 w[Neuron][In]、v[Out][Neuron]等;}BP神經(jīng)網(wǎng)絡(luò)訓(xùn)練 trainNetwork(){do{for(i 小于 樣本容量 Data){計(jì)算按照第 i 個(gè)樣本輸入,產(chǎn)生的BP神經(jīng)網(wǎng)絡(luò)的輸出 computO(i);累記誤差精度;反饋調(diào)節(jié)BP神經(jīng)網(wǎng)絡(luò)中的神經(jīng)元,完成第 i 個(gè)樣本的學(xué)習(xí) backUpdate(i);}}while(達(dá)到訓(xùn)練次數(shù) 或者 符合誤差精度);}存儲(chǔ)訓(xùn)練好的神經(jīng)元信息 writeNeuron();用一些數(shù)據(jù)來(lái)測(cè)試,訓(xùn)練出來(lái)的BP神經(jīng)網(wǎng)絡(luò)的結(jié)果;return 0; }

? ? ? ?以上是處理的流程,對(duì)于讀取數(shù)據(jù)、保存數(shù)據(jù)之類的處理本文將略去這方面內(nèi)容,突出主干部分。

?

初始化BP神經(jīng)網(wǎng)絡(luò)

? ? ? 初始化主要是涉及兩個(gè)方面的功能,一方面是對(duì)讀取的訓(xùn)練樣本數(shù)據(jù)進(jìn)行歸一化處理,歸一化處理就是指的就是將數(shù)據(jù)轉(zhuǎn)換成0~1之間。在BP神經(jīng)網(wǎng)絡(luò)理論里面,并沒(méi)有對(duì)這個(gè)進(jìn)行要求,不過(guò)實(shí)際實(shí)踐過(guò)程中,歸一化處理是不可或缺的。因?yàn)槔碚撃P蜎](méi)考慮到,BP神經(jīng)網(wǎng)絡(luò)收斂的速率問(wèn)題,一般來(lái)說(shuō)神經(jīng)元的輸出對(duì)于0~1之間的數(shù)據(jù)非常敏感,歸一化能夠顯著提高訓(xùn)練效率。可以用以下公式來(lái)對(duì)其進(jìn)行歸一化,其中 加個(gè)常數(shù)A 是為了防止出現(xiàn) 0 的情況(0不能為分母)。

? ? ? ?y=(x-MinValue+A)/(MaxValue-MinValue+A)

? ? ? 另一方面,就是對(duì)神經(jīng)元的權(quán)重進(jìn)行初始化了,數(shù)據(jù)歸一到了(0~1)之間,那么權(quán)重初始化為(-1~1)之間的數(shù)據(jù),另外對(duì)修正量賦值為0。實(shí)現(xiàn)參考代碼如下:

void initBPNework(){int i,j;/*找到數(shù)據(jù)最小、最大值*/for(i=0; i<In; i++){Minin[i]=Maxin[i]=d_in[0][i];for(j=0; j<Data; j++){Maxin[i]=Maxin[i]>d_in[j][i]?Maxin[i]:d_in[j][i];Minin[i]=Minin[i]<d_in[j][i]?Minin[i]:d_in[j][i];}}for(i=0; i<Out; i++){Minout[i]=Maxout[i]=d_out[0][i];for(j=0; j<Data; j++){Maxout[i]=Maxout[i]>d_out[j][i]?Maxout[i]:d_out[j][i];Minout[i]=Minout[i]<d_out[j][i]?Minout[i]:d_out[j][i];}}/*歸一化處理*/for (i = 0; i < In; i++)for(j = 0; j < Data; j++)d_in[j][i]=(d_in[j][i]-Minin[i]+1)/(Maxin[i]-Minin[i]+1);for (i = 0; i < Out; i++)for(j = 0; j < Data; j++)d_out[j][i]=(d_out[j][i]-Minout[i]+1)/(Maxout[i]-Minout[i]+1);/*初始化神經(jīng)元*/for (i = 0; i < Neuron; ++i) for (j = 0; j < In; ++j){ w[i][j]=(rand()*2.0/RAND_MAX-1)/2;dw[i][j]=0;}for (i = 0; i < Neuron; ++i) for (j = 0; j < Out; ++j){v[j][i]=(rand()*2.0/RAND_MAX-1)/2;dv[j][i]=0;} }

?

BP神經(jīng)網(wǎng)絡(luò)訓(xùn)練

? ? ? 這部分應(yīng)當(dāng)說(shuō)是整個(gè)BP神經(jīng)網(wǎng)絡(luò)形成的引擎,驅(qū)動(dòng)著樣本訓(xùn)練過(guò)程的執(zhí)行。由BP神經(jīng)網(wǎng)絡(luò)的基本模型知道,反饋學(xué)習(xí)機(jī)制包括兩大部分,一是BP神經(jīng)網(wǎng)絡(luò)產(chǎn)生預(yù)測(cè)的結(jié)果,二是通過(guò)預(yù)測(cè)的結(jié)果和樣本的準(zhǔn)確結(jié)果進(jìn)行比對(duì),然后對(duì)神經(jīng)元進(jìn)行誤差量的修正。因此,我們用兩個(gè)函數(shù)來(lái)表示這樣的兩個(gè)過(guò)程,訓(xùn)練過(guò)程中還對(duì)平均誤差 e 進(jìn)行監(jiān)控,如果達(dá)到了設(shè)定的精度即可完成訓(xùn)練。由于不一定能夠到達(dá)預(yù)期設(shè)定的精度要求,我們添加一個(gè)訓(xùn)練次數(shù)的參數(shù),如果次數(shù)達(dá)到也退出訓(xùn)練。實(shí)現(xiàn)參考代碼如下:

?

void trainNetwork(){int i,c=0;do{e=0;for (i = 0; i < Data; ++i){computO(i);e+=fabs((OutputData[0]-d_out[i][0])/d_out[i][0]);backUpdate(i);}//printf("%d %lf\n",c,e/Data);c++;}while(c<TrainC && e/Data>0.01); }

?

??????? 其中的函數(shù),computO(i) (O是output縮寫)計(jì)算BP神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)第 i 個(gè)樣本的輸出也就是第一個(gè)過(guò)程。backUpdate(i) 是根據(jù)預(yù)測(cè)的第 i 個(gè)樣本輸出對(duì)神經(jīng)網(wǎng)絡(luò)的權(quán)重進(jìn)行更新,e用來(lái)監(jiān)控誤差。

   ?到這里,我們整體回顧來(lái)看,BP神經(jīng)網(wǎng)絡(luò)程序?qū)崿F(xiàn)的骨架已經(jīng)介紹完了,訓(xùn)練過(guò)程中核心的兩個(gè)函數(shù)computO(i) 和 backUpdate(i) 的實(shí)現(xiàn)在下一篇再來(lái)分析,晚安。



C語(yǔ)言實(shí)現(xiàn)上?中介紹了程序?qū)崿F(xiàn)時(shí)定義的一些數(shù)據(jù)結(jié)構(gòu)、程序執(zhí)行的流程以及 程序的基本骨架(詳情見 C語(yǔ)言實(shí)現(xiàn)上)。留下了兩個(gè)關(guān)鍵函數(shù)computO(i) 和 backUpdate(i) 沒(méi)有分析實(shí)現(xiàn),參數(shù) i 代表的是第 i 個(gè)樣本,本篇我們一起來(lái)分析下這兩個(gè)函數(shù)的實(shí)現(xiàn)。

BP神經(jīng)網(wǎng)絡(luò)輸出

? ? ? 函數(shù) computO(i) 負(fù)責(zé)的是通過(guò)BP神經(jīng)網(wǎng)絡(luò)的機(jī)制對(duì)樣本 i 的輸入,預(yù)測(cè)其輸出。回想BP神經(jīng)網(wǎng)絡(luò)的基本模型(詳情見 基本模型)對(duì)應(yīng)的公式(1)還有 激活函數(shù)對(duì)應(yīng)的公式(2):

? ??

??????

? ? ? 在前篇設(shè)計(jì)的BP神經(jīng)網(wǎng)絡(luò)中,輸入層與隱藏層權(quán)重對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)是w[Neuron][In],隱藏層與輸出層權(quán)重對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)是v[Out][Neuron],并且數(shù)組 o[Neuron] 記錄的是神經(jīng)元通過(guò)激活函數(shù)對(duì)外的輸出,BP神經(jīng)網(wǎng)絡(luò)預(yù)測(cè)的樣本結(jié)果保存在OutputData[Out]中。由此,就可以得到以下實(shí)現(xiàn)的參考代碼:

void computO(int var){int i,j;double sum,y;/*神經(jīng)元輸出*/for (i = 0; i < Neuron; ++i){sum=0;for (j = 0; j < In; ++j)sum+=w[i][j]*d_in[var][j];o[i]=1/(1+exp(-1*sum));}/* 隱藏層到輸出層輸出 */for (i = 0; i < Out; ++i){sum=0;for (j = 0; j < Neuron; ++j)sum+=v[i][j]*o[j];OutputData[i]=sum;} }

?

BP神經(jīng)網(wǎng)絡(luò)的反饋學(xué)習(xí)

???????? 函數(shù) backUpdate(i) 負(fù)責(zé)的是將預(yù)測(cè)輸出的結(jié)果與樣本真實(shí)的結(jié)果進(jìn)行比對(duì),然后對(duì)神經(jīng)網(wǎng)絡(luò)中涉及到的權(quán)重進(jìn)行修正,也這是BP神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)的關(guān)鍵所在。如何求到對(duì)于 w[Neuron][In] 和 v[Out][Neuron] 進(jìn)行修正的誤差量便是關(guān)鍵所在!誤差修正量的求法在基本模型一文中數(shù)學(xué)分析部分有解答,具體問(wèn)題具體分析,落實(shí)到我們?cè)O(shè)計(jì)的這個(gè)BP神經(jīng)網(wǎng)絡(luò)上來(lái)說(shuō),需要得到的是對(duì)w[Neuron][In] 和 v[Out][Neuron] 兩個(gè)數(shù)據(jù)進(jìn)行修正誤差,誤差量用數(shù)據(jù)結(jié)構(gòu) dw[Neuron][In] ?和 ?dv[Out][Neuron]? 來(lái)進(jìn)行存儲(chǔ)。那么來(lái)分析下這兩個(gè)修正誤差量是什么樣的?推導(dǎo)的思路與基本模型中推導(dǎo)誤差量的一致,這里僅列出對(duì)具體對(duì)于我們?cè)O(shè)計(jì)的BP神經(jīng)網(wǎng)絡(luò)中的數(shù)學(xué)推導(dǎo)過(guò)程:

???

? ? ? 如果你不想知道推導(dǎo)過(guò)程,那么只需要看上面中的兩個(gè) 所以(有三個(gè)點(diǎn)的地方) 的內(nèi)容,就可以知道所需要的誤差量是什么樣的了;如果想要想弄明白的話,或許需要自己在稿子上畫畫看推導(dǎo)推導(dǎo)。到這里完成了數(shù)學(xué)推導(dǎo),實(shí)現(xiàn)的代碼就很容易寫了。在具體實(shí)現(xiàn)對(duì)誤差修改中,我們?cè)偌由蠈W(xué)習(xí)率,并且對(duì)先前學(xué)習(xí)到的修正誤差量進(jìn)行繼承,直白的說(shuō)就是都乘上一個(gè)0到1之間的數(shù),具體的見如下實(shí)現(xiàn)參考代碼:

#define A 0.2 #define B 0.4 #define a 0.2 #define b 0.3 void backUpdate(int var) {int i,j;double t;for (i = 0; i < Neuron; ++i){t=0;for (j = 0; j < Out; ++j){t+=(OutputData[j]-d_out[var][j])*v[j][i];dv[j][i]=A*dv[j][i]+B*(OutputData[j]-d_out[var][j])*o[i];v[j][i]-=dv[j][i];}for (j = 0; j < In; ++j){dw[i][j]=a*dw[i][j]+b*t*o[i]*(1-o[i])*d_in[var][j];w[i][j]-=dw[i][j];}} }

  

? ? ? ?好了,至此BP神經(jīng)網(wǎng)絡(luò)的C語(yǔ)言實(shí)現(xiàn)就全部完成了。最后,我們可以測(cè)試下BP神經(jīng)網(wǎng)絡(luò)的運(yùn)行。我這里是這樣給出數(shù)據(jù)的,兩個(gè)輸入a、b(10以內(nèi)的數(shù)),一個(gè)輸出 c,c=a+b。換句話說(shuō)就是教BP神經(jīng)網(wǎng)絡(luò)加法運(yùn)算。在 45個(gè)神經(jīng)元,820個(gè)訓(xùn)練樣例,樣本平均誤差小于0.01時(shí)完成訓(xùn)練(學(xué)習(xí)率等見參考代碼)的條件下,最后預(yù)測(cè) (6,8),(2.1,7),(4.3,8)實(shí)際輸出結(jié)果如下:

   ? ?最后附上參考實(shí)現(xiàn)代碼,以及實(shí)驗(yàn)訓(xùn)練時(shí)的數(shù)據(jù)、和神經(jīng)元信息。(本示例 僅為BP神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)的 簡(jiǎn)單DEMO,若實(shí)際使用還需多加考慮!!!)

  參考代碼下載


總結(jié)

以上是生活随笔為你收集整理的BP神经网络-- C语言实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日本精品一区二区视频 | 日韩欧美亚洲精品 | 色婷婷丁香 | 日本成人片在线 | 一区二区三区免费在线观看 | 日韩在线精品视频一区二区涩爱 | 国产日韩欧美中文字幕 | 香港三级日本三级韩国三级 | 无码日本精品xxxxxxxxx | 污站在线观看 | 国产特黄 | 污污网站在线免费观看 | 无码人妻aⅴ一区二区三区有奶水 | www成人免费视频 | 亚洲AV无码阿娇国产精品 | 日韩av在线播放一区 | 色秀视频在线观看 | 超碰95在线| 97免费观看视频 | 久久六 | 国产精品美女毛片真酒店 | www.av欧美| 国产精品综合 | 日本不卡一区二区三区视频 | 黄色三级国产 | 国产原创视频在线观看 | 国产av剧情一区 | 日韩在线天堂 | 久久黄色小说 | 日韩在线第一 | 国产成人无码一区二区三区在线 | 中文字幕精品久久久久人妻红杏ⅰ | 亚洲 日本 欧美 中文幕 | 国内外免费激情视频 | 波多野吉衣视频在线观看 | 大陆av在线播放 | 午夜淫片| 深夜视频在线观看免费 | 综合久久一区 | 日韩av一 | 日日操日日碰 | 日韩精品免费观看 | 亚洲色图偷拍视频 | 白嫩少妇激情无码 | 国产国产乱老熟女视频网站97 | 日韩在线免费av | 极品尤物在线观看 | 亚洲天堂五码 | av黄色天堂 | 岛国av免费在线 | 色多多在线观看 | 国产精品亚洲一区二区三区在线观看 | 一本色道久久88加勒比—综合 | 色一情一乱一乱一区91av | 亚洲最大在线观看 | 桃色视频网站 | 熟女俱乐部一区二区视频在线 | 99国产精品人妻噜啊噜 | 色视频国产 | www.youjizz.com在线观看 | 国产精品黑人一区二区三区 | 色涩网站 | 污视频软件在线观看 | 韩日视频一区 | 偷偷操网站 | 韩国av网 | 久久亚洲激情 | 亚洲在线资源 | 国产毛片aaa | 亚洲天堂无吗 | 黄色免费看片 | 伊人久久精品一区二区三区 | 国产毛片久久久久久 | 7777在线视频 | 日韩av视屏 | 一级黄色免费 | 日本高清视频一区 | 波多野结衣乳巨码无在线 | 国产精品免费看片 | 国产午夜一区二区三区 | 2021毛片| 免费一级一片 | 国产a大片| 天天上天天干 | 免费中文字幕av | 免费色网址 | 少妇特黄一区二区三区 | 天堂中文在线观看 | 日韩一区二区影视 | 欧美精品播放 | 激情久久免费视频 | 麻豆亚洲av熟女国产一区二 | 亚洲免费黄色片 | 亚洲一区播放 | 欧美美女性视频 | 午夜粉色视频 | 女优一区二区三区 | 毛片毛多水多 | 影音先锋色小姐 |