pytorch深度学习

本文详细介绍了PyTorch中的张量数据类型、操作以及在GPU上的使用,包括类型推断、损失函数、张量的索引与切片、维度变换等。此外,还讲解了卷积神经网络和循环神经网络的基本原理,以及在实际应用中的数据增强和时间序列预测。
摘要由CSDN通过智能技术生成

回归问题

分类问题(手写数字识别)

基础知识

张量数据类型

python和PyTorch类型对应

但是String在PyTorch中是没有对应的,可以有以下两种方法,一是用onehot编码代替,比如分类猫和狗 【1 0 】代表狗,【0,1】代表猫;第二中在NLP中常用的glove等。

但是这里也要注意,即使是同一个数据,被放在CPU和GPU上的数据类型也是不一样的。

1. 类型推断

2. dim=0的标量

loss通常就是一个标量

3. dim=1的张量

也可以从numpy引入

dim(维度)=1的张量通常用于bias

怎么区分开shape,dim,size?

比如有一个张量

[1,2,5

3,4,9],

dim就是行和列两个维度,dim=2;但是size/shape就是[2,3],代表的是形状

4. dim=n的张量

三维适合RNN的文字处理

四维适合图片类型

(2,3,28,28)对应(b,c,h,w),b是batchsize,c是channel,h是height,w是width。

numel即number of element=2328*28=4704

创建Tensor

大写Tensor和小写tensor,区别
从numpy导入
从list导入
empty()
set default type
rand/rand_like,randint

随机初始化tensor

正态分布构造  randn
full构造
arange/range
linspace/logspace

切割

ones/zeros/eye

随机打散,这啥意思,不懂啊

randperm

是把索引随机打散,下面10,就是把0到10随机打散

索引与切片

如何对tensor索引

高级索引方式,连续选取

冒号

可以看成箭头

-1就是从最后一个索引位置开始

隔行索取,有2个冒号出现,后面一个是步伐,其实通用形式就是start:end:step

 index_select

若给了具体的索引

...

表示任意多的维度,其实就是简化一些     :,:,

mask_select

使用掩码索引,有弊端:会把数据默认打平,故不常用

下面就是把大于0.5的变成1,再用masked_select提取出来

take函数

还有一种也是打平,用的也不多

维度变换

View reshape

数据的储存/维度顺序非常重要!!!如上22,23,24行,如果恢复错误则出现混乱,这是view的致命缺点:把维度顺序丢失

Squeeze v.s. unsqueeze

挤压和展开

unsqueeze!!!

用于插入

0表示在0位置之前插入,-1表示在-1位置之后插入

正数插在前,负数插在后

下面是个好例子

要把b加到f上,先要让它们维度一致,给b插入维度

在新的上面插入,维度一致后再扩张,后续讲到

Squeeze

squeeze(参数),不加参数就把能挤压的全部挤压

13.14行,因为1位置是32不是1,无法挤压,返回原来的

Expand/repeat

二者都扩展维度,expand只在需要的时候同时扩展数据,repeat实实在在把数据复制和扩展进来

因此推荐使用expand,不占内存

原来size不为1想扩展到别的size是没办法的,只能由1->N

-1表示这个维度的size不变,12和13行是bug但在最新版本已经被修复

repeat函数,数字表示在该维度上重复的次数

矩阵转置 
a.t()  只适2D(矩阵),否则会报错
Transpose

view会导致维度关系变模糊,所以需要人为跟踪,contiguous函数使内存顺序变得连续,重新申请一片内存再复制过来

permute

[b,c,h,w]-->[b,h,w,c]

[b,h,w,c]是numpy存储图片的格式,需要这一步才能导出numpy

可以用transpose,但是可以看出很麻烦

14,15行,现在的1位置放放原来的2位置,以此类推

Broadcasting自动扩展

 手动插入,先插小维度

如下,2和3

broadcasting可以直接让2个不同shape的tensor相加,同时省下了大量内存消耗

如下,给4个班,32个学生,8门课的分数都+5分

如果用unsqueeze和expand很麻烦,但直接用broadcasting很快

小维度指定,大维度随意,指定每一门课都加5分,前面没有?话意味着对大维度也适合,即对每个班级下每个学生都适合:每门课加5分

下面有误,【4,32,8】

也可以指定只对英语科目加5分,给出小维度的8

如果给出1就是对所有科目

左下给出4,只给出4门课的指定,无法broadcasting

如下,对4张图32个通道都使用,自动插入1,把【14,14】的数据叠加上去

,下面不符合使用broadingcast,要使用手动

其实就是给出某维度上的1就是都适用去加相同的数据的意思,给出某维度上的全部size就是按照指定的加,已理解

要么给出1,要么给出维度上的最大size

合并与分割(拼接与拆分)

cat

在非cat的维度上的size要一样,例如

stack

与cat不同的是会创造新的维度,给出的两个tensor形状必须一模一样,然后在给出的dim前面插入新的维度,size为2

例如两个班级,a:[32,8]  表示32个学生,8门课程,b:[32,8] 表示32个学生,8门课程;

但是cat的话,就是[64,8],班级的维度就没了

于是stack,就是[2,32,8],下标[0表示a班,[1]表示b班

cat v.s stack

split

根据长度来拆分,c.split([a,b],dim=0),表示0维度上拆分成长度为a的一份和长度为b的一份,只有一个数字就是均分

chunk

按照数量拆分

bac拆分成2份

数学运算

basic

+-*/对应函数add,sub,mul,div,本质是一样的

/表示除法,//表示整除

matmul

矩阵相乘,也可以用@符号

把a降维[4,784]->[4,512]

若对4维度进行相乘,mm会报错

matmul会对后面两个维度进行相乘

15,16会进行broadingcast后再相乘,但是18,19不会,于是报错

power

次方运算

exp log

log默认以e为底,要以10为底就是log10

近似

向下取整,向上取整,拆成整数和小数部分

round四舍五入

clamp

裁剪功能

梯度的模:w.grad.norm(2)

clamp(10)就是要求里面最小的是10,就会把小于10的变为10

统计属性

norm

范数,

1范数,所有元素绝对值求和;2范数,所有元素绝对值的平方求和再开根号

取哪个维度的范数,取完后的形状这个个维度就会消掉?

mean,sum,min,max,prod,argmax,argmin

prod是累乘

argmax和argmin返回索引

(首先会先打平再得出索引!如下12行得出7而不是[1,3])

若argmax(参数给出维度),就是在某个维度的最大值

如下右边,12行输出:给出1dim上的索引,即每行最大值给出列索引

4张照片,每张照片10个prediction,给出每张照片最大prediction的索引

argmax(dim=1)会输出4个索引

argmax(dim=0)会输出10个索引

dim,keepdim

max不仅会返回索引,还会返回值,比argmax多一个功能

如果不keepdim,返回[4],维度为1

keepdim则返回[4,1],维度还是2

top-k  or k-th

比max返回更多

a.topk(3,dim=1)表示返回最大的前3个,把largest=False就是返回最小

a.kthvalue(8,dim=1)表示返回第8小的

compare

gt也表示>0

eq,都是对4行10列中的每一个元素进行逐一比较

equal是对整个进行 比较2个tensor是否完全相同,返回ture或false

高阶操作

where

for语句是在cpu上运行的,我们用where就能在gpu上运行,实现并行处理

gather

其实就是一个查表的操作,看右边板书好理解

例子,gathe使用完成了从retrieve到globel的映射

搜索一些东西,long()

梯度

什么是梯度

梯度是一个向量,向量的长度(模)表示函数增长速度,方向表示在当前点最快的增长方向

我们常用梯度来搜索极小值

凸函数,可以找到全局最优解

从不同位置初始化可能得到不同的局部最优解

resnet56很好解决了掉入局部最小值的情况,loss变平滑,更快找到全局最小值,网络可以迭得很深而且很好的优化

鞍点,在一个位置

还有几种影响因素

如何逃出局部极小值,添加一个动量(惯性)!可以理解为惯性使其冲出局部最小值

常见函数的梯度

就是求偏微分,很简单

激活函数与loss的梯度

激活函数

sigmoid函数

连续,光滑,压缩在0到1之间

代码实现

torch.nn.functional as F!!!

Tanh

在RNN网络中用的比较多

Relu

最常用,deep Learning

因为导数计算简单,x>0时就是1,适合寻找最优解

不会出现梯度离散和梯度爆炸的情况

loss及其梯度

MSE

均方差

F.mse_loss(predict,label),完成动态图的建图

autograd.grad

会报错是因为没有设置w是需要求导的

可以像22行那样对w参数进行更新,注意最后的_,告诉系统w是需要梯度的

也可以在定义的时候就给出w需要梯度信息:w=torch.full([1],2,require_grad=Ture)

loss.backward

使用后会对需要求导的参数求导,使用w.grad即可调用

自动求导api
Softmax激活函数

求导

当i=j时

当i !=j时

结论

p.backward(retain_graph=Ture)只会保持一次,第二次再使用会报错,应该再设置一次

无论是grad函数还是backward函数,传入的loss一定是dim=1的[1],或者dim=0的数

所以不能把整个p传入求导,可传p[1],或者p[2]

感知机的梯度推导

单输出感知机

上标表示层,下标表示节点

最终结果,很简洁

多输出感知机(全连接输出层)

共有N*M个梯度

链式法则

验证链式法则成立

MLP反向传播

最终结果

总结

对于任何一层的偏微分式子就可以通过输出层的δ慢慢反推

优化问题实战

2D函数优化实例

2元函数可以画图,其实是不必要的,从图中可以看出初始值

实战

Logistic Regression

二分类

多分类

需要激活函数,让输出具有概率特征,并且导数像sigmoid函数一样有一定的特征

交叉熵

与softmax匹配的loss,适用于分类问题

就是信息量,越确定的事情信息量越小,越不确定的事情信息量越大

entropy是单个事件

cress entropy是两个事件,Dkl是KL Divergence,即散度

于是就可以用交叉熵来作为loss

对于二分类问题

举例,说明越接近的两个向量,交叉熵越小

交叉熵和MSE其实各有优缺点,MSE的梯度计算比交叉熵简单 

但对于分类问题使用交叉熵 

注意:pytorch中已经将softmax和交叉熵计算打包在一起,所以使用的时候如下图

要么用41行的形式,要么用42行,注意传入参数

网络构建

全连接层

 初级方法

若loss长时间不更新:梯度迭代出问题

检查以下几种地方:激活函数,初始值设置有问题

总结

高级方法

总结

对比

激活函数与gpu加速

以下当x趋于无穷梯度为0,会出现梯度离散现象

右边梯度为1,性质好,不会出现梯度离散,但也有可能出现在x<0时

于是出现

Leaky ReLu

SELU

由两个函数的合并,目前很少很少用到

softplus

时relu函数在0附近平滑处理,也用的很少很少

GPU accelerate

.to方法

测试,计算accuracy

如何test,计算accuracy

Visdom可视化

tensor丢到cpu上再转换为numpy才能做这样的可视化

visdom可以直接接受tensor,还有各种功能

打开监听功能,复制链接到网页,不能关闭

对于image可以直接接受tensor,对直线类型还是接受的numpy数据?

append表示连续画点,刷新率很快,大概一秒一次

想同时看多个数据这样

可视化功能

过拟合和欠拟合

给一个误差

现在我们来选择一个模型去测量

衡量模型的学习能力?

次方越高,模型表达能力越强   model capacity

但是参数越高,学习能力越强,占内存越大

举例

underfitting

以下,模型表达能力不够,复杂度较低

overfitting

过分考虑极端点,模型复杂度太高,更接近于每一个点,可能train得很好,但是test的时候不好

泛化能力也变差

总结

现实情况更多的是overfitting,两种fitting都是对于给定数据集而言,当数据集足够多的情况下可能就不会over fitting

我们要做的事情是如何检测和消除overfitting

交叉验证(划分train和test)

如何检测呢

划分,两个部分的分布肯定是一样的

根据test_loss的情况判断是否overfitting,一般选取testaccurancy最高的点停止,选取这点的状态作为模型参数最佳状态

下图就是再5位置之后过拟合了,最佳状态会被保存,再往后发现确实过拟合了,就将最佳状态作为模型参数

val set

新增的set

防止过拟合的功能交给了val set,一般test set在客户手中你不知道,防止你作弊,过拟合

test set完全只是 单纯用来测试,如果用test测试的数据来反挑选模型,叫做数据污染,用人为想法去得到参数

如何划分呢,

左边60k随机切割用来train和validation

Regularization

使参数的范数趋近0,会得到更低复杂度的模型,防止overfitting

低维参数足够表达,高维度参数会很小,使模型泛化

代码实现

如果没有over fit ing却设置了regularzition,会使模型变差

动量与学习率衰减

当前的更新方向加上上一次的更新方向

momentum参数数值表示考虑多少的历史方向

帮助逃脱局部极小值

但是不理想的情况,可能导致更新得很慢

代码实现

有的优化器不需要额外管理momenteum,如adm,它自带

关于learning rate,使其动态更新,就可以在短时间内达到最低点

在平坦的地方减小lr

另外一种学习率监听

Early Stop,dropout,SGD

dropout

每次断掉一些连接,有一定概率,不是真实的减少

代码实现

这是在两层之间实现随机断开,不是在线性层内部

dropout_prob是断掉的概率,keep——prob是保持的概率,使用这两种的时候不要搞混!

在test的时候不dropout,把所有连接恢复

stochastic gradient decent:SGD 随机梯度下降

stochastic不是完全随机

若数据集很大,梯度累加很耗显存?

仅仅是把数据集上所有梯度的平均值化为在一个batch上的平均值

卷积神经网络

什么是卷积

图片是如何表达的,这里是0—255,一般我们会变成0—1之间

rgb

4个隐藏层,共5层的网络需要多少参数

在过去连1.6mb都算大,装不下

人眼有局部相关性,局部感受

因此提出了卷积神经网络,利用局部相关性

全值共享,用一个小窗口扫描整个图片

参数量只有小窗口的参数量

卷积表达式

延伸到图片上!

锐化图片,锐化核与原图片卷积

模糊

边缘检测

具体?

使用卷积网络

k,小窗口就是代表不同观察角度,观察出不同的图片效果

具体如何运算?

kernel有“2个通道”,看multi-k,意会一下

multi-k[16,3,3,3]第一个16表示:sharpen、bluer等16个channel

第二个3表示RGB3个通道,从上一层输入图片x中继承而来

LeNet-5
特征学习
卷积运算代码

没打padding图像会小一点点

使用类的实例,它就会先运行hooks,(pytorch自带的一些功能,帮助更好的建设?),再调用.foward函数——————看19,20行

自动更新窗口参数,所以需要梯度更新

还有一个比较低阶的调用接口F.conv2d (小写的c,表示函数,大写一般表示类

池化层 pooling层

向下采样

隔行或隔列,完成降维的过程

取2*2窗口中最大的值

下图有错,是取average

代码
向上采样

放大2倍?

代码

放大2倍,

ReLu

把比较黑的点,数值为负,去掉,就变得颜色灰了些

代码

inplace表示覆盖原来的内存空间,减小内存使用

BatchNorm

sigmoid函数会出现梯度离散,尽量少用但是,偶尔会有用到的时候

怎么办呢

例子

右下的搜索方式会更稳定

全值缩放,使其分布为N(0,1)

右下数字是统计得出,可以使RGB  3  个通道分布为N(0,1)

Batch Norm具体是什么?其他很像

3个channel,[3]的均值和方差

具体例子

(6,3,784)6张图片,3个通道进行batchnorm得到均值μ和方差,(在当前batch)

再通过右上角运算迫使其分布变为N(0,1)

第二个运算式子。。。差不多

代码实现

对1d数据

running_μ和running_σ²   表示全值的均值和方差

batchnorm内部行为

running_μ和σ需要更新,β和γ也需要梯度信息会自动更新???

第2步就是放缩变换,,

对2d数据

weight和bias就是γ和β

对于当前μ和σ²无法直接知道,但是通过running可以获得全值的

affine指是否对数据进行β和γ的变换和自动更新,设置为false就是N(0~1),并且不会自动进行更新

在test数据集上时,与上不同

eval()函数将其模式转换为test用的

μ和σ²就是全值,γβ不需要更新???

效果

收敛速度更快,表现更好,更稳定

经典卷积网络

LeNet-5

AlexNet

大爆炸进展!!!

VGG

1*1的卷积核???

Googlenet

同一层用不同卷积核

不是层越多,train得越好

如今已经有1000多层了,怎么做到的?

ResNet

深度残差网络

增加了短路连接,shortcut防止前面的层梯度离散

最差也能退化到22层效果

这里参数量???减少

代码

DenseNet

nn.Module

1.好处

2.容器

3.参数

4.modules

modules是包含了自己在内的所有子类,显示出来

5.to(device)

直接转移到gpu

对于类,返回的就是net本身,对于tensor返回a_gpu

6.save and load

  1. train/test

切换,因为有些层对于train和test的功能不一样,比如dropout和BN

8.

nn.Parameter 类,自动封装w,b,nn.parameters方法即可直接调用,并且不用写需要梯度这句话

数据增强

big data

data argumentation将10张照片变换为20张,例如旋转,调色等等

Flip  翻转

rotate旋转

scale缩放

crop part裁剪

noise高斯噪声

pytorch里面好像没有,需要人为添加

上述操作会帮助,但还是原本就有很多数据好

卷积网络与resnet实战

时间序列表示方法

将string类型表示

第一个是有多少字,第二个是表达方式

对于图片,从上往下看的话

 文字

另外一种编码方式,更好用

语义相关性

啥 Embedding

查表操作

glove

循环神经网络RNN

RNN原理

评价一句话是好评还是差评

因此,w,b参数全局共享,增加语义信息,减少参数量

然鹅,我们需要一个长期的memory来保存

这个单元贯穿整个语境,考虑上一步的输入

ht是语境信息,更新自我!

梯度推导

RNN Layer使用

参数理解

x[10,3,100]   表示一句话10个单词,一次处理3句话,每个单词表达方式(长度

xt  [3,100]  一次 处理3个句子,一个时间戳处理3个句子的第一个单词

最后知道了h0是[b,20]这样的一个维度

RNN输入参数

forward函数

[5,3,100]5个单词,3句话,每个单词100维

但是不需要人为喂5次(因为5个单词)forward函数一次喂到位,直接喂x,不是xt

最后的输出,ht是最后的memory信息,out是每个memory的一个聚合

layer=1

对于多层呢

layer=2

out是最后输出的也就是最后一层的

h0= [4,3,20]       h(最后一层)= [4,3,20]

out= [10,3,20]

手动循环

一句话10个单词,手动喂10次,(小方块是一个cell,没有循环的箭号

传入的参数和RNN一样

人为for几次,在x[0]上循环

layer=1

layer=2

注意第一层30和第二层30匹配

时间序列预测

波形预测

使用另一种表达方式 [b,50,1] ,  b=1时表示  一共送一条曲线,每条曲线50个点,每个点就是一个数值

start是随机的,防止网络记住

例如最下,给0~48个点,预测1~49个点

batch_first = Ture,表达方式改变下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值