DAY28 CNN(卷积神经网路 续二)

昨天介绍完CNN卷积神经网路正向传播程序,今天要来研究CNN卷积神经网路反向传播程序:

首先在上次全连接层Softmax做反向传播:
首先依照之前说明的机率out:
https://ithelp.ithome.com.tw/upload/images/20211012/20141654QWJCQq0puu.png
把它做偏微分并使用chain rule:
会有以下两种情况
1.c≠k
https://ithelp.ithome.com.tw/upload/images/20211012/20141654hiXA5Yu3nz.png
2.c=k
https://ithelp.ithome.com.tw/upload/images/20211012/20141654zvxuWh2d5L.png
然後依照
https://ithelp.ithome.com.tw/upload/images/20211012/20141654PZjCgnMv3L.png
我们可以得到偏微:
https://ithelp.ithome.com.tw/upload/images/20211012/201416540Vi8Xzeeot.png
在依照chain rule
https://ithelp.ithome.com.tw/upload/images/20211012/20141654fvkDh1ygJ5.png
其中,我们最终想要这三个微分

  1. 可以更新权重
  2. 可以更新bias
  3. 可以更新反向传播至池化层数据

所以全连接层反向传播程序如下:
在原本class:Softmax上加上反向运算def

#全连接层反向传播
    def backprop(self, d_L_d_out, learn_rate):
        for i, gradient in enumerate(d_L_d_out):
        	#如果没有梯度就下一个
            if gradient == 0:
                continue
        	#exp(tc)-->分子
            t_exp = np.exp(self.last_totals)
        
            #S-->分母
            S = np.sum(t_exp)
            
			#dout/dt k != c 情况
            d_out_d_t = -t_exp[i] * t_exp / (S ** 2)
            #dout/dt k == c 情况
            d_out_d_t[i] = t_exp[i] * (S - t_exp[i]) / (S ** 2)
        	
        	#dt/dw
            d_t_d_w = self.last_input  
            #dt/db
            d_t_d_b = 1
            #dt/input 1000 x 10
            d_t_d_inputs = self.weights
        
            #dL/dt = dout/dt*梯度 
            d_L_d_t = gradient * d_out_d_t
        
            
            #dL/dw = dt/dw*dL/dt 	(1000, 1) @ (1, 10) = (1000, 10)
            d_L_d_w = d_t_d_w[np.newaxis].T @ d_L_d_t[np.newaxis]
            #dL/db = dL/dt*dt/db
            d_L_d_b = d_L_d_t * d_t_d_b
            #dL/dinputs = dt/dinputs*dL/dt 	(1000, 10) @ (10, 1)= (1000, 1)
            d_L_d_inputs = d_t_d_inputs @ d_L_d_t
        
            #更新权重还有bias
            
            self.weights -= learn_rate * d_L_d_w
            self.biases -= learn_rate * d_L_d_b
        

            return d_L_d_inputs.reshape(self.last_input_shape)

接下来是池化层:
基本上非最大值在微分後就会是0,所以如下图:
https://ithelp.ithome.com.tw/upload/images/20211012/201416540d3woSy8AN.png
所以程序如下,在原本class:MaxPool2加上反向运算def

#反向运算    
    def backprop(self, d_L_d_out):
    	#dL/dinput -->一开始设置为0
        d_L_d_input = np.zeros(self.last_input.shape)
        
        for im_region, i, j in self.iterate_regions(self.last_input):
            h, w, f = im_region.shape
            #找寻那区域最大值
            amax = np.amax(im_region, axis=(0, 1))
            
            for i2 in range(h):
                for j2 in range(w):
                    for f2 in range(f):
                    	#如果是最大值就把刚刚dL/dinput传入这层dL/dinput
                        if im_region[i2, j2, f2] == amax[f2]:
                            d_L_d_input[i + i2, j + j2, f2] = d_L_d_out[i, j, f2]
                            
        return d_L_d_input

最後反向给卷积层:
https://ithelp.ithome.com.tw/upload/images/20211012/20141654dGDq54Mbut.png
所以他的偏微就是那张照片范围:
程序如下:在class:Conv3x3加上反向运算def

#反向运算
    def backprop(self, d_L_d_out, learn_rate):
    	#dL/dfilter --> 一开始设置为0
        d_L_d_filters = np.zeros(self.filters.shape)
        for im_region, i, j in self.iterate_regions(self.last_input):
            for f in range(self.num_filters):
            	#dL/dfilter = sum(dL/dout*照片区块)
                d_L_d_filters[f] += d_L_d_out[i, j, f] * im_region
        #调整一开始filters   用学习率*dL/dfilter
        self.filters -= learn_rate * d_L_d_filters

(资料来源:https://zhuanlan.zhihu.com/p/102119808并加上注解程序)

好,今天CNN反向传播程序算是研究完,明天就把CNN的程序完成,并且去跑执行结果

在戒指发光同一时间,原本飘在空中羽毛掉落在地上,刚好掉到娃娃旁边,原来娃娃在刚刚,终於精疲力尽倒下,而地面上还冒出鲜血和娃娃血液混合再一起,当羽毛碰到血的时候.羽毛突然产生变化,几秒钟之後,出现了一只狐狸,只不过这只狐狸没有嘴巴,而且四肢通红,狐狸环顾四周後,随即抬起红色爪子,而此时前方树木开始燃烧,最终烧成灰烬,而前方赫然就是森林出口

        --|你们到底是谁?为何要如此执着?|--  MM.CS

<<:  Day 28 - 将 Specification 後台储存资料提取後,送至前台渲染 Specification 版面内容区块 - MSSQL 查询精灵 - ASP.NET Web Forms C#

>>:  表单处理 Object 里的 Array

【资料库系统】L2 关联式模型

L2 关联式模型 2-1 关联式模型结构 表(tables):一个关联式资料库包含了表的集合 关联(...

Day12 CSS基础设定介绍_1

文字及字体 文字大小及字体是我们在网页中最常设定跟调整的,在预设的字体中你可能找不到你想要的字体类型...

基本操作 - 登入,取得市场清单

引用 Shioaji 要使用 shioaji 的话,一开始要先引用,这一段就是引用并给予一个简称 s...

[Day07- React Native]建立 React Native 专案

React Native 官网 现在有许多可以建立双平台的工具,像是 Golang 的 Flutte...

[DAY 17] 回应试算表

存放题目和读取题目的google 试算表搞定了 呈现题目的google 表单也搞定了 接下来来说说记...