以前在误差反向传播法里面介绍的神经网络是两层结构,现在来搭建一个多层的结构,神经网络的一个特点或说优势就是可以不断地叠加层(隐藏层)。
       多层结构: 一张数字图片(1*28*28=784)——>Affine1层——>ReLU1(激活层)——>Affine2层——>ReLU2——>......——>AffineN层——>Softmax层(概率)
主要就是生成Affine层和激活函数层,代码就是解释,如有不明白的欢迎留言进行交流

multi_layer_net.py

import numpy as np
from collections import OrderedDict
from common.layers import *
from common.gradient import numerical_gradientclass MultiLayerNet:'''全连接的多层神经网络hiddenSizeList:隐藏层列表,可以设定为若干个activation:激活函数为relu或sigmoidweight_init_std:权重的标准差(如0.01)指定'relu'或'he'的情况下设定“He的初始值”指定'sigmoid'或'xavier'的情况下设定“Xavier的初始值”weight_decay_lambda:Weight Decay(L2范数)的强度'''def __init__(self,inputSize,hiddenSizeList,outputSize,activation='relu',weight_init_std='relu',weight_decay_lambda=0):self.inputSize=inputSizeself.outputSize=outputSizeself.hiddenSizeList=hiddenSizeListself.hiddenLayerNum=len(hiddenSizeList)self.weight_decay_lambda=weight_decay_lambdaself.params={}self.__init_weight(weight_init_std)#生成Affine层和激活函数层(隐藏层)以及最后的Affine层和Softmax层activationLayer={'sigmoid': Sigmoid,'relu': Relu}self.layers=OrderedDict()for idx in range(1,self.hiddenLayerNum+1):self.layers['Affine'+str(idx)]=Affine(self.params['W'+str(idx)],self.params['b'+str(idx)])self.layers['Activation'+str(idx)]=activationLayer[activation]()idx=self.hiddenLayerNum+1self.layers['Affine'+str(idx)]=Affine(self.params['W'+str(idx)],self.params['b'+str(idx)])self.lastLayer=SoftmaxWithLoss()def __init_weight(self,weight_init_std):'''初始化权重'''allSizeList=[self.inputSize]+self.hiddenSizeList+[self.outputSize]for idx in range(1,len(allSizeList)):scale=weight_init_stdif str(weight_init_std).lower() in ('relu','he'):scale=np.sqrt(2.0 / allSizeList[idx-1])  # 使用ReLU的情况下推荐的初始值elif str(weight_init_std).lower() in ('sigmoid','xavier'):scale=np.sqrt(1.0 / allSizeList[idx-1])  # 使用sigmoid的情况下推荐的初始值#np.random.randn标准正态分布,标准差为scaleself.params['W'+str(idx)]=scale*np.random.randn(allSizeList[idx-1],allSizeList[idx])self.params['b'+str(idx)]=np.zeros(allSizeList[idx])def predict(self,x):for layer in self.layers.values():x=layer.forward(x)return xdef loss(self,x,t):'''求损失函数'''y=self.predict(x)weight_decay=0for idx in range(1,self.hiddenLayerNum+2):W=self.params['W'+str(idx)]weight_decay+=0.5 * self.weight_decay_lambda * np.sum(W ** 2)return self.lastLayer.forward(y,t)+weight_decaydef 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 accuracydef numerical_gradient(self,x,t):'''数值微分求梯度'''loss_W=lambda W: self.loss(x,t)grads={}for idx in range(1,self.hiddenLayerNum+2):grads['W'+str(idx)]=numerical_gradient(loss_W,self.params['W'+str(idx)])grads['b'+str(idx)]=numerical_gradient(loss_W,self.params['b'+str(idx)])return gradsdef gradient(self,x,t):'''误差反向传播求梯度'''# forwardself.loss(x,t)# backwarddout=1dout=self.lastLayer.backward(dout)layers=list(self.layers.values())layers.reverse()for layer in layers:dout=layer.backward(dout)# 设定grads={}for idx in range(1,self.hiddenLayerNum+2):grads['W'+str(idx)]=self.layers['Affine'+str(idx)].dW+self.weight_decay_lambda * self.layers['Affine'+str(idx)].Wgrads['b'+str(idx)]=self.layers['Affine'+str(idx)].dbreturn grads

layers.py(Affine和激活函数Relu,Sigmoid,Softmax)

import numpy as np
from common.functions import *class Relu:def __init__(self):self.mask=Nonedef forward(self,x):self.mask=(x<=0)out=x.copy()out[self.mask]=0return outdef backward(self,dout):dout[self.mask]=0dx=doutreturn dxclass Sigmoid:def __init__(self):self.out=Nonedef forward(self,x):out=sigmoid(x)self.out=outreturn outdef backward(self,dout):dx=dout*(1.0-self.out)*self.outreturn dxclass Affine:def __init__(self,W,b):self.W =Wself.b=bself.x=Noneself.original_x_shape=None# 权重和偏置参数的导数self.dW=Noneself.db=Nonedef forward(self,x):# 对应张量self.original_x_shape=x.shapex=x.reshape(x.shape[0],-1)self.x=xout=np.dot(self.x,self.W)+self.breturn outdef backward(self,dout):dx=np.dot(dout,self.W.T)self.dW=np.dot(self.x.T,dout)self.db=np.sum(dout,axis=0)dx=dx.reshape(*self.original_x_shape)  # 还原输入数据的形状(对应张量)return dxclass SoftmaxWithLoss:def __init__(self):self.loss=Noneself.y=None # softmax的输出self.t=None # 监督数据def forward(self,x,t):self.t=tself.y=softmax(x)self.loss=cross_entropy_error(self.y,self.t)return self.lossdef backward(self,dout=1):batch_size=self.t.shape[0]if self.t.size == self.y.size: # 监督数据是one-hot-vector的情况dx=(self.y-self.t)/batch_sizeelse:dx=self.y.copy()dx[np.arange(batch_size),self.t]-=1dx=dx/batch_sizereturn dxclass Dropout:'''随机删除神经元self.mask:保存的是False和True的数组,False的值为0是删除的数据'''def __init__(self,dropout_ratio=0.5):self.dropout_ratio=dropout_ratioself.mask=Nonedef forward(self,x,train_flg=True):if train_flg:self.mask=np.random.rand(*x.shape)>self.dropout_ratioreturn x*self.maskelse:return x*(1.0-self.dropout_ratio)def backward(self,dout):return dout*self.maskclass BatchNormalization:def __init__(self,gamma,beta,momentum=0.9,running_mean=None,running_var=None):self.gamma=gammaself.beta=betaself.momentum=momentumself.input_shape=None # Conv层的情况下为4维,全连接层的情况下为2维  # 测试时使用的平均值和方差self.running_mean=running_meanself.running_var=running_var  # backward时使用的中间数据self.batch_size=Noneself.xc=Noneself.std=Noneself.dgamma=Noneself.dbeta=Nonedef forward(self,x,train_flg=True):self.input_shape=x.shapeif x.ndim != 2:N,C,H,W=x.shapex=x.reshape(N,-1)out=self.__forward(x,train_flg)return out.reshape(*self.input_shape)def __forward(self,x,train_flg):if self.running_mean is None:N,D=x.shapeself.running_mean=np.zeros(D)self.running_var=np.zeros(D)if train_flg:mu=x.mean(axis=0)xc=x-muvar=np.mean(xc**2,axis=0)std=np.sqrt(var+10e-7)xn=xc/stdself.batch_size=x.shape[0]self.xc=xcself.xn=xnself.std=stdself.running_mean=self.momentum*self.running_mean+(1-self.momentum)*muself.running_var=self.momentum*self.running_var+(1-self.momentum)*var            else:xc=x-self.running_meanxn=xc/((np.sqrt(self.running_var+10e-7)))out=self.gamma*xn+self.beta return outdef backward(self,dout):if dout.ndim != 2:N,C,H,W=dout.shapedout=dout.reshape(N,-1)dx=self.__backward(dout)dx=dx.reshape(*self.input_shape)return dxdef __backward(self,dout):dbeta=dout.sum(axis=0)dgamma=np.sum(self.xn*dout,axis=0)dxn=self.gamma*doutdxc=dxn/self.stddstd=-np.sum((dxn*self.xc)/(self.std*self.std),axis=0)dvar=0.5*dstd/self.stddxc += (2.0/self.batch_size)*self.xc*dvardmu=np.sum(dxc,axis=0)dx=dxc-dmu/self.batch_sizeself.dgamma=dgammaself.dbeta=dbetareturn dx

其中一些方法没有使用到,暂时放出来,后面也将详细专门介绍这些方法,对于如何优化参数都是特别有效的。另外common目录里的functions.py的一些公共函数都在前面有介绍,就不贴出来了,可以参阅Python随机梯度下降法(四)【完结篇】

我们来加载MNIST数据集,此例为三层结构,可以自己随意添加层,类似[80,120,100,100]

import numpy as np
from dataset.mnist import load_mnist
from common.multi_layer_net import MultiLayerNet#读取MNIST数据
(x_train,t_train),(x_test,t_test)=load_mnist(normalize=True)
train_num=x_train.shape[0]#60000张训练数据
batch_num=200#每次随机抽取的数量
max_iter=500#迭代次数
#三层(隐藏层有两层)
networks=MultiLayerNet(inputSize=784,hiddenSizeList=[80,120],outputSize=10)lr=0.1
for i in range(max_iter):batch_mask=np.random.choice(train_num,batch_num)x_batch=x_train[batch_mask]t_batch=t_train[batch_mask]grads=networks.gradient(x_batch,t_batch)#分别将三层的权重和偏置的梯度进行更新for k in ('W1','b1','W2','b2','W3','b3'):networks.params[k]-=lr*grads[k]if i%100==0:print(grads['W1'].shape,grads['W2'].shape,grads['W3'].shape)#(784, 80) (80, 120) (120, 10)print(grads['b1'].shape,grads['b2'].shape,grads['b3'].shape)#(80,) (120,) (10,)print(networks.accuracy(x_train,t_train))

精度(正确率)
0.11478333333333333
0.8880166666666667
0.91055
0.9217666666666666
0.9310666666666667

全连接的多层神经网络结构(MultiLayerNet)相关推荐

  1. 【深度学习】经典卷积神经网络结构说明

    前言   20世纪 90年代,LeCun et al.等人发表一篇关于手写数字识别的论文 [论文PDF下载],论文中使用的网络结果如下: 此网络结构认为是卷积神经网络的开山鼻祖,也确立了CNN的现代结 ...

  2. 【tensorlfow2】安装及简介全连接神经网络

    [tensorlfow]全连接神经网络FC-DNN 文章目录 一.[Win10+Anaconda+Tensorflow2.0安装教程 1.检测已经安装的环境 2.创建tensorflow虚拟环境 3. ...

  3. Pytorch深度学习入门与实战一--全连接神经网络

    全连接神经网络在分类和回归问题中都非常有效,本节对全连接神经网及神经元结构进行介绍,并使用Pytorch针对分类和回归问题分别介绍全连接神经网络的搭建,训练及可视化相关方面的程序实现. 1.全连接神经 ...

  4. 机器学习入门(15)— 全连接层与卷积层的区别、卷积神经网络结构、卷积运算、填充、卷积步幅、三维数据卷积、多维卷积核运算以及批处理

    卷积神经网络(Convolutional Neural Network,CNN)CNN 被用于图像识别.语音识别等各种场合,在图像识别的比赛中,基于深度学习的方法几乎都以 CNN 为基础. 1. 全连 ...

  5. 通俗讲解多层全连接前向网络的基本结构

    通俗讲解多层全连接前向网络的基本结构 1 模拟神经元 2 单层神经网络的分类器 3 激活函数 3.1 Sigmoid 3.2 Tanh 3.3 ReLU 4.4 Leaky ReLU 3.5 Maxo ...

  6. PyTorch基础入门五:PyTorch搭建多层全连接神经网络实现MNIST手写数字识别分类

    )全连接神经网络(FC) 全连接神经网络是一种最基本的神经网络结构,英文为Full Connection,所以一般简称FC. FC的准则很简单:神经网络中除输入层之外的每个节点都和上一层的所有节点有连 ...

  7. cs231n-2022-assignment2#Q1:多层全连接神经网络

    目录 1. 前言 2. 数据加载 3. 实现多层全连接网络 4. Sanity check 4.1 用小数据集训练一个三层网络 4.2  用小数据集训练一个五层网络 5. 更新规则 6. Train ...

  8. 全连接神经网络的BP算法(BP神经网络模型)与卷积神经网络的BP算法

    1.神经网络模型 1.1神经网络模型的演变: 神经元模型------->感知机模型------->神经网络模型 神经元模型:1943年,W.S.McCulloch和W.Pitts根据生物学 ...

  9. 深度学习框架 TensorFlow:张量、自动求导机制、tf.keras模块(Model、layers、losses、optimizer、metrics)、多层感知机(即多层全连接神经网络 MLP)

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 安装 TensorFlow2.CUDA10.cuDNN7.6. ...

最新文章

  1. jqGrid简单使用
  2. Redis 持久化(persistence)
  3. mac php7 mysql 扩展_升级到php7和安装拓展(mac centos)
  4. 骆驼(camel)命名法_Apache Camel 3 –骆驼核心vs骆驼核心引擎(较小的核心)
  5. couchbase_Couchbase 2.0归类视图简介
  6. 给树莓派超频[浙大嵌入式系统]
  7. 使用Keras打造一个实时可用交通标志识别App
  8. TokenInsight作为联盟伙伴加入CoinMarketCap的数据透明联盟(DATA) | TokenInsight
  9. 利用PS和抠图软件轻松换证件照背景
  10. 高中知识三角函数怎么计算机,高中三角函数怎么学 有什么方法
  11. dede服务器建站_新手搭建DeDecms织梦网站的详细操作流程
  12. 对小米路由器提出严正批评,2.4G下,40MHz自动变20MHz
  13. 软考信息安全工程师+2021-01-30 1.网络信息安全概述+重点
  14. 算法快学笔记(十三):狄克斯特拉(Dijkstra)算法原理与实现
  15. Unicable命令设置
  16. python怎么实现打开摄像头_python开启摄像头以及深度学习实现目标检测方法
  17. LFS系统安装镜像制作
  18. 【考研加油】所有上岸的考研人都有一个共同的特点,就是他们都参加考试了。2023考研加油。
  19. 【Java后端】读取文件夹中的图片转成base64编码并写入properties文件
  20. 康普:云时代智能布线多面手

热门文章

  1. git-stash用法
  2. android sdk离线安装
  3. 一本通1594涂抹果酱
  4. 【主席树】bzoj1112: [POI2008]砖块Klo
  5. centos7 挂载镜像盘 LVM处理的不合理
  6. 多校#5-1005-Instring-HDU5785-manacher+维护
  7. 【转载】100多个很有用的JavaScript函数以及基础写法大集合
  8. ubuntu下mysql整个数据库备份与还原
  9. LHF Objective-C语法(7)id类型、动态判断与选择器
  10. 小白设计模式:访问者模式