例子见P37
例:
torch.utils.data.DataLoader(dataset,batch_size=1,shuffle=False,sampler=None, batch_sampler
=None,num_workers=0,collate_fn=<function default_collate>, pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None): 自定义数据加载器。组合了一个数据集和采样器,并提供关于数据的迭代器。
dataset (Dataset):需要加载的数据集(可以是自定义或者自带的数据集)。
batch_size:batch的大小(可选项,默认值为1)。
shuffle:是否在每个epoch中shuffle整个数据集, 默认值为False。
sampler:定义从数据中抽取样本的策略. 如果指定了, shuffle参数必须为False。
num_workers:表示读取样本的线程数,0表示只有主线程。
collate_fn:合并一个样本列表称为一个batch。
pin_memory:是否在返回数据之前将张量拷贝到CUDA。
drop_last (bool, optional) :设置是否丢弃最后一个不完整的batch,默认为False。
在torchvision这个包中还有更高级的有关于计算机视觉的数据读取类: ImageFolder要求图片是下面这种存放形式:
root/dog/xxx.png
root/dog/xxy.png
root/cat/ 123.png
root/cat/ 456.png
dset = lmageFolder(root='root_path',transform=None,loader=default_loader)
root是根目录,该目录下有几个文件夹,每个文件夹表示一个类别: transform和 target_transform 是图片增强,之后我们会详细讲;
loader是图片读取的办法,然后通过 loader将图片转换成我们需要的图片类型进入神经网络
优化算法是一种调整模型参数更新的策略,通过修改参数使得损失函数最小化(或最大化)
1. 一阶优化算法
使用各个参数的梯度值来更新参数,最常用的一阶优化算法是梯度下降。梯度下降的功能是通过寻找最小值,控制方差,更新模型参数,最终使模型收敛
网络的参数更新公式
2. 二阶优化算法
使用了二阶导数(也叫做 Hessian 方法)来最小化或最大化损失函 数,主要基于牛顿法,但是由于二阶导数的计算成本很高,所以这种方法并没有广泛使用。
torch.optim 是一个实现各种优化算法的包,大多数常见的算法都能够直接通过这个包来调用,比如随机梯度下降,具体官方实例(在优化之前需要先将梯度归零,即 optimizer.zeros() , 然后通过 loss.backward()反向传播,自动求导得到每个参数的梯度,最后只需要 optimizer. step ()就可以通过梯度做一步参数更新)
使用 torch.save,有两种保存方式: (1) 保存整个模型的结构和参数,保存的对象是模型 model (2) 保存模型的参数,保存的对象是模型的状态 model.state dict()
对应于保存模型,加载模型的方式: (1) 加载完整的模型和参数,使用 load model = torch.load('XXX' ) (2) 加载模型参数,需要先导入模型的结构,然后model.load state dic (torch.load('XXX')) 来导入
二分类算法一一Logistic 回归
非线性变换 Sigmoid 函数是 Logistic 分布函数中 γ=1 ,μ=0 的特殊形式。 Logistic 回归要更进一步,通过找到分类概率 P(Y =1) 与输入变量x的直接关系,然后通过比较概率值来判断类别. Logistic 回归的思路是先拟合决策边界(这里的决策边界不局限于线性,还可以是多项式),再建立这个边界和分类概率的关系,从而得到二分类情况下的概率。模型的参数估计 具体见P44
定义 Logistic 回归的模型
class LogisticRegression(nn.Module) :
self.lr=nn.Linear()
self.sm=nn.Sigmoid ()
criterion = nn.BCELoss ()
optimizer = torch . optim.SGD( logistic_model.parameters () , lr=le-3 ,momentum=0.9 )
训练模型
for epoch in range(50000):
变量转成Variable形式
前向传播:out = model (x) #self.lr=nn.Linear() self.sm=nn.Sigmoid ()
loss = criterion(out , y)
反向传播:optimizer. zero_grad ()
loss.backward ()
optimizer. step ()
简单的一层神经网络的数学形式简单,可以看成一个线性运算再加上一个激活函数(可激活变大/变小),Logistic 回归是使用了 Sigmoid 作为激活函数的一层神经网络
适合用于前向传播(实际基本不用)
Sigmoid 函数有以下两大缺点
( 1 ) Sigmoid 函数靠近1和0的两端会造成梯度消失,梯度下降法通过梯度乘上学习率来更新参数,因此如果梯度接近 0,那么没有任何信息来更新参数,造成模型不收敛
( 2 ) 经过 Sigmoid 激活函数的输出,作为后一层网络的输入是非 0 均值的,若输入进入下一层神经元的时候全是正的,则导致梯度全是正的,在更新参数时永远都是正梯度。
ReLU 的优点:适合用于后向传播
(1)相比于 Sigmoid 和 Tanh 激活函数, ReLU 激活函数可极大地加速随机梯度下降法的收敛速度,这因为它是线性的,且不存在梯度消失的问题
( 2 )相比于 Sigmoid 和 Tanh 激活函数, ReLU 的计算方法更加简单.只需要一个阈值运算就可以得到结果,不需要进行一大堆复杂的运算。
ReLU 的缺点:
训练的时候很脆弱.举个例子:由于ReLU在x<0时梯度为0,这样就导致负的梯度在这个ReLU被置零,那么这个神经元之后的梯度就永远是0了,不再对任何数据有所响应。在实际操作中可以通过设置比较小的学习率来避免这个小问题
4.Leaky ReLU 略
5.Maxout 略
第一个参数代表下一步的位置
第二个参数代表当前位置
α代表学习率,每迈出一步的距离,不能太大也不能太小
代表梯度,损失函数
人工设置学习率
1.SGD 随机梯度下降
每次使用一批 (batch) 数掘进行梯度的计算,而不是计算全部数据的梯度
2.Momentum
相比于标准梯度下降算法,Momentum项能够在相关方向加速SGD,使得参数更新方向更多地沿着横轴进行,抑制振荡,从而加快收敛
3.Nesterov
Momentum加上nesterov项后,梯度在大的跳跃后,进行计算对当前梯度进行校正
自适应学习率
1.Adagrad
适合处理稀疏梯度中后期,分母上梯度平方的累加将会越来越大,使gradient→0,使得训练提前结束2.Adadelta
训练初中期,加速效果不错,很快训练后期,反复在局部最小值附近抖动3.RMSprop
RMSprop算是Adagrad的一种发展,和Adadelta的变体,效果趋于二者之间适合处理非平稳目标对于RNN效果很好4.Adam
这是一种综合型的学习方法,可以看成是RMSprop 加上动量 (Momentum) 的学习方法,达到比 RMSProp 更好的效果。
补充 深度学习最全优化方法总结比较
1.中心化
每个特征维度都减去相应的均值实现中心化,这样可以使得数据变成 0 均值,特别对于一些图像数据.
2.标准化/归一化
有两种常用的方法:StandardScaler:减去均值然后除以方差(或标准差),这种数据标准化方法经过处理后数据符合标准正态分布,即均值为0,标准差为1
MinMaxScaler:将特征缩放到给定的最小值和最大值之间,或者也可以将每个特征的最大绝对值转换至单位大小。
标准化(归一化)两个优点:1)归一化后加快了梯度下降求最优解的速度;
2)归一化有可能提高精度。
经验之谈1)在分类、聚类算法中,需要使用距离来度量相似性的时候、或者使用PCA技术进行降维的时候,StandardScaler表现更好。
2)在不涉及协方差计算、数据不符合正态分布的时候,可以使用MinMaxScaler。比如图像处理中,将RGB图像转换为灰度图像后将其值限定在[0,255]的范围。
3)使用MinMaxScaler,其协方差产生了倍数值的缩放,因此无法消除量纲对方差、协方差的影响,对PCA分析影响巨大;同时,由于量纲的存在,距离的计算结果会不同。
在StandardScaler中,每个维度都是去量纲化的,避免了不同量纲的选取对距离计算产生的巨大影响。
4)若数据包含许多异常值,RobustScaler 对数据的中心和范围使用更有鲁棒性的估计。
针对稀疏矩阵,用MaxAbs
3.PCA(去噪)
数据中心化,用协方差矩阵对数据进行去相关性,投影到一个特征空间,取主要特征向量。
4.白噪声(加噪)
将数据投影到一个特征空间, 然后每个维度除以特征值来标准化这些数据,直观上就是一个多元高斯分布转化到了 一个 0 均值,协方差矩阵为 1 的多元高斯分布 。
3. 4.在CNN中基本不用
1.全 0 初始化
不可取,否则权重相同
2. 随机初始化
经常用,在训练深度神经网络时可能会造成两个问题,梯度消失和梯度爆炸。
梯度消失和梯度爆炸 补充:详解机器学习中的梯度消失、爆炸原因及其解决方法
3. 稀疏初始化
实际较少用到
4. 初始化偏置( bias )
偏置 (bias)通常是初始化为 0
5. 批标准化( Batch Normalization )
效果好,它位于X=WU+B激活值获得之后,非线性函数变换之前
对于每个隐层神经元,把逐渐往非线性函数的取值区间的上下限两端靠近的激活输入分布 强制拉回到 均值为0方差为1的比较标准的正态分布,使得输入值落入非线性函数比较敏感的区域,以此避免梯度消失问题。
具体见 深入理解Batch Normalization批标准化
1.正则化(目的是限制参数过多或者过大,避免模型更加复杂)
L2正则化是正则化(regularization)中比较常用的形式:对于权重过大的部分进行惩罚,让参数更新之后更加靠近0
L1正则化是另一种正则化方法:在损失函数中增加权重的 1 范数
在实际中通常使用 L2 正则化,我们也可以把L1正则化和 L2 正则化结合起来,如 。L1相对于 L2 ,在优化的过程中可以让权重变得更加稀疏,在优化结束的时候,权重只会取一些与最重要的输入有关的权重,这就使得与噪声相关的权重被尽可能降为 0L2 会比L1更加发散,权重也会被限制得更小
补充:机器学习中 L1 和 L2 正则化的直观解释
还有一种正则化方法叫做最大范数限制,其迫使权重在更新的过程中范数有一个上界,可以使得当学习率设置太高的时候网络不会"爆炸"
2.Dropout
在前向传播的时候,让某个神经元的激活值以一定的概率p停止工作, 也就是说每次训练忽略一部分的特征检测器(让一部分的隐层节点值为0)在预测的时候,如果保留所有的权重(预测没办法随机丢弃,若丢弃一些神经元,会带来结果不稳定的问题),每一个神经单元的权重参数要乘以概率p。每一次训练batch,Dropout之后就可以看作是一个新的模型,然后训练了很多次之后就可以看成是这些模型的集成,整个dropout过程就相当于对很多个不同的神经网络取平均
快速回忆版
1、构建好一个神经网络
2、训练网络必须经过4步:
第一步:将输入input向前传播,进行运算后得到输出output
第二步:将output再输入loss函数,计算loss值(是个标量)
第三步:将梯度反向传播到每个参数
第四步:利用公式进行权重更新
细抠代码版
1、搭建网络:
黄字重点2、导入包、定义超参数(如 batch size 、 learning rate 还有 num_epoches)
3、用torchvision.transforms进行数据预处理
4、读取数据集(见1.3)
torchvision.datasets
torch.utils.data.DataLoader。建立数据迭代器
5、导入网络,定义损害函数和优化方法
model = net.Batch_Net(输入图片维度, 隐藏层1 , 隐藏层2, 分类数)
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters() , lr=learning_rate)
6、训练网络
例:for epoch in range(50000):
变量转成Variable形式
前向传播:out = model (x) #self.lr=nn.Linear() self.sm=nn.Sigmoid ()
loss = criterion(out , y)
反向传播:optimizer. zero_grad ()
loss.backward ()
optimizer. step ()
7、测试网络
