例子见P37
例:
torch.utils.data.DataLoader(dataset,batch_size=1,shuffle=False,sampler=None, batch_sampler
=None,num_workers=0,collate_fn=
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。
要求图片是下面这种存放形式:
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 回归
定义 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
2.Adadelta
3.RMSprop
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 范数
补充:机器学习中 L1 和 L2 正则化的直观解释
还有一种正则化方法叫做最大范数限制,其迫使权重在更新的过程中范数有一个上界,可以使得当学习率设置太高的时候网络不会"爆炸"
2.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、测试网络