赞
踩
课程链接:Python人工智能20个小时玩转NLP自然语言处理【黑马程序员】_哔哩哔哩_bilibili
目录
参考神经网络——最易懂最清晰的一篇文章_illikang的博客-CSDN博客_神经网络
典型的神经网络包含三层:输入层、输出层、中间层(隐藏层)。输入输出层一般是固定的,中间层可以自由指定。拓扑与箭头表示预测过程中数据的走向。需要训练的是肩头上的权重,即连接线的权值。
神经网络基于神经元模型,几个输入通过不同权重求和,经过一个非线性函数输出。箭头表示值的加权传递。
这个基础的MP模型中最终输出的是sgn函数,即0或1。在完整的神经元中,将sum与sgn统一到一个函数中,且允许多个输出。后续的研究主要针对于特征与目标之间关系的权值。
为权值附上角标,得到下面的图
类似于线性方程组形式得到输出可以改写成:z=g(W*a),即神经网络中前一层计算后一层的矩阵运算。
除去输出层之外,都设定一个偏置单元,要求只含有储存功能,且储存值永远为1。偏置单元与后一层的所有节点都连接,但是一般不会画出来
定义损失函数,要求所有训练数据的损失最小化。但是需要注意的是,机器学习中优化只是很小的一部分,更重要的是学习而不是优化,要求保证泛化能力。
CNN(Conventional Neural Network,卷积神经网络)
RNN(Recurrent Neural Network,递归神经网络)
在两层神经网络的输出层后面,继续添加层次。原来的输出层变成中间层,新加的层次成为新的输出层。所以可以得到下图。
依照这样的方式不断添加,我们可以得到更多层的多层神经网络。公式推导的话其实跟两层神经网络类似,使用矩阵运算的话就仅仅是加一个公式而已。
在已知输入a(1),参数W(1),W(2),W(3)的情况下,输出z的推导公式如下:
神经网络的每一个神经元如下:
wx + b的形式,其中
因此有:
因为没太弄清楚卷积和池化所以问了朋友:
激活函数一开始是线性函数g(z)=g(w1x1+w2x2+b),b表示调整作用的偏置项。后引入非线性激活函数sigmoid函数:
z表示w1x1+w2x2+b或者其他线性组合,其图像表示如下( 横轴表示定义域z,纵轴表示值域g(z) ),即将一个实数压缩到0,1空间中,也就是说,sigmoid函数的功能是相当于把一个实数压缩至0到1之间。当z是非常大的正数时,g(z)会趋近于1,而z是非常小的负数时,则g(z)会趋近于0,由此就可以把激活函数堪称一种分类正负样本的概率。
例如,在两个样本的分类问题中,通过设定合适的sigmoid函数使得只有和都取1的时候,g(z)→1,判定为正样本;或取0的时候,g(z)→0,判定为负样本,如此达到分类的目的。
还有常用的非线性激活函数有sigmoid、tanh、relu等等。
卷积神经网络在图像识别问题中将图像分割为多个小块,并分别进行匹配。
卷积,即对图像(不同的数据窗口数据)和滤波矩阵(一组固定的权重:因为每个神经元的多个权重固定,所以又可以看做一个恒定的滤波器filter)做内积(逐个元素相乘再求和)
理解起来,w1x1+w2x2+b就是一个滤波器。多个滤波器叠加就是卷积层。使用不同的滤波器进行图像处理,则可以得到不同的颜色深浅、轮廓数据等输出数据。
实际梯度下降中,sigmoid容易饱和、造成终止梯度传递,且没有0中心化。
激活函数:ReLU收敛快,作为激励层
池化层是取小块区域的平均或者最大,来缩小数据(下图取最大)
主要使用的包:torch.nn 构建子模块的包都在其中,以来auto grad自动求导
其中比较重要的是Conv2d函数,用来实现2d卷积操作,其输入参数如下:
Conv2d函数要求批次样本输入,不接受单一样本,要求4DTensor,形状为(nsamples,nchannels,height,width)。单一样本需要扩充,设置nsamples为1
- import torch
- import torch.nn as nn
- import torch.nn.functional as F
-
- #定义一个简单的网络类(一个初始化函数+一个前向包裹函数+维度扁平化)
- class Net(nn.Module):#所有的类的定义都继承nn.Module
- #一共定义两个卷积层
- def__init__(self):
- super(Net,self).__init__()#首先定义初始化函数
- #第一层卷积网络,输入维度1,输出维度6,卷积核3*3
- self.conv1=nn.Conv2d(1,6,3)
- #第二层卷积网络,输入维度6,输出维度16,卷积核3*3(2的输入就是1的输出)
- self.conv2=nn.Conv2d(6,16,3)
- #定义三层全连接层
- self.fc1=nn.Linear(16*6*6,120)#未来输入的图片是32*32,需要推导
- self.fc2=nn.Linear(120,84)
- self.fc3=nn.Linear(84,10)
-
- #前向传播
- def forward(self,x):
- #在(2,2)池化窗口下执行最大池化操作
- #在第一个卷积层下relu且2*2池化
- x=F.max_pool2d(F.relu(self.conv1(x)),(2,2))
- #在第二个卷积层下relu
- x=F.max_pool2d(F.relu(self.conv2(x)),2)
- x=x.view(-1,self.num_flat_features(x))#减少了一个张量的维度
- #num_flat_features表示卷积后的张量x计算size,见下
- #在一二全连接层中relu,并在第三层输出
- x=F.relu(self.fc1(x))
- x=F.relu(self.fc2(x))
- x=self.fc3(x)
- return x
-
- def num_flat_features(self,x)
- #计算size,第零个维度上的batch_size(一次训练所抓取的数据样本数量)不计算
- size=x.size()[1:]#取后两位
- num_features=1
- for s in size:
- num_features*=s
- return num_features
-
- net=Net()#实例化
- print(net)
- output=net(input)
- #模拟十个标签
- target=torch.randn(10)
- #变成二维张量
- target=target.view(1,-1)
- #计算均方差损失模拟差距
- criterion=nn.MSELoss()
- #预测值和真实值之间的差距
- loss=criterion(output,target)
- print(loss)
- #注意在反向传播之前需要将梯度首先清零
- net.zero_grad()
- #先打印第一个卷积层偏置清零前的数据
- print("conv1.bias.grad before backward")
- print(net.conv1.bias.grad)
- #反向传播(就是这一句)
- loss.backward()
- print("conv1.bias.grad after backward")
- print(net.conv1.bias.grad)
随机梯度下降SGD(weight=weight-learning_rate*gradient)
- learning_rate=0.01#超参数
- for f in net.parameters():#遍历所有参数
- f.data.sub_(f.grad.data*learning_rate)#就地减法替代
- import torch.optim as optim
- #有一个包提供常见的优化算法SGD、Adam等
-
- #创建优化器优化的对象,就是网络中所有可训练参数net.parameters()
- #lr设置初始学习率
- optimizer=optim.SGD(net.parameters(),lr=0.01)
-
- #注意三步走:梯度清零zero_grad(),反向传播backward(),参数更新step()
-
- #优化器首先清零
- optimizer.zero_grad()
- #输入
- output=net(input)
- loss=criteron(output,target)
- #执行反向传播
- loss.backward()
- #进行参数更新!!!
- #optimizer.step()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。