前言

之前写了篇文章《手撕神经网络(1)——神经网络的基本组件》介绍了手撕神经网络的各个层。但是疫情和学习原因,导致其后续一直没有机会写,这两天难得空闲,终于有机会继续分享。

概要

在文章《手撕神经网络(1)——神经网络的基本组件》一文中,我们将神经网络的各个组件,通过python类的方式定义完毕,而在这篇文章中,我们就来使用这些积木,搭建成我们的神经网络。

网络结构

为双层神经网络,即含有:

  • 一个输入层
  • 一个隐藏层
  • 一个输出层
    我们仍然是使用python类来定义网络的结构

初始化

超参数

显然,对于一个双层神经网络,其有哪些超参数?—— 最基本的就是:各个层的神经元个数,分别设置为:input_size,hidden_size,output_size

网络参数

权重

对于一个双层神经网络,其参数为第一层的权重w1,b1w_1,b1w1​,b1,第二层的权重w2,b2w_2,b_2w2​,b2​。我们将这些参数协程该类的属性:

class TwoLayerNet:def __init__(self, input_size,hidden_size,output_size,weight_init_std=0.01):# 初始化权重self.params={}self.params['W1']=weight_init_std*np.random.randn(input_size,hidden_size)self.params['b1']=np.zeros(hidden_size)self.params['W2']=weight_init_std*np.random.randn(hidden_size,output_size)self.params['b2']=np.zeros(output_size)

这里,为了方便对第一层的权重w1,b1w_1,b1w1​,b1,第二层的权重w2,b2w_2,b_2w2​,b2​的管理,我们使用一个容器(字典)来包装它们。

你可能会发现,我们本文开头提到的搭建积木的事,直到现在都没有提起。也没有用到积木。不着急,在使用这些积木搭建我们的模型之前,我们先来想一下我们的神经网络的功能:

  • 预测:通过正向传播,将输入转化为输出。即我们的神经网络类需要有forward方法。
  • 学习:通过反向传播,通过计算实际输出与正确标签之间的误差,计算误差的梯度,在通过梯度下降法完成网络参数的更新。即我们的神经网络类需要有backward方法。
    现在,你可以回到文章《手撕神经网络(1)——神经网络的基本组件》中看一看,我们的积木——也就是每一个层的类,都定义了什么方法?—— 正好是我们整个神经网络所需要的forward方法和backward方法!
    所以,讲到这里,你脑海里一定闪过一个聪明的想法:要实现整个神经网络的正向(反向)传播,只需要用一个for loop遍历所有的层(也就是我们的积木),将上一个层的正向(反向)传播所得到的结果传递给下一层不就行了吗!
    ——是的,这也是链式法则的思想,也是我们接下来要做的事情。但是,先别着急,在做这些之前,我们还需要将这些层(积木)作为属性传递给我们的神经网络类,因为我们无论是在forward方法还是backward方法中,都会用到!
        # 各个层self.layers=OrderedDict()self.layers['Affine1']=Affine(self.params['W1'],self.params['b1'])self.layers['ReLU1']=Relu()self.layers['Affine2']=Affine(self.params['W2'],self.params['b2'])self.lastLayer=SoftmaxWithLoss()

注意,这里出于同样地目的,我是用了字典这个容器来包装各个层。但是这个字典不是一个普通的字典,而是一个有序字典(普通的哈希表是无序的,这一点你是知道的)。这是因为我们希望各个层在进行正向和反向传播时都能保持前后顺序。

讲到这里,实际上我们的搭积木过程也完成了。—— 你可能会疑惑:嗯?你真的搭积木了吗,我怎么没有发现?——嗯,我真的搭建了,因为搭积木不就是把我们的组件(层)按照一定的顺序组合起来吗。我们的有序字典已经完成了这件事情!

完整初始化代码

from collections import OrderedDictclass TwoLayerNet:def __init__(self, input_size,hidden_size,output_size):# 初始化权重self.params={}self.params['W1']=np.random.randn(input_size,hidden_size)self.params['b1']=np.zeros(hidden_size)self.params['W2']=np.random.randn(hidden_size,output_size)self.params['b2']=np.zeros(output_size)# 各个层self.layers=OrderedDict()self.layers['Affine1']=Affine(self.params['W1'],self.params['b1'])self.layers['ReLU1']=Relu()self.layers['Affine2']=Affine(self.params['W2'],self.params['b2'])self.lastLayer=SoftmaxWithLoss()

前向传播

我们的积木已经搭建完成,但是距离最终的任务还很遥远,因为我们现在只是有一个框架,我们所搭建的模型还没有一些实用的功能。神经网络的一个最基本的功能应该是——正向传播。其实现方法之前已经介绍过,通过for loop即可:

    def predict(self,x):for layer in self.layers.values():x=layer.forward(x)    # 逐层前向传播return x

反向传播

想一下,我们反向传播,传播的是什么?——是误差(对参数的梯度),是损失(对参数的梯度)。所以,我们在实现反向传播的方法之前,需要先实现一个误差计算的方法。

    def loss(self,x,t):y=self.predict(x)return self.lastLayer.forward(y,t)

下面,需要实现反向传播,我们的方法要完成这样的功能:输入数据对(X,y)(X,y)(X,y),计算误差loss并计算loss对网络参数的梯度,然后将梯度返回。

    def backward(self,x,t):self.loss(x,t)    # 前向传播dout=1  # 最后一层的反向输入,为1dout=self.lastLayer.backward(dout)layers=list(self.layers.values())  # 将所有的层按顺序放入列表中layers.reverse()  # 反向传播,需要从最后一层开始,一直向前传播for layer in layers:    # 反向传播dout=layer.backward(dout)# 获取梯度grads={}grads['W1']=self.layers['Affine1'].dWgrads['b1']=self.layers['Affine1'].dbgrads['W2']=self.layers['Affine2'].dWgrads['b2']=self.layers['Affine2'].dbreturn grads

在上面的代码中,有一点需要注意,那就是反向传播的过程完成以后,各个Affine层的梯度属性自动被更新,我们直接取各Affine个层的梯度属性即可。

其他方法

为了使神经网络的功能更加完善,我们再给神经网络添加一个方法,比如计算精度的方法:

    def accuracy(self,x,t):y=self.predict(x)y=np.argmax(y,axis=1)if t.ndim != 1:t=np.argmax(t,axis=1)accuracy=np.sum(y==t)/float(x.shape[0])return accuracy

到目前为止,整个神经网络的搭建已经完成! 下一篇文章中,我将给出训练的过程。

代码

https://github.com/HanggeAi/numpy-neural-network

手撕神经网络(2)—— 将基本组件搭建成躯干相关推荐

  1. 深度学习之手撕深度神经网络DNN代码(基于numpy)

    声明 1)本文仅供学术交流,非商用.所以每一部分具体的参考资料并没有详细对应.如果某部分不小心侵犯了大家的利益,还望海涵,并联系博主删除. 2)博主才疏学浅,文中如有不当之处,请各位指出,共同进步,谢 ...

  2. 手撕python_GitHub - caishiqing/manual: 手撕机器学习

    手撕机器学习 用腻了开源框架,尝试下手撕机器学习模型?写这个手撕机器学习系列,旨在不使用任何开源框架的条件下手推实现各种模型,同时保证高性能. Requirements 适用于python2.7与py ...

  3. 手撕图机器学习,图神经网络

    手撕图机器学习,图神经网络 写在前面 & 配套链接(访者必读) 图的基本表示 图的基本参数 图的类别 节点连接数(Node degree) 图的矩阵表示(邻接矩阵) 连接列表和邻接列表 其他图 ...

  4. 手撕Resnet卷积神经网络-pytorch-详细注释版(可以直接替换自己数据集)-直接放置自己的数据集就能直接跑。跑的代码有问题的可以在评论区指出,看到了会回复。训练代码和预测代码均有。

    Alexnet网络详解代码:手撕Alexnet卷积神经网络-pytorch-详细注释版(可以直接替换自己数据集)-直接放置自己的数据集就能直接跑.跑的代码有问题的可以在评论区指出,看到了会回复.训练代 ...

  5. 你绕不开的组件—锁,4个方面手撕锁的多种实现

    你绕不开的组件-锁,4个方面手撕锁的多种实现|互斥锁的原理|自旋锁的原理|原子操作的汇编代码|CAS的实现 专注于服务器后台开发,包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Re ...

  6. 手撕包菜 mysql_手撕包菜搭建

    概述 最近做了两件事,一件事就是买了块1t硬盘,第二件事就是买了个百度云会员,无奈找不到资源下载,那就没办法了,搭建一个磁力链接搜索引擎来爬去链接,然后去找资源. 说道磁力链接搜索引擎,最好的当然是手 ...

  7. 手撕Alexnet卷积神经网络-pytorch-详细注释版(可以直接替换自己数据集)-直接放置自己的数据集就能直接跑。跑的代码有问题的可以在评论区指出,看到了会回复。训练代码和预测代码均有。

    Alexnet网络详解代码:手撕Alexnet卷积神经网络-pytorch-详细注释版(可以直接替换自己数据集)-直接放置自己的数据集就能直接跑.跑的代码有问题的可以在评论区指出,看到了会回复.训练代 ...

  8. 从零构建神经网络-不使用框架(纯纯手撕)

    一.从零构建神经网络-不使用框架(纯手撕) 神经网络从0开始 动手从零开始实现一个神经网络,不使用框架,一步一步推理应该可以加深一下对神经网络的理解. 网络结构为三层全连接网络,节点个数依次为784. ...

  9. 手撕VGG卷积神经网络-pytorch-详细注释版(可以直接替换自己数据集)-直接放置自己的数据集就能直接跑。跑的代码有问题的可以在评论区指出,看到了会回复。训练代码和预测代码均有。

    Alexnet网络详解代码:手撕Alexnet卷积神经网络-pytorch-详细注释版(可以直接替换自己数据集)-直接放置自己的数据集就能直接跑.跑的代码有问题的可以在评论区指出,看到了会回复.训练代 ...

最新文章

  1. 小程序clearinterval无效解决
  2. 字符串匹配shiftand算法
  3. 【FFmpeg】函数详解(二)
  4. matlab m 文件例子,一个简单OFDM例子(matlab m文件)
  5. MAC OSX10.9.2上搭建Apache,php
  6. js中继承的几种用法总结(apply,call,prototype)
  7. 音视频技术开发周刊 | 204
  8. git忽略某个文件夹
  9. 【Elasticsearch】class_cast_exception KeywordFieldMapper cannot be cast to ObjectMapper
  10. CSS重新认识(一)
  11. php图像生成和处理,PHP的gd库(图像生成和处理)的应用
  12. 疫情防控背景下在线课程教学满意度影响因素分析与对策探讨-以电子商务及法律专业为例
  13. 纯净版VS2015安装教程(适合初次安装或者重装系统后)
  14. 一键批量检测微信是否被好友删除,支持最新版微信
  15. 二进制与base64
  16. java求面积_Java计算几何图形的面积
  17. 斯坦福大学校工程学院计算机,加州大学洛杉矶分校:受大脑启发的计算机视觉的对象发现和检测...
  18. 配置文件工具类【ConfigTools】
  19. leetcode-数据结构-566. 重塑矩阵
  20. 【Spring Boot】使用 SSL 证书加密 API(HTTPS)

热门文章

  1. 一张图数字孪生北京大兴机场
  2. netty对接青鸟消防主机
  3. 广东高科技产业商会会长王理宗:回眸经典故事重燃青春岁月
  4. linux建立分区,介绍Linux硬盘系统建立分区步骤
  5. 物联网感知层数据通信综合创新技术
  6. RactNative---react-native-storage使用
  7. 2021年川师大九中高考成绩查询,大写的优秀!包九中发布2020年高考“成绩单”!...
  8. 开网店必看:2019年,《电商法》下五大电商趋势分析!
  9. L9935_二相步进电机驱动器
  10. IOS学习博客-坚持就是胜利