在之前的深度学习笔记(一):logistic分类 中,已经描述了普通logistic回归以及如何将logistic回归用于多类分类。在这一节,我们再进一步,往其中加入隐藏层,构建出最简单的神经网络


2.简单神经网络及后向传播算法


2.1 大概描述和公式表达

神经网络的大概结构如图所示,


从左往右,分别是输入层,隐藏层,输出层,分别记为x,h, y. 从输入层到隐藏层的矩阵记为Whx, 偏置向量bh; 从隐藏层到输出层的矩阵记为Wyh, 偏置向量为by. 那么根据之前logistic分类的公式稍作扩展,不难得到

hz=Whxx+bhha=σ(hz)yz=Wyhha+byya=σ(yz)

其实就是两层logistic分类的堆叠,将前一个分类器的输出作为后一个的输入。得到输出ya 以后的判断方法也比较类似,哪项最高就判定属于哪一类。真正值得写一下的是神经网络中的后向算法。按照传统的logistic分类,只能做到根据误差来更新Wyh 和by 那么如何来更新从输入层到隐藏层的参数Whx和bh呢?这就要用到后向算法了。所谓后向算法,就是指误差由输出层逐层往前传递,进而逐层更新参数矩阵和偏执向量。后向算法的核心其实就4个字:链式法则。首先来看Wyh 和by的更新

C=12(ya−y)2∂C∂yz=C′σ′(yz)=(ya−y).×a.×(1−a)∂C∂Wyh=∂C∂yz∂yz∂Wyh=C′σ′(yz)hTa∂C∂by=∂C∂yz∂yz∂by=C′σ′(yz)

其实在上面的公式中,已经用到了链式法则。 类似的,可以得到

∂C∂ha=∂C∂yz∂yz∂ha=WTyh[C′σ′(yz)]∂C∂Whx=∂C∂ha∂ha∂W=[∂C∂haσ′(hz)]xT∂C∂bh=∂C∂ha∂ha∂bh=[∂C∂haσ′(hz)]

可以看到,在Whx和bh的计算中都用到了∂C∂ha 这可以看成由输出层传递到中间层的误差。那么在获得了各参数的偏导数以后,就可以对参数进行修正了

Wyh:=Wyh−η∂C∂Wyhby:=by−η∂C∂byWhx:=Whx−η∂C∂Whxbh:=bh−η∂C∂bh

2.2 神经网络的简单实现

为了加深印象,我自己实现了一个神经网络分类器,分类效果如下图所示


上图中,左上角显示的是实际的分类,右上角显示的是分类器判断出的各点分类。靠下的图显示的是分类器的判断准确率随迭代次数的变化情况。可以看到,经过训练以后,分类器的判断准确率还是可以的。

下面是代码部分

import numpy as np
import matplotlib.pyplot as plt
import random
import math# 构造各个分类
def gen_sample():data = []radius = [0,50]for i in range(1000):  # 生成10k个点catg = random.randint(0,1)  # 决定分类r = random.random()*10arg = random.random()*360len = r + radius[catg]x_c = math.cos(math.radians(arg))*leny_c = math.sin(math.radians(arg))*lenx = random.random()*30 + x_cy = random.random()*30 + y_cdata.append((x,y,catg))return datadef plot_dots(data):data_asclass = [[] for i in range(2)]for d in data:data_asclass[int(d[2])].append((d[0],d[1]))colors = ['r.','b.','r.','b.']for i,d in enumerate(data_asclass):# print(d)nd = np.array(d)plt.plot(nd[:,0],nd[:,1],colors[i])plt.draw()def train(input, output, Whx, Wyh, bh, by):"""完成神经网络的训练过程:param input:   输入列向量, 例如 [x,y].T:param output:  输出列向量, 例如[0,1,0,0].T:param Whx:     x->h 的参数矩阵:param Wyh:     h->y 的参数矩阵:param bh:      x->h 的偏置向量:param by:      h->y 的偏置向量:return:"""h_z = np.dot(Whx, input) + bh   # 线性求和h_a = 1/(1+np.exp(-1*h_z))      # 经过sigmoid激活函数y_z = np.dot(Wyh, h_a) + byy_a = 1/(1+np.exp(-1*y_z))c_y = (y_a-output)*y_a*(1-y_a)dWyh = np.dot(c_y, h_a.T)dby = c_yc_h = np.dot(Wyh.T, c_y)*h_a*(1-h_a)dWhx = np.dot(c_h,input.T)dbh = c_hreturn dWhx,dWyh,dbh,dby,c_ydef test(train_set, test_set, Whx, Wyh, bh, by):train_tag = [int(x) for x in train_set[:,2]]test_tag = [int(x) for x in test_set[:,2]]train_pred = []test_pred = []for i,d in enumerate(train_set):input = train_set[i:i+1,0:2].Ttag = predict(input,Whx,Wyh,bh,by)train_pred.append(tag)for i,d in enumerate(test_set):input = test_set[i:i+1,0:2].Ttag = predict(input,Whx,Wyh,bh,by)test_pred.append(tag)# print(train_tag)# print(train_pred)train_err = 0test_err = 0for i in range(train_pred.__len__()):if train_pred[i]!=int(train_tag[i]):train_err += 1for i in range(test_pred.__len__()):if test_pred[i]!=int(test_tag[i]):test_err += 1# print(test_tag)# print(test_pred)train_ratio = train_err / train_pred.__len__()test_ratio = test_err / test_pred.__len__()return train_err,train_ratio,test_err,test_ratiodef predict(input,Whx,Wyh,bh,by):# print('-----------------')# print(input)h_z = np.dot(Whx, input) + bh   # 线性求和h_a = 1/(1+np.exp(-1*h_z))      # 经过sigmoid激活函数y_z = np.dot(Wyh, h_a) + byy_a = 1/(1+np.exp(-1*y_z))# print(y_a)tag = np.argmax(y_a)return tagif __name__=='__main__':input_dim   = 2output_dim  = 2hidden_size = 200Whx = np.random.randn(hidden_size, input_dim)*0.01Wyh = np.random.randn(output_dim, hidden_size)*0.01bh  = np.zeros((hidden_size, 1))by  = np.zeros((output_dim, 1))data = gen_sample()plt.subplot(221)plot_dots(data)ndata = np.array(data)train_set = ndata[0:800,:]test_set = ndata[800:1000,:]train_ratio_list = []test_ratio_list = []for times in range(10000):i = times%train_set.__len__()input = train_set[i:i+1,0:2].Ttag = int(train_set[i,2])output = np.zeros((2,1))output[tag,0] = 1dWhx,dWyh,dbh,dby,c_y = train(input,output,Whx,Wyh,bh,by)if times%100==0:train_err,train_ratio,test_err,test_ratio = test(train_set,test_set,Whx,Wyh,bh,by)print('times:{t}\t train ratio:{tar}\t test ratio: {ter}'.format(tar=train_ratio,ter=test_ratio,t=times))train_ratio_list.append(train_ratio)test_ratio_list.append(test_ratio)for param, dparam in zip([Whx, Wyh, bh, by],[dWhx,dWyh,dbh,dby]):param -= 0.01*dparamfor i,d in enumerate(ndata):input = ndata[i:i+1,0:2].Ttag = predict(input,Whx,Wyh,bh,by)ndata[i,2] = tagplt.subplot(222)plot_dots(ndata)# plt.figure()plt.subplot(212)plt.plot(train_ratio_list)plt.plot(test_ratio_list)plt.show()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144

深度学习笔记(二):简单神经网络,后向传播算法及实现相关推荐

  1. 深度学习笔记:卷积神经网络的可视化--卷积核本征模式

    目录 1. 前言 2. 代码实验 2.1 加载模型 2.2 构造返回中间层激活输出的模型 2.3 目标函数 2.4 通过随机梯度上升最大化损失 2.5 生成滤波器模式可视化图像 2.6 将多维数组变换 ...

  2. 【数据挖掘】神经网络 后向传播算法 向前传播输入 案例计算分析 ( 网络拓扑 | 输入层计算 | 隐藏层计算 | 输出层计算 )

    文章目录 I . 神经网络 后向传播算法 计算 隐藏层 与 输出层 的输入输出实例分析 II . 神经网络 后向传播算法 输入层公式 III. 神经网络 后向传播算法 输入层计算 IV . 神经网络 ...

  3. 【深度学习笔记1】神经网络的搭建与简单应用

    目录 推荐阅读 前言 神经网络与深度学习 使用Tensorflow搭建神经网络 环境搭建和导包遇到的问题: 问题1:Duplicate registrations for type 'optimize ...

  4. 深度学习(二)神经网络中的卷积和反卷积原理

    原文作者:aircraft 原文地址:https://www.cnblogs.com/DOMLX/p/9579392.html 一.卷积 在深度学习的过程中,很多神经网络都会用到各种卷积核来进行操作, ...

  5. 深度学习笔记:卷积神经网络的Tensorflow实现

    文章出处:深度学习笔记11:利用numpy搭建一个卷积神经网络 免费视频课程:Hellobi Live | 从数据分析师到机器学习(深度学习)工程师的进阶之路 在上一讲中,我们学习了如何利用 nump ...

  6. 【数据挖掘】神经网络 后向传播算法 ( 梯度下降过程 | 梯度方向说明 | 梯度下降原理 | 损失函数 | 损失函数求导 | 批量梯度下降法 | 随机梯度下降法 | 小批量梯度下降法 )

    文章目录 I . 梯度下降 Gradient Descent 简介 ( 梯度下降过程 | 梯度下降方向 ) II . 梯度下降 示例说明 ( 单个参数 ) III . 梯度下降 示例说明 ( 多个参数 ...

  7. 【数据挖掘】神经网络 后向传播算法( 向后传播误差 | 输出层误差公式 | 隐藏层误差公式 | 单元连接权值更新公式 | 单元偏置更新公式 | 反向传播 | 损失函数 | 误差平方和 | 交叉熵 )

    文章目录 I . 向后传播误差 简介 II . 输出层误差计算公式 III . 隐藏层层误差计算公式 IV . 使用误差更新 连接权值 V . 使用误差更新 单元偏置 VI . 反向传播 过程 VII ...

  8. 1.3)深度学习笔记------浅层神经网络

    目录 1)Neural Network Overview 2)Neural Network Representation 3)Computing a Neural Network's Output(重 ...

  9. 吴恩达深度学习笔记- lesson4 卷积神经网络

    文章目录 Week 1 卷积神经网络基础 4.1.1 计算机视觉(Computer vision) 4.1.2 边缘检测示例(Edge detection example) 4.1.3 更多边缘检测内 ...

  10. 深度学习(二) 神经网络基础算法推导与实践

    深度学习的核心就是各种不同的神经网络模型(CNN.RNN.GCN.GNN等)的学习和训练过程.这些神经网络模型的共同点都是一个"黑盒子",通过一定的学习算法将大量数据交给模型训练, ...

最新文章

  1. vc6静态库的生成和调用
  2. 以为Swing没人用了,原来群友们都是如此优秀!
  3. thymeleaf常用属性
  4. python怎样算学的好_python怎么学习好
  5. 【性能优化】如何让APK瘦成一道闪电
  6. The Future Of Mobile Development: HTML5 Vs. Native Apps
  7. waves效果器_学会EQ效果器,浑厚亮嗓又大气
  8. LaTex论文排版 | (24) 插入超链接和目录
  9. 怎样锁定oracle用户名,oracle 锁定用户
  10. 十个程序员必备的网站推荐
  11. cubase打开时,别的软件和网页无法正常播放视频。
  12. 微信小程序关键字搜索
  13. ce查找人物基址_关于CE找基址的一些基础概念
  14. 启动Tomcat服务器报错:Several ports (8005, 8080, 8009) required by Tomcat v9.0 Server at localhost are alrea
  15. 微信正式支持注册小号,但不是谁都可以
  16. 基于BIM轻量化的智能建造OA管理系统
  17. 自然语言处理(二)——词性标注与命名实体识别
  18. HMI-7-[高分屏支持]:Qt 适配高分屏
  19. 酷友观点/经验:iphone 5\6\6p各尺寸参照图(原创)
  20. LDO线性稳压器详解

热门文章

  1. Newtonsoft.Json序列化和反序列之javascriptConvert.SerializeObject,DeserializeObject,JsonWriter,JsonReader...
  2. LeetCode - Remove Duplicates from Sorted List
  3. html矩形变圆形的代码,html5canvas绘制矩形和圆形的实例代码.pdf
  4. Html页面增加返回顶部图标和隐藏出现
  5. 杭电oj-----Farm Irrigation(BFS)
  6. centos7 文件名中文乱码_CentOS 下中文文件名显示乱码问题
  7. python 复制列表内容_python 复制列表的六种方法
  8. python重写和装饰器_Python | 老司机教你 5 分钟读懂 Python 装饰器
  9. python在字典中插入新的数据_Python数据类型之字典dict
  10. 缩放浏览器不会换行_深入解析 EventLoop 和浏览器渲染、帧动画、空闲回调的关系...