Pytorch深度学习

目录

layout: post title: “pytorch深度学习” date: 2021-05-27 description: “”

tag: pytorch 深度学习


概念

  1. 机器学习和深度学习原理:

    image-20210527135302299

    image-20210527141007989

    算法,是基于人类指定规则,

机器学习是Input经过人类手动提取特征(真正的输入x),然后mapping from features是完成y对x的函数映射,output是y

表型学习是features的提取也可以学习,自动提取

​ 深度学习,是把数据输入的最简单特征直接作为输入,然后接入额外的层,提取特征

  1. 维度诅咒:

    image-20210527135452229

    维度越多,对数据需求越大。

    image-20210527135814290

  2. Back Propagation(计算图)反向传播算法

    image-20210527142635540

    image-20210527142726168

    单条路径: e对a的导数,等于a到e路径上所有偏导的乘积,

    多条路径: e对b的导数,等于两条路径偏导乘积的和

  3. 需要线性代数和概率论


线性模型

  1. 准备数据集 dataset

  2. 选择模型model(随机森林、knn)

  3. training

  4. inferring OR predicting

  5. 模型评估–损失loss

    MSE(平均方差损失)

    image-20210527151110358

    image-20210527151913168

    image-20210527152132328

注意:

模型训练过程中实时的画一些可视化图,比如visdom可以实现这个功能。

断点,数据存盘


梯度下降– gradient

  1. 分治的思想,如二分法,求极值,寻找最优值,

  2. 梯度定义:

    image-20210527153832044

    image-20210527154233008

    导数大于0,增函数,说明函数在上升

    学习率表示往前走多远,值应该小一点,每一次迭代都朝着下降最快的反向前进

    收敛: 模型刚开始训练的时候,cost损失会下降的非常快,但是越往后下降的越来越慢,说明模型训练过程趋向收敛。

    image-20210527161844180

    image-20210527162143354

  3. 随机梯度下降

    只需要求一次就可以,随机求一个样本

image-20210527162455662

batch 梯度,兼具时间复杂度和性能


反向传播–back propagation

image-20210527172608219

image-20210527201241425

image-20210527201557574

每一层输出需要加一个非线性的函数,

计算方法:

image-20210527205709717

先前馈计算,源着箭头的方向计算,再反过来计算

image-20210527210806776

pytorch基本类型,Tensor是重要的数据存储单元,包含data(存权重)和grad(损失对权重的导数)

image-20210527211047234

image-20210527211225031

requires_grad默认为FALSE,需要设为TRUE才会计算梯度

w是Tensor矩阵形式,x也要是对应的矩阵,然后转换成计算图的模式

image-20210527211543743

这个代码是在构建计算图

image-20210527211742581

L = loss(x,y), 前馈计算,源着计算线路图计算loss,正向反馈计算损失

l.backward 是反向传播,反向计算计算图中每个变量的导数,并存入变量中,反向传播后计算图会被释放,这里计算w的导数

w.data = w.data - 0.01*w.grad.data

这里需要对data进行操作,grad也是Tensor张量,需要取data,否则张量计算就会生成计算图

l也是张量,不能直接加减

如:sum+=l.item() l是向量

w.grad.data.zero_()对w导数的值清零,如果不清零,第二次会保留w第一次的导数,结果就是两次导数的和


pytorch使用

  1. Tensor 张量

  2. forward

  3. backward

    矩阵乘法,行的每个值乘以另一个矩阵列的每个矩阵的值得和,

    image-20210528223523824

  • 第一步准备数据

    image-20210527221709812

    x、y必须是矩阵

  • 第二部设计模型

    这里的模型(nn.Module)就是计算y_hat

    image-20210528220025843

    image-20210528220238240

  • 构建损失模型和优化器

    image-20210528221357765

    criterion需要参数y_hat和y;MSELoss和SGD都是类,criterion和optimizer都是这些类的一个实例化

    model.parameters(),是调用模型linear.parameters中所有的参数;lr是学习率

  • 训练循环

    前馈(计算损失)、反馈(计算梯度)、更新(梯度下降算法更新权重 )

    image-20210527220525953

    image-20210527221557590

    image-20210528222312464

    1. 先算y_hat
    2. 再算loss
    3. 所有参数梯度归零
    4. 反馈
    5. 更新

    image-20210528222900136

    image-20210528222651087

    说明99次的时候,模型损失0.25,模型未收敛,效果不理想

    999次时,模型收敛

    模型不是训练越多越好,训练过多可能过拟合,在训练集上表现很好,但是在开发集的验证集上,损失反而上升,所以训练过程中需要关注开发集中损失有无上升

    image-20210528223341977


逻辑回归–分类问题

  1. 官方提供的一些流行的数据集–torchvison包

    image-20210528224700690

    回归问题是关心最后考试能拿多少分,计算一个结果。

    而回归问题关心能否通过考试,类别的概率的分布(通过与不通过),二分类问题,只用算一个类别的概率。因为两个类别的概率和必须为0,P(y_hat = 1)

  2. 逻辑回归原理

    image-20210528230955370

    线性回归预测的结果值域是实数范围,而分类的概率值域是[0,1]的区间,需要把预测是实数值映射回[0,1],所以用到了上面的函数

    image-20210528230742156

    image-20210528232008312

    饱和函数:导函数大于0时,导数越来越小,趋于0

    逻辑回归函数的导数接近于正太分布

    逻辑回归函数可以保证值域在0~1之间

    image-20210528232259860

    最终损失函数不是比较坐标轴中值得差异,而是概念分布的差异

    cross-entropy交叉熵


多维数组

  1. 多维数组: 即有多个特征,多个变量x

  2. mini batch

    image-20210530204045212

    计算多维线性回归z的方法,矩阵运算

  3. 空间转换

    image-20210530205042849

    x是n维空间的任一向量,然后乘以A之后结果是m维度的空间里面,那么所乘矩阵是m*n的矩阵,它表示从n维空间映射回m空间的线性变换,矩阵是一种空间变换的函数

    image-20210530205408893

    这个的意思是把任意8维空间的向量映射到一个成2维空间上,这里做一个线性映射。

    但是我们经常要做的空间变换中,可能不一定是线性的,可能是一些非常复杂的非线性,所以我想用多个线性变换层,通过找到最优的权重,把他们组合起来,来模拟这种非线性的变换,神经网络本质是寻找一种非线性的空间函数

    image-20210530223227271

    sigema可以把线性函数转换成非线性函数

    深度神经网络中神经层数越多,学习效果很好,学习能力越好,但是并不是精度越高越好,精度太高也会把噪声学习,造成过拟合,所以模型需要泛化能力

    读文档能力,基本架构能力(微机原理、cpu),开发的核心能力,这种方法泛化能力,将来遇到新的编程语言,可以快速读文档,快速上手。

    image-20210530225044679

    分多个层一步步降为,而不是直接从n维降到1维,可以找到更好的特征,层数越多,非线性越强,可以更好的学习分布。

    image-20210530225630933

    np的loadtxt可以直接读入gz压缩文件;一般神经网络使用的是32位的浮点数,由于显卡的限制

    这里[-1]拿出来的是矩阵,如果不加[]拿出来的是向量,计算的时候都要死矩阵,不能是向量

    image-20210530230111075

    这里变量x都一直用一样的,方便调试,不容易出错,这里第一个x相当于是O1


加载数据集

Dataset和DataLoader

  1. DataLoader是给数据集增加索引,方便拿取mini-batch的数据(也就是整个数据集中取部分用于训练,提高精度和效率,一般随机梯度下降,对于单个样本训练效果会最好,会获得比较好的随机性,帮助我们跨过鞍点,但是效率很低,对于整个数据集(一个batch)进行操作,很快,但是精度差),mini-batch均衡性能和效率的需求。

  2. mini-batch

    image-20210530232302900

    训练循环包含两重循环,第二层(内层)是mini-batch,外层是把所有mini-batch循环都跑一遍

    Epoch

    就是所有训练数据的一次前馈传播和一次反馈传播,也就是说把所有的样本都参与了一次训练

    Batch-Size

    每次训练的时候用的样本数量

    Iterations

    batch一共分了多少个,即内层跌代一共执行了多少次

    image-20210530233027067

    shuffle = True,每次训练的mini-batch使用的数据都是打乱顺序随机选择的

    image-20210530233515785

    先shuffle打乱样本顺序,然后loader分组,这里batch-size=2,就两两分组

    image-20210530233553725

    Dataset是抽象类,它不能被实例化,只能被其他类继承;Dataloader可以实例化

    _getitem_作用,增加索引,支持下标操作;len支持数据条数返回

    image-20210530234316192

    数据集如果本身不够大,可以使用第一种方式,一次性读入内存,

    如果数据集很大,可以把数据集的文件名放到一个列表里

    image-20210530235036511

    这里因为数据集很小,所以,直接把x_data,y_data直接加载到内存中,return x,y 返回(x,y)的元组

    image-20210531135542456

    image-20210531140927472

    image-20210531141657131

    练习

    image-20210531141851174


## 多分类问题–softmax layer

image-20210531142341061

输出的每个值的概率需要满足:P>0; sum(P)=1

线性变换后的值有正有负,怎么通过变换都变成[0,1];

如何变换是和为1

image-20210531142703783image-20210531143347677

image-20210531143513977

只有一步做softmax变换

2.计算损失函数–交叉熵 cross entropy

image-20210531144022850

Loss(Y_hat, Y) = -YlogY_hat

image-20210531144939240

image-20210531144918422

注意: 交叉熵损失,最后一步不需要做非线性变换,直接交给交叉熵损失就可以

image-20210531145245724

python读入图像使用pillow

深度神经网络对于图像训练要求,图像需要转换成图像张量,像素值在-1~1之间,满足正态分布

image-20210531150527636

图像张量,单通道和多通道;pytorch需要将图像从W* H * C转换成C * W * H方便深度神经网络更高效操作图像

image-20210531150706551

首先将pixel从[0,255]压缩到[0,1]; 然后将图像从单通道转换成多通道

归一化:

image-20210531151018416

四六级成绩,先把成绩映射到了0~1分布里面

  1. 准备数据集

    image-20210531151334685

  2. 设计模型

    image-20210531151736757

    首先需要把1* 28 * 28的三阶张量变成一阶的向量;变换方法,把图像的每一行拼起来,这一行共有784个元素

    view是改变张量的形状

    image-20210531152332480

    注意:最后一层不做激活

  3. 优化器

    image-20210531152512609

    增加了冲量,相当于惯性,下山时速度更快

  4. 训练

    image-20210531152642518

    optimizer.zero_grad()优化器使用之前应该先清零

    取loss值时需要使用loss.item()

  5. 测试

    image-20210531153032819

    torch.no_grad(),test不需要计算梯度

    需要把每行最大值的下标拿出来