<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      一文弄懂神經(jīng)網(wǎng)絡(luò)中的反向傳播法——BackPropagation

        最近在看深度學(xué)習(xí)的東西,一開始看的吳恩達的UFLDL教程,有中文版就直接看了,后來發(fā)現(xiàn)有些地方總是不是很明確,又去看英文版,然后又找了些資料看,才發(fā)現(xiàn),中文版的譯者在翻譯的時候會對省略的公式推導(dǎo)過程進行補充,但是補充的又是錯的,難怪覺得有問題。反向傳播法其實是神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)了,但是很多人在學(xué)的時候總是會遇到一些問題,或者看到大篇的公式覺得好像很難就退縮了,其實不難,就是一個鏈?zhǔn)角髮?dǎo)法則反復(fù)用。如果不想看公式,可以直接把數(shù)值帶進去,實際的計算一下,體會一下這個過程之后再來推導(dǎo)公式,這樣就會覺得很容易了。

        說到神經(jīng)網(wǎng)絡(luò),大家看到這個圖應(yīng)該不陌生:

       

        這是典型的三層神經(jīng)網(wǎng)絡(luò)的基本構(gòu)成,Layer L1是輸入層,Layer L2是隱含層,Layer L3是隱含層,我們現(xiàn)在手里有一堆數(shù)據(jù){x1,x2,x3,...,xn},輸出也是一堆數(shù)據(jù){y1,y2,y3,...,yn},現(xiàn)在要他們在隱含層做某種變換,讓你把數(shù)據(jù)灌進去后得到你期望的輸出。如果你希望你的輸出和原始輸入一樣,那么就是最常見的自編碼模型(Auto-Encoder)。可能有人會問,為什么要輸入輸出都一樣呢?有什么用啊?其實應(yīng)用挺廣的,在圖像識別,文本分類等等都會用到,我會專門再寫一篇Auto-Encoder的文章來說明,包括一些變種之類的。如果你的輸出和原始輸入不一樣,那么就是很常見的人工神經(jīng)網(wǎng)絡(luò)了,相當(dāng)于讓原始數(shù)據(jù)通過一個映射來得到我們想要的輸出數(shù)據(jù),也就是我們今天要講的話題。

        本文直接舉一個例子,帶入數(shù)值演示反向傳播法的過程,公式的推導(dǎo)等到下次寫Auto-Encoder的時候再寫,其實也很簡單,感興趣的同學(xué)可以自己推導(dǎo)下試試:)(注:本文假設(shè)你已經(jīng)懂得基本的神經(jīng)網(wǎng)絡(luò)構(gòu)成,如果完全不懂,可以參考Poll寫的筆記:[Mechine Learning & Algorithm] 神經(jīng)網(wǎng)絡(luò)基礎(chǔ)

        假設(shè),你有這樣一個網(wǎng)絡(luò)層:

        第一層是輸入層,包含兩個神經(jīng)元i1,i2,和截距項b1;第二層是隱含層,包含兩個神經(jīng)元h1,h2和截距項b2,第三層是輸出o1,o2,每條線上標(biāo)的wi是層與層之間連接的權(quán)重,激活函數(shù)我們默認為sigmoid函數(shù)。

        現(xiàn)在對他們賦上初值,如下圖:

        其中,輸入數(shù)據(jù)  i1=0.05,i2=0.10;

           輸出數(shù)據(jù) o1=0.01,o2=0.99;

           初始權(quán)重  w1=0.15,w2=0.20,w3=0.25,w4=0.30;

                 w5=0.40,w6=0.45,w7=0.50,w8=0.55

       

        目標(biāo):給出輸入數(shù)據(jù)i1,i2(0.05和0.10),使輸出盡可能與原始輸出o1,o2(0.01和0.99)接近。

       

        Step 1 前向傳播

        1.輸入層---->隱含層:

        計算神經(jīng)元h1的輸入加權(quán)和:

      神經(jīng)元h1的輸出o1:(此處用到激活函數(shù)為sigmoid函數(shù)):

       

       

        同理,可計算出神經(jīng)元h2的輸出o2:

        

       

        2.隱含層---->輸出層:

        計算輸出層神經(jīng)元o1和o2的值:

        

       

      這樣前向傳播的過程就結(jié)束了,我們得到輸出值為[0.75136079 , 0.772928465],與實際值[0.01 , 0.99]相差還很遠,現(xiàn)在我們對誤差進行反向傳播,更新權(quán)值,重新計算輸出。

       

      Step 2 反向傳播

      1.計算總誤差

      總誤差:(square error)

      但是有兩個輸出,所以分別計算o1和o2的誤差,總誤差為兩者之和:

       

      2.隱含層---->輸出層的權(quán)值更新:

      以權(quán)重參數(shù)w5為例,如果我們想知道w5對整體誤差產(chǎn)生了多少影響,可以用整體誤差對w5求偏導(dǎo)求出:(鏈?zhǔn)椒▌t)

      下面的圖可以更直觀的看清楚誤差是怎樣反向傳播的:

      現(xiàn)在我們來分別計算每個式子的值:

      計算

      計算

      (這一步實際上就是對sigmoid函數(shù)求導(dǎo),比較簡單,可以自己推導(dǎo)一下)

       

      計算

      最后三者相乘:

      這樣我們就計算出整體誤差E(total)對w5的偏導(dǎo)值。

      回過頭來再看看上面的公式,我們發(fā)現(xiàn):

      為了表達方便,用來表示輸出層的誤差:

      因此,整體誤差E(total)對w5的偏導(dǎo)公式可以寫成:

      如果輸出層誤差計為負的話,也可以寫成:

      最后我們來更新w5的值:

      (其中,是學(xué)習(xí)速率,這里我們?nèi)?.5)

      同理,可更新w6,w7,w8:

       

      3.隱含層---->隱含層的權(quán)值更新:

       方法其實與上面說的差不多,但是有個地方需要變一下,在上文計算總誤差對w5的偏導(dǎo)時,是從out(o1)---->net(o1)---->w5,但是在隱含層之間的權(quán)值更新時,是out(h1)---->net(h1)---->w1,而out(h1)會接受E(o1)和E(o2)兩個地方傳來的誤差,所以這個地方兩個都要計算。

       

       

      計算

      先計算

      同理,計算出:

                

      兩者相加得到總值:

      再計算

      再計算

      最后,三者相乘:

       為了簡化公式,用sigma(h1)表示隱含層單元h1的誤差:

      最后,更新w1的權(quán)值:

      同理,額可更新w2,w3,w4的權(quán)值:

       

        這樣誤差反向傳播法就完成了,最后我們再把更新的權(quán)值重新計算,不停地迭代,在這個例子中第一次迭代之后,總誤差E(total)由0.298371109下降至0.291027924。迭代10000次后,總誤差為0.000035085,輸出為[0.015912196,0.984065734](原輸入為[0.01,0.99]),證明效果還是不錯的。

       

      代碼(Python):

        1 #coding:utf-8
        2 import random
        3 import math
        4 
        5 #
        6 #   參數(shù)解釋:
        7 #   "pd_" :偏導(dǎo)的前綴
        8 #   "d_" :導(dǎo)數(shù)的前綴
        9 #   "w_ho" :隱含層到輸出層的權(quán)重系數(shù)索引
       10 #   "w_ih" :輸入層到隱含層的權(quán)重系數(shù)的索引
       11 
       12 class NeuralNetwork:
       13     LEARNING_RATE = 0.5
       14 
       15     def __init__(self, num_inputs, num_hidden, num_outputs, hidden_layer_weights = None, hidden_layer_bias = None, output_layer_weights = None, output_layer_bias = None):
       16         self.num_inputs = num_inputs
       17 
       18         self.hidden_layer = NeuronLayer(num_hidden, hidden_layer_bias)
       19         self.output_layer = NeuronLayer(num_outputs, output_layer_bias)
       20 
       21         self.init_weights_from_inputs_to_hidden_layer_neurons(hidden_layer_weights)
       22         self.init_weights_from_hidden_layer_neurons_to_output_layer_neurons(output_layer_weights)
       23 
       24     def init_weights_from_inputs_to_hidden_layer_neurons(self, hidden_layer_weights):
       25         weight_num = 0
       26         for h in range(len(self.hidden_layer.neurons)):
       27             for i in range(self.num_inputs):
       28                 if not hidden_layer_weights:
       29                     self.hidden_layer.neurons[h].weights.append(random.random())
       30                 else:
       31                     self.hidden_layer.neurons[h].weights.append(hidden_layer_weights[weight_num])
       32                 weight_num += 1
       33 
       34     def init_weights_from_hidden_layer_neurons_to_output_layer_neurons(self, output_layer_weights):
       35         weight_num = 0
       36         for o in range(len(self.output_layer.neurons)):
       37             for h in range(len(self.hidden_layer.neurons)):
       38                 if not output_layer_weights:
       39                     self.output_layer.neurons[o].weights.append(random.random())
       40                 else:
       41                     self.output_layer.neurons[o].weights.append(output_layer_weights[weight_num])
       42                 weight_num += 1
       43 
       44     def inspect(self):
       45         print('------')
       46         print('* Inputs: {}'.format(self.num_inputs))
       47         print('------')
       48         print('Hidden Layer')
       49         self.hidden_layer.inspect()
       50         print('------')
       51         print('* Output Layer')
       52         self.output_layer.inspect()
       53         print('------')
       54 
       55     def feed_forward(self, inputs):
       56         hidden_layer_outputs = self.hidden_layer.feed_forward(inputs)
       57         return self.output_layer.feed_forward(hidden_layer_outputs)
       58 
       59     def train(self, training_inputs, training_outputs):
       60         self.feed_forward(training_inputs)
       61 
       62         # 1. 輸出神經(jīng)元的值
       63         pd_errors_wrt_output_neuron_total_net_input = [0] * len(self.output_layer.neurons)
       64         for o in range(len(self.output_layer.neurons)):
       65 
       66             # ?E/?z?
       67             pd_errors_wrt_output_neuron_total_net_input[o] = self.output_layer.neurons[o].calculate_pd_error_wrt_total_net_input(training_outputs[o])
       68 
       69         # 2. 隱含層神經(jīng)元的值
       70         pd_errors_wrt_hidden_neuron_total_net_input = [0] * len(self.hidden_layer.neurons)
       71         for h in range(len(self.hidden_layer.neurons)):
       72 
       73             # dE/dy? = Σ ?E/?z? * ?z/?y? = Σ ?E/?z? * w??
       74             d_error_wrt_hidden_neuron_output = 0
       75             for o in range(len(self.output_layer.neurons)):
       76                 d_error_wrt_hidden_neuron_output += pd_errors_wrt_output_neuron_total_net_input[o] * self.output_layer.neurons[o].weights[h]
       77 
       78             # ?E/?z? = dE/dy? * ?z?/?
       79             pd_errors_wrt_hidden_neuron_total_net_input[h] = d_error_wrt_hidden_neuron_output * self.hidden_layer.neurons[h].calculate_pd_total_net_input_wrt_input()
       80 
       81         # 3. 更新輸出層權(quán)重系數(shù)
       82         for o in range(len(self.output_layer.neurons)):
       83             for w_ho in range(len(self.output_layer.neurons[o].weights)):
       84 
       85                 # ?E?/?w?? = ?E/?z? * ?z?/?w??
       86                 pd_error_wrt_weight = pd_errors_wrt_output_neuron_total_net_input[o] * self.output_layer.neurons[o].calculate_pd_total_net_input_wrt_weight(w_ho)
       87 
       88                 # Δw = α * ?E?/?w?
       89                 self.output_layer.neurons[o].weights[w_ho] -= self.LEARNING_RATE * pd_error_wrt_weight
       90 
       91         # 4. 更新隱含層的權(quán)重系數(shù)
       92         for h in range(len(self.hidden_layer.neurons)):
       93             for w_ih in range(len(self.hidden_layer.neurons[h].weights)):
       94 
       95                 # ?E?/?w? = ?E/?z? * ?z?/?w?
       96                 pd_error_wrt_weight = pd_errors_wrt_hidden_neuron_total_net_input[h] * self.hidden_layer.neurons[h].calculate_pd_total_net_input_wrt_weight(w_ih)
       97 
       98                 # Δw = α * ?E?/?w?
       99                 self.hidden_layer.neurons[h].weights[w_ih] -= self.LEARNING_RATE * pd_error_wrt_weight
      100 
      101     def calculate_total_error(self, training_sets):
      102         total_error = 0
      103         for t in range(len(training_sets)):
      104             training_inputs, training_outputs = training_sets[t]
      105             self.feed_forward(training_inputs)
      106             for o in range(len(training_outputs)):
      107                 total_error += self.output_layer.neurons[o].calculate_error(training_outputs[o])
      108         return total_error
      109 
      110 class NeuronLayer:
      111     def __init__(self, num_neurons, bias):
      112 
      113         # 同一層的神經(jīng)元共享一個截距項b
      114         self.bias = bias if bias else random.random()
      115 
      116         self.neurons = []
      117         for i in range(num_neurons):
      118             self.neurons.append(Neuron(self.bias))
      119 
      120     def inspect(self):
      121         print('Neurons:', len(self.neurons))
      122         for n in range(len(self.neurons)):
      123             print(' Neuron', n)
      124             for w in range(len(self.neurons[n].weights)):
      125                 print('  Weight:', self.neurons[n].weights[w])
      126             print('  Bias:', self.bias)
      127 
      128     def feed_forward(self, inputs):
      129         outputs = []
      130         for neuron in self.neurons:
      131             outputs.append(neuron.calculate_output(inputs))
      132         return outputs
      133 
      134     def get_outputs(self):
      135         outputs = []
      136         for neuron in self.neurons:
      137             outputs.append(neuron.output)
      138         return outputs
      139 
      140 class Neuron:
      141     def __init__(self, bias):
      142         self.bias = bias
      143         self.weights = []
      144 
      145     def calculate_output(self, inputs):
      146         self.inputs = inputs
      147         self.output = self.squash(self.calculate_total_net_input())
      148         return self.output
      149 
      150     def calculate_total_net_input(self):
      151         total = 0
      152         for i in range(len(self.inputs)):
      153             total += self.inputs[i] * self.weights[i]
      154         return total + self.bias
      155 
      156     # 激活函數(shù)sigmoid
      157     def squash(self, total_net_input):
      158         return 1 / (1 + math.exp(-total_net_input))
      159 
      160 
      161     def calculate_pd_error_wrt_total_net_input(self, target_output):
      162         return self.calculate_pd_error_wrt_output(target_output) * self.calculate_pd_total_net_input_wrt_input();
      163 
      164     # 每一個神經(jīng)元的誤差是由平方差公式計算的
      165     def calculate_error(self, target_output):
      166         return 0.5 * (target_output - self.output) ** 2
      167 
      168     
      169     def calculate_pd_error_wrt_output(self, target_output):
      170         return -(target_output - self.output)
      171 
      172     
      173     def calculate_pd_total_net_input_wrt_input(self):
      174         return self.output * (1 - self.output)
      175 
      176 
      177     def calculate_pd_total_net_input_wrt_weight(self, index):
      178         return self.inputs[index]
      179 
      180 
      181 # 文中的例子:
      182 
      183 nn = NeuralNetwork(2, 2, 2, hidden_layer_weights=[0.15, 0.2, 0.25, 0.3], hidden_layer_bias=0.35, output_layer_weights=[0.4, 0.45, 0.5, 0.55], output_layer_bias=0.6)
      184 for i in range(10000):
      185     nn.train([0.05, 0.1], [0.01, 0.09])
      186     print(i, round(nn.calculate_total_error([[[0.05, 0.1], [0.01, 0.09]]]), 9))
      187 
      188 
      189 #另外一個例子,可以把上面的例子注釋掉再運行一下:
      190 
      191 # training_sets = [
      192 #     [[0, 0], [0]],
      193 #     [[0, 1], [1]],
      194 #     [[1, 0], [1]],
      195 #     [[1, 1], [0]]
      196 # ]
      197 
      198 # nn = NeuralNetwork(len(training_sets[0][0]), 5, len(training_sets[0][1]))
      199 # for i in range(10000):
      200 #     training_inputs, training_outputs = random.choice(training_sets)
      201 #     nn.train(training_inputs, training_outputs)
      202 #     print(i, nn.calculate_total_error(training_sets))

       

        

        最后寫到這里就結(jié)束了,現(xiàn)在還不會用latex編輯數(shù)學(xué)公式,本來都直接想寫在草稿紙上然后掃描了傳上來,但是覺得太影響閱讀體驗了。以后會用公式編輯器后再重把公式重新編輯一遍。穩(wěn)重使用的是sigmoid激活函數(shù),實際還有幾種不同的激活函數(shù)可以選擇,具體的可以參考文獻[3],最后推薦一個在線演示神經(jīng)網(wǎng)絡(luò)變化的網(wǎng)址:http://www.emergentmind.com/neural-network,可以自己填輸入輸出,然后觀看每一次迭代權(quán)值的變化,很好玩~如果有錯誤的或者不懂的歡迎留言:)

       

      參考文獻:

      1.Poll的筆記:[Mechine Learning & Algorithm] 神經(jīng)網(wǎng)絡(luò)基礎(chǔ)http://www.rzrgm.cn/maybe2030/p/5597716.html#3457159 )

      2.Rachel_Zhang:http://blog.csdn.net/abcjennifer/article/details/7758797

      3.http://www.cedar.buffalo.edu/%7Esrihari/CSE574/Chap5/Chap5.3-BackProp.pdf

      4.https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/

       

      ------------------------------------本博客所有內(nèi)容以學(xué)習(xí)、研究和分享為主,如需轉(zhuǎn)載,請聯(lián)系本人,標(biāo)明作者和出處,并且是非商業(yè)用途,謝謝!--------------------------------

       

       

      posted @ 2016-06-30 16:23  Charlotte77  閱讀(454924)  評論(177)    收藏  舉報
      主站蜘蛛池模板: 亚洲色成人网站www永久| 日本一区二区三区在线 |观看| 一级片一区二区中文字幕| 亚洲精品揄拍自拍首页一| 内射一区二区三区四区| 亚洲av与日韩av在线| 日韩精品欧美高清区| 在线中文一区字幕对白| 伊人久久大香线蕉av五月天| 诱人的老师hd中文字幕| 高邮市| 亚洲狠狠狠一区二区三区| 亚洲中文字幕久久精品品| 内射极品少妇xxxxxhd| 精品久久久无码中文字幕| 国产av亚洲一区二区| 蜜桃久久精品成人无码av | 一区二区三区鲁丝不卡| 日韩一区二区三区东京热| 在线a级毛片免费视频| 欧美丰满熟妇xxxx性ppx人交| 亚洲国产成人久久精品不卡| 2020精品自拍视频曝光| 成av免费大片黄在线观看| 国产第一区二区三区精品| 天堂一区人妻无码| 亚洲免费的福利片| 一区二区三区鲁丝不卡| 丝袜美腿亚洲综合第一区| 亚洲精品中文字幕尤物综合| 精品人妻伦一二二区久久| 国产午夜福利精品视频| 丹江口市| 久久这里都是精品二| 精品国产福利久久久| 日本欧美大码a在线观看| 丰满少妇特黄一区二区三区| 最新亚洲av日韩av二区| 伊人成色综合人夜夜久久| 成人免费亚洲av在线| 成人免费无遮挡在线播放|