长宁区网站建设网页,wordpress 漏洞 2014,武隆网站建设公司,苏州交通网站建设一、神经网络
神经网络神经网络#xff08;Neural Networks#xff09;是一种模拟人脑神经元网络结构的计算模型#xff0c;用于处理复杂的模式识别、分类和预测等任务。
人工神经元是神经网络的基础构建单元#xff0c;模仿了神武神经元的工作原理#xff0c;核心功能是…一、神经网络
神经网络神经网络Neural Networks是一种模拟人脑神经元网络结构的计算模型用于处理复杂的模式识别、分类和预测等任务。
人工神经元是神经网络的基础构建单元模仿了神武神经元的工作原理核心功能是接收输入信号经过加权求和和非线性激活函数处理后输出结果。
人工神经元 输入神经元接收多个输入每个输入有一个对应的权重。加权求和计算输入的加权和添加偏置项。激活函数对加权和结果应用激活函数引入非线性能力。 神经网络结构 输入层接收数据不进行计算。隐藏层提取特征通过多层堆叠实现复杂变换。输出层生成预测结果或分类。 全连接网络 每层神经元与上一层的所有神经元相连。常见问题参数量大容易过拟合对高维数据局部特征捕捉能力差。
先说一下参数的初始化对于线性回归模型来说在进行正向传播时不能缺失的值有构成前向传播方程的偏置和权重这两个值而对于输入层来说就是传入y w*xb中的x而为了方便传播在输入层中就会将传入的x引入这个方程来进行定义的线性变换但是输出层只负责最简单的线性变化。
在这个线性变化过程中就有一个问题这个方程中的w和b哪里来
由于之前学过线性回归的时候我们知道这个前向传播的方程是为了算出预测值来与实际数据进行损失计算然后通过反向传播来更新梯度值进行简单的梯度下降来逼近我们希望求得的权重和偏置所以输出层的权重和偏置是由我们自定义的而torch中就提供了很多种初始化的方法。接下来说几个例子。
全零初始化
因为会破坏对称性一般治用于初始化偏置
import torch
import torch.nn as nndef test():linear nn.Linear(in_feature6,out_feature4)nn.init.zeros_(linear.weight)print(linear.weight)if __name__ main:test()然后还有全1初始化就没必要再写一遍了。
任意常数初始化
import torch
import torch.nn as nndef test002():# 2. 固定值参数初始化linear nn.Linear(in_features6, out_features4)# 初始化权重参数nn.init.constant_(linear.weight, 0.63)# 打印权重参数print(linear.weight)passif __name__ __main__:test002()
防止了参数为0的情况出现但是运用在权重上依旧避免不了破坏对称性的问题。
随机初始化
最基本的初始化方式避免破坏对称性
import torch
import torch.nn as nndef test001():# 1. 均匀分布随机初始化linear nn.Linear(in_features6, out_features4)# 初始化权重参数nn.init.uniform_(linear.weight)# 打印权重参数print(linear.weight)if __name__ __main__:test001()
Xavier初始化
也叫做Glorot初始化。
方法根据输入和输出神经元的数量来选择权重的初始值。权重从以下分布中采样 W ∼ U ( − 6 n i n n o u t , 6 n i n n o u t ) W\sim\mathrm{U}\left(-\frac{\sqrt{6}}{\sqrt{n_\mathrm{in}n_\mathrm{out}}},\frac{\sqrt{6}}{\sqrt{n_\mathrm{in}n_\mathrm{out}}}\right) W∼U(−ninnout 6 ,ninnout 6 ) 或者 W ∼ N ( 0 , 2 n i n n o u t ) W\sim\mathrm{N}\left(0,\frac{2}{n_\mathrm{in}n_\mathrm{out}}\right) W∼N(0,ninnout2) N ( 0 , std 2 ) N ( 0 , std 2 ) \mathcal{N}(0, \text{std}^2)\mathcal{N}(0, \text{std}^2) N(0,std2)N(0,std2)
其中 n in n_{\text{in}} nin 是当前层的输入神经元数量 n out n_{\text{out}} nout是输出神经元数量。
优点平衡了输入和输出的方差适合Sigmoid和 Tanh 激活函数。
应用场景常用于浅层网络或使用Sigmoid、Tanh 激活函数的网络。
import torch
import torch.nn as nndef test007():# Xavier初始化正态分布linear nn.Linear(in_features6, out_features4)nn.init.xavier_normal_(linear.weight)print(linear.weight)# Xavier初始化均匀分布linear nn.Linear(in_features6, out_features4)nn.init.xavier_uniform_(linear.weight)print(linear.weight)if __name__ __main__:test007()
二、激活函数
就我自己的理解来是进入每个神经元时就是一次线性变换再输出给下一个神经元的时候则是通过非线性变化的激活函数来提高数据的分离度而如果不设置激活函数也是能传递的只是他始终进行的线性的变化而线性数据的一个缺点就是无法表示复杂的非线性的关系如异或问题。而引入激活函数的优点还有
通过升维来提取更改层次的抽象特征控制输出值的范围稳定梯度传播动态调整神经元的激活状态增强表达能力实现逼近任意复杂函数的能力
下面是常用的激活函数
常见激活函数 Sigmoid将输出映射到 (0,1)(0, 1)(0,1)适合二分类输出层易出现梯度消失。Tanh将输出映射到 (−1,1)(-1, 1)(−1,1)适合隐藏层梯度较大缓解梯度消失问题。ReLU输出正值本身负值为零计算简单适合深层网络存在神经元死亡问题。Leaky ReLU改进 ReLU为负值引入小斜率避免神经元死亡。Softmax将输出映射为概率分布适合多分类任务的输出层。 选择建议 隐藏层优先选择 ReLU 或其变体。输出层根据任务选择二分类用 Sigmoid多分类用 Softmax回归任务用线性激活。
由于激活函数的公式过多就不说了。
三、损失函数
这里的损失函数与之前学习反向传播时的概念无差异只是根据不同的任务推出了不同损失函数去更好的适配这些任务的回归。 线性回归损失 MAE平均绝对误差对异常值鲁棒。MSE均方误差对大误差敏感。Smooth L1结合 MAE 和 MSE 的优点平滑过渡。 分类损失 交叉熵损失 多分类问题与 Softmax 搭配。衡量预测分布与真实分布的差异。 二分类交叉熵 二分类问题与 Sigmoid 搭配。用于衡量模型对两个类别的预测效果。 总结 回归任务MSE、Smooth L1。二分类任务Sigmoid 二分类交叉熵。多分类任务Softmax 交叉熵。
反向传播的api实现
由于上面所有的都是为了反向传播而服务所以单论以上的所有都是理论上的只有在神经网络中实现反向传播才会真正的运用到上面所有的知识。
import torch
import torch.nn as nn
import torch.optim as optimclass Net(nn.Module):def __init__(self):super(Net, self).__init__()self.linear1 nn.Linear(2, 2)self.linear2 nn.Linear(2, 2)# 网络参数初始化self.linear1.weight.data torch.tensor([[0.15, 0.20], [0.25, 0.30]])self.linear2.weight.data torch.tensor([[0.40, 0.45], [0.50, 0.55]])self.linear1.bias.data torch.tensor([0.35, 0.35])self.linear2.bias.data torch.tensor([0.60, 0.60])def forward(self, x):x self.linear1(x)x torch.sigmoid(x)x self.linear2(x)x torch.sigmoid(x)return xif __name__ __main__:inputs torch.tensor([[0.05, 0.10]])target torch.tensor([[0.01, 0.99]])# 获得网络输出值net Net()output net(inputs)# 计算误差loss torch.sum((output - target) ** 2) / 2# 优化方法optimizer optim.SGD(net.parameters(), lr0.5)# 梯度清零optimizer.zero_grad()# 反向传播loss.backward()# 打印(w1-w8)观察w5、w7、w1 的梯度值是否与手动计算一致print(net.linear1.weight.grad.data)print(net.linear2.weight.grad.data)#更新梯度optimizer.step()# 打印更新后的网络参数print(net.state_dict())这个程序中没有用到上面说到的这些初始化而是自定义传参初始化。