首页 > 其他 > 详细

第4章 pytorch基础

时间:2020-01-02 10:05:33      阅读:388      评论:0      收藏:0      [点我收藏+]

第4章 pytorch基础


4.1数据类型

技术分享图片

dimension为0的标量

  • 某个数据,0维的数据
  • 用处:误差
  • 技术分享图片

dim为1

  • 用处bias,线性输入
  • 技术分享图片

dim,size/shape区别

dim是几行

dim为2

  • size(0)表示第一个维度
    技术分享图片

dim3适合rnn

dim4适合图片,CNN

随机生成

randn:随机正态分布
rand:随机0-1均值分布
randint(m, n):从m到n的随机化,但不包含n


4.2 生成torch

使用:

  • torch.tensor([2., 3.2]):生成一个一维的tensor
  • torch.FloatTensor(d1, d2, d3): 生成3维的Tensor,但不初始化

不初始化的tensor后面一定要覆盖

full:全填充

torch.full([2,3], 7)

arange/range


4.3 索引与切片

基础索引方式

a[0].shape:表示第0个维度数据
a[0, 0, 2, 4]:具体的某个标量
技术分享图片

连续索引

a[:2]:从0到2的索引,但不包含2
‘a[: 1]‘:从第一个到索引为1
a[-1:]:从最后一个到最后一个(-1表示倒数第一个)
技术分享图片

隔行采样

a[0 : 28 : 2]
a[: : 2]

index_select直接选取

  • 在某个维度进行操作
    a.index_select(0, [0, 2]):表示在第0个维度上选取第0和2的tensor:

out.shape = torch.Size([2, 3 ,28, 28])

a.index_select(2,torch.arange(8)).shape
表示在第二个维度上取0:8,输出

torch.Size([4,2,8,28])

...表示所有都取,方便书写

三个.
a[... , : 2].shape
torch.Size([4, 3, 28, 2])

mask 和 take,取掩码,会将数据打平

take先将几行几列变成一行n列


4.4 tensor维度和其他变化

view和reshape

  • 两个功能一致
  • shape查看当前的尺寸
  • a.view()要有物理意义,否则容易导致数据的污染或者丢失
    1. 变成4张图片,每个图片把所有通道打平,用在全连接层的转换
    2. 把所有行都合在一块
    3. 把所有图片组成一个大的通道数
    4. view完后,如果不知道前面是怎么来的,再变回去会有逻辑错误,造成数据污染
    5. 如果view中和原本通道的数目不一致会出现错误
      技术分享图片

Squeeze和unsqueeze(压缩和展开)

unsqueeze

可插入的位置为[-5, 5)。
0为第一个位置,-1为最后一个数的后面,和4相同,5会报错

a.unsqueeze(4)
技术分享图片
实例
将b的维度扩展到f相同维度
技术分享图片

squeeze

b.squeeze():能压缩的都压缩(压缩为1的通道)
b.squeeze(0)压缩第0个通道
技术分享图片

Expand/repeat

区别

  • repeat会复制里面的内容,expand只是简单的扩展
  • repeat里面参数是表示复制多少次,而expand表示扩展到多少维
expand
  • 原本有数据的不能扩展,只能对为1的扩展
  • -1表示原来多少,现在还是多少,或者为1
  • -4是个bug,会真的变成-4
    技术分享图片

repeat

表示复制的此处,如32表示复制32次
不推荐使用
技术分享图片

转置

.t()

只针对2维的tensor,其他的不行

transpose
  • 表示某两个数据转换
  • 转换后需要加contiguous(),让其变成连续,否则会出错
  • 转换回来的时候,一定要记住他的转换维度变换顺序,否则转不回来
    技术分享图片
permute

内部自己调用transport,直接用先前的位置标号来重组现在的维度。
技术分享图片


5.1 broadcast

  • 自动的将维度增加,先在相同维度的前面增加1(unsqueeze),然后再expand扩展到相同维度
  • 优点在于省去认为扩展,且节省内存

应用场景

  • 定义的通道要么和原来的相同,要么为1或者不定义:如4,3,32,32 + 3,1,1, 这个时候后者会自动扩展,表示的物理意义为三个通道分别叠加一个值
  • 如果包含了不为1且不等于对应通道的则无法叠加,如上述不能加2,3,32,32

5.2tensor合并和分割

cat

某个维度上进行合并,必须保证其他维度一致,否则会出错
技术分享图片

stack

将两个相同维度的tensor扩展为成2维,必须保证两个tensor维度相同
技术分享图片

split拆分

两种方式:

  • 给一个tensor,如[2, 3] 告诉拆分为2和3的两个tensor(前提是有5维)
  • 给一个int,如1,那么拆分为维度为1的多个tensor

注意
2不能被2拆分
技术分享图片

chunk

指定拆分为多少块,和split中的第二种方法一致
技术分享图片

5.3 tensor运算

加减乘除

重载符号:+-* /
或者:add,sub,mul,div
注意:这里的乘是元素相乘
技术分享图片

4种相加

x = torch.rand(5, 3)
y = torch.rand(5, 3)
#第一种
print(x + y)
#第二种
print(torch.add(x, y))
#第三种
result = torch.empty(5, 3)
torch.add(x, y, out=result)
print(result)
#第四种
y.add_(x)
print(y)

矩阵相乘

torch.mm针对2维
torch.matmul所有维度(推荐使用)
@是上述matmul的重载使用
技术分享图片
多于2维相乘

  • 只针对后面两维相乘,前面的保留不动
  • 对于维数不对的会进行维度broadcast,但注意有可能不能成功的broadcast
    技术分享图片

Power

用法:

  • pow(2)
  • sqrt()开方
  • rsqrt()开方的倒数
  • a** 2:a的平方
  • a** (0.5):a的开方
    技术分享图片

对数

exp()
log():默认e为低,可以换,log2()

浮点数运算

  • floor ceil
  • round
  • trunc:取整数部分
  • frac():取小数部分

clamp用于梯度裁剪

  • 单个参数时:(min):将小于这个的数变成这个
  • 两个:(min,max):保留这个区间的数,其他依次向上或向下取参数设定值
    技术分享图片

5.4 tensor统计

norm

  1. norm(n):表示几范数
  2. norm(n , dim = m):在m维度上的n范数,如下表的b上面1维度的1范数,就是同一行的所有列进行范数运算
    技术分享图片

max、min、mean、sum、prod

prod:返回所有元素乘积
技术分享图片

argmax、argmin

默认为把所有数据打平后再来计算最大最小值所在位置
可以指定某个维度上来计算,如右侧例子中,在1维上,那么是对每行中找出列最大的值,返回4个数,同理在0维时

dim和keepdim

max(dim = n)会返回一个在n维上的最大值,并将索引一起返回
argmax只会返回索引
keepdim = true,会保留先前的维度,比如这里保留为4, 1
技术分享图片

topk和kthvalue

topk:前几个大的,返回数值和索引
kthvalue:第几小,默认从小到大排序,返回值和索引

比较

>和gt一样
eq是比较每一个元素
equal是比价两个是否全等
技术分享图片

5.6 tensor高阶

where

方便GPU调用
技术分享图片

gather

查表:从局部的到全局的转变,利用GPU进行
技术分享图片
先把要查的对象扩展到和表一样的大小
技术分享图片

网络初始化

凯明初始化
learning rate要合适小
逃离最小值:在局部极小值的时候,需要一个惯性逃离极小值,具体还不是很懂


6.2 激活函数和损失函数的梯度

激活函数

tanh在RNN中经常使用

线性划分十个单元和各个激活函数表示:

a = torch.linspace(-1,1,10)
torch.sigmoid(a)
torch.tanh(a)
torch.relu(a)

损失函数

Mean Squared Error(均方差)
  • norm求loss
    • torch.norm(y- pred, 2).pow(2)
      技术分享图片
pytorch自动求导
  • autograd.grad

    • 要设置w为可求导:w.requires_grad_()
    • 或者x = torch.ones(2,4,requires_grad=True)
    • 然后更新图(pytorch是动态图):mse=F.mse_loss(x* w, torch.ones(1))
    • 应该先lab,在pred,这样建立一个损失函数(均方差)
      • F是建立某种损失函数的图(缩写)
      • 技术分享图片
  • loss.backward

    • 在上面基础上,mse.backward()
    • 然后要查看哪一个的时候w.grad
    • 技术分享图片
  • 总结

  • 技术分享图片

  • 对于backward类型:如果Tensor是一个标量(即它包含一个元素数据)则不需要为backward()指定任何参数, 但是如果它有更多的元素,你需要指定一个gradient 参数来匹配张量的形状。

  • 注意,要想使x支持求导,必须让x为浮点类型,也就是我们给初始值的时候要加个点:“.”。不然的话,就会报错。

  • loss.backward()在调用前需要清除已存在的梯度,否则梯度将被累加到已存在的梯度

    • net.zero_grad() # 清除梯度

softmax

  • 结构:
    • 技术分享图片
  • 求导计算
    • 技术分享图片
  • pytorch计算
    技术分享图片

7.4 MLP反向传导推导

从输出到前面每一层的迭代然后链式法则计算

7.5函数最优化

学习率优化
第一步初始化,lr为学习率
每一次迭代需要将上一步的梯度先清0
optimizer.step()是更新x、y的梯度

optimizer = torch.optim.Adam([x], lr=1e-3)

optimizer.zero_grad()
pred.backward()
optimizer.step()

技术分享图片


8.1分类和逻辑回归问题

  • 分类问题去趋近某一个概率(实际概率和真实概率)
    • 实际概率也不一定为1,可能为某个小数
  • 回归问题去趋近某一个真实值(实际值和真实值)
    • 连续问题

逻辑回归(logistic regression)

逻辑:因为用了sigmoid函数
regression:默认MSE为这个问题,最小均方差

8.2 交叉熵

Entropy

量化分布的概率,如果某个概率确定,那么确定性越高
技术分享图片

Cross Entropy

对两个或者多个的概率分布,统计两个概率重合程度(或者散度)
越小越好
技术分享图片

  • 对于P = Q
    H(p,q) = H(p)

  • 对于one-hot分类
    H(p,q) = D(p|q)

二分类问题

y为某个对象的概率的真实值,p为网络学习到的值(自己的计算值)
技术分享图片

多分类问题

不使用MSE而使用交叉熵
交叉熵下降更大
MSE更加简单,也需要尝试
技术分享图片

实例

  1. cross_entropy是包含了softmax,log和nll_loss三个操作一体的,因此不能再写softmax输入
  2. 单独用的时候需要各个都计算一遍
  3. log函数是对上述多分类问题中Q的计算
    技术分享图片

8.2 LR多分类实战

关键:初始化很重要,用凯明初始化,不要乱随机初始化

torch.nn.init.kaiming_normal_(w1)
torch.nn.init.kaiming_normal_(w2)
torch.nn.init.kaiming_normal_(w3)

8.3 利用自带的全连接层进行测试

  • nn.Linear(in, out) : 全连接层

  • 能用relu的地方要用relu,除非RGB像素重建

  • inplace的操作,会节省内存
    技术分享图片

  • 类风格和函数风格调用
    类风格中的参数都封装起来了,需要另外调用,但更安全。
    技术分享图片

  • 不用自己管理参数,直接在net.parameters()

net = MLP()
optimizer = optim.SGD(net.parameters(), lr=learning_rate)
criteon = nn.CrossEntropyLoss()

8.4 激活函数和GPU加速

leakyRelu

其他激活函数

SELU和softplus

GPU加速

第一步:device = torch.device(‘cuda:0‘)
第二步:把需要加速的放到GPU中,加.to(device)
net = MLP().to(device)
data, target = data.to(device), target.cuda()
criteon = nn.CrossEntropyLoss().to(device)
注意:.cuda()不推荐使用,cuda:0是使用那张显卡

8.5测试MNIST

测试准确率

求出softmax后的最大值索引
与目标进行比较
相同的为1,并求多少个1
最后求比例
技术分享图片

8.6 可视化visdom

  1. 有类似TensorFlow的TensorBoardX,但这个需要每次把tensor转换成numpy
  2. 使用visdom在windows下先去官方GitHub上下载,然后再安装目录下安装。
    pip install -e .
  3. 安装完成后,退回到用户目录,
    cd ../..
    运行:
    python -m visdom.server
    复制:You can navigate to http://localhost:8097 网址到浏览器,运行
  4. pytorch中再调用即可
    单曲线
    第一行通过win注册一个窗口,update=‘append‘很重要,是附加,而不是覆盖
    opts=dict(title=‘train loss‘)是指定显示title
viz.line([0.], [0.], win=‘train_loss‘, opts=dict(title=‘train loss‘))

viz.line([loss.item()], [global_step], win=‘train_loss‘, update=‘append‘)

双曲线
第一个定义有几根曲线,后面定义横坐标

viz.line([[0.0, 0.0]], [0.], win=‘test‘, opts=dict(title=‘test loss&acc.‘,
                                                   legend=[‘loss‘, ‘acc.‘]))
                                                   
viz.line([[test_loss, correct / len(test_loader.dataset)]],
             [global_step], win=‘test‘, update=‘append‘)

可视化图

viz.images(data.view(-1, 1, 28, 28), win=‘x‘)
    viz.text(str(pred.detach().cpu().numpy()), win=‘pred‘,
             opts=dict(title=‘pred‘))

9.1 过拟合和欠拟合

过拟合:因为模型大小有限,而构建的模型太过复杂,导致过分拟合数据,测试的时候效果则反而不行
欠拟合:模型太过简单,不能很好的抽象出现在的模型
泛化能力:能够找到合适的模型来描述现在的数据集模型,且能迁移
关键:如何检测过拟合,如何降低欠拟合

9.2 交叉验证

把数据集分成三份,train set val set test set
前两个是自己拿到的,后面一个是客户或者其他人持有用来验证的

如何检测已经过拟合
在测试数据集出现准确率下降时,这个时候需要保存这个模型,防止进一步的数据过拟合

pytorch如何分成三份

pytorch只能分成两份,因此需要人为的自己分开

train_db = datasets.MNIST(‘../data‘, train=True, download=True,
                   transform=transforms.Compose([
                       transforms.ToTensor(),
                       transforms.Normalize((0.1307,), (0.3081,))
                   ]))
train_loader = torch.utils.data.DataLoader(
    train_db,
    batch_size=batch_size, shuffle=True)

test_db = datasets.MNIST(‘../data‘, train=False, transform=transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.1307,), (0.3081,))
]))
test_loader = torch.utils.data.DataLoader(test_db,
    batch_size=batch_size, shuffle=True)


print(‘train:‘, len(train_db), ‘test:‘, len(test_db))
train_db, val_db = torch.utils.data.random_split(train_db, [50000, 10000])
print(‘db1:‘, len(train_db), ‘db2:‘, len(val_db))
train_loader = torch.utils.data.DataLoader(
    train_db,
    batch_size=batch_size, shuffle=True)
val_loader = torch.utils.data.DataLoader(
    val_db,
    batch_size=batch_size, shuffle=True)

9.3 减低过拟合

方法

  • 更多的数据
  • 减低模型的复杂性
    • 知道数据集大小则减小网络成熟,shallow
    • 不知道一个匹配情况,则用regularition,自动的将大的网络结构降低网络复杂程度
  • dropout
  • 数据增强
  • 提前终结

regulation

在代价函数中加入一项:
技术分享图片
这个也叫weight Decay

常用两种方法
技术分享图片
λ是一个超参数,θ为w或者b,下面是2范数情形,1范数时需要人为的自己写一下。

技术分享图片
1范数

技术分享图片
2范数

9.3动量和学习率衰减

动量

减小随机性,跳过局部极小点

学习率衰减

一开始选用比较大的学习率,后面减小,有两个方案

补充知识

Early stopping

有个经验选择在这里面,当准确率不再上升,或者下降一定程度时就停掉学习,输出模型

Dropout

  1. Dropout是让一些参数在训练过程中直接不参与训练,尽量减少权值的使用,以降低过拟合
  2. pytorch和TensorFlow两个Dropout函数使用刚好定义是相反的,需要注意
    技术分享图片
  3. 在测试的时候,要人为的写入一个参数,保证所有权值都使用尽量,否则会降低准确率
    训练过程中的0.5是0.5的概率断掉,如果为1,是都断掉
    技术分享图片
    技术分享图片

batch

将一个完整的数据集分成多个batch输入训练,因为把所有数据集放进去这个不大可能,显存不够大。


10.1卷积

pytorch调用
nn.Conv2d(in, out, kernel_size = n, stride = m, padding = l)
可以直接用layer(x),pytorch帮助完成forward操作
技术分享图片

另外一种调用方法,通过函数类型
注意:通道的数目要注意
技术分享图片

10.2池化和Relu

池化

最大池化和平均池化,优先使用最大池化
技术分享图片

上采样:是pytorch中特有的,不再使用upSample函数,而是F.interpolate
技术分享图片

Relu

过滤掉为负值的点,增加非线性化
inplace一般设置为true,这样替换掉前者,节省空间
技术分享图片

10.3 BatchNorm

当使用sigmoid函数时,为了保证梯度下降更快,不出现梯度离散现象,对现有的数据进行N(0~1)c操作。

方法类别

技术分享图片

做法:找出平均值,然后当前值减去平均值除以最大最小值差,pytorch调用BatchNorm2d
技术分享图片

10.4 残差网络

10.5 nn.Moudule

写网络时,直接继承这个类,就可以方便的管理网络参数训练。
自定义继承这个类时也可以加到parameter中去。
后面再回过头来补充

10.6 数据增强

pytorch可以直接自己做一些简单的数据增强,不需要自己生成一些图片。
包括旋转,镜像,随机剪切等几何操作
技术分享图片


11.2梯度离散和梯度爆炸

这里主要是针对RNN,梯度离散在CNN中也同样存在,在网络结构层数变多时,梯度下降会导致最前面的网络权值基本不变,导致层数增加也不会使网络效果变好。
RNN优化方法是LSTM


12 卷积网络实战

数据集,CIFAR

13 自定义数据集(宝可梦精灵)

数据集的预处理

数据集需要reshape到同一个尺寸,网络才好训练
然后将reshape的图进行数据增强
增强后归一到一个比例上
最后转换为tensor


附录:补充

data和detach

.data 与 .detach(),区别

常用方法

torch.lerp(star, end, weight) : 返回结果是out= start+ (end-start) * weight
torch.rsqrt(input) : 返回平方根的倒数
torch.mean(input) : 返回平均值
torch.std(input) : 返回标准偏差
torch.prod(input) : 返回所有元素的乘积
torch.sum(input) : 返回所有元素的之和
torch.var(input) : 返回所有元素的方差
torch.tanh(input) :返回元素双正切的结果
torch.equal(torch.Tensor(a), torch.Tensor(b)) :两个张量进行比较,如果相等返回true,否则返回false
torch.ge(input,other,out=none) 、 torch.ge(torch.Tensor(a),torch.Tensor(b))    比较内容:
ge: input>=other  也就是a>=b, 返回true,否则返回false
gt: input> other    也就是a>b, 返回true,否则返回false
lt: input<other 也就是a<b, 返回true,否则返回false
torch.max(input): 返回输入元素的最大值
torch.min(input) : 返回输入元素的最小值
element_size() :返回单个元素的字节
引用连接

第4章 pytorch基础

原文:https://www.cnblogs.com/muche-moqi/p/12131603.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!