基本数据类型
在pytorch中是没有字符串类型的,如果是分类问题,需要使用onehot,或者embedding(如Word2vec,glove)
数据类型
注:GPU和CPU的数据类型是不同的
查询数据类型
a.type() 查询数据的类型
isinstance(待查询数据,数据类型) 查看该数据的数据类型与所给的数据类型是否一致。一致,True;不一致,False
数据的维度
Dimension 0
标量
Dim 1
tensor传入的参数只能是现有数据,需要带上方括号
from_numpy将numpy类型数据转换为tensor类型数据
Intensor、FloatTensor只是创建时数据类型不同
Tensor传入的参数为现有数据或者shape,传入现有数据时需要加方括号,随机生成一维向量,默认类型为float
Dim 3
注:有多少维就有多少层方括号
Dim 4
tensor类型数据一些常用函数
a.shape
a.numel() 总的元素个数,例:[2, 3]为6
a.dim() a的维度为多少
tensor的创建
使用numpy类型
使用list类型
创建未初始化的tensor时需注意,一定要在后面设置数据,否则直接使用初始化的数据有可能报错
设置tensor的默认数据类型
用随机函数生成tensor
rand生成随机数的范围[0,1),均匀分布
rand_like 产生一个和a相同shape,相同随机方法的tensor
randint(min, max, shape) 产生一个min和max均匀分布的tensor,例:torch.randint(1, 10, [3, 3])
正态分布的随机初始化
不给参数默认为N(0, 1)
给参数时,需要两个相同tensor类型的数据
创建tensor时,全部指定为一个数值
torch.full([shape], val)
使用arange创建
arange中前两个参数代表范围,第三个代表取值间隔
linspace/logspace创建
linspace前两个参数代表范围,steps表述取几个值,取值时均匀取值
logspace前两个参数是对数的指数,例如:torch.logspace(0, -1, steps=10) 取值范围是100 ~ 10-1 ,其中底数可以通过base参数设置
Ones/zeros/eye创建
eye创建主对角线为1,其余为0
randperm创建
randperm会创建一个随机分布,不重复,取值为0~num-1,长度为num的tensor,使用a[idx]和b[idx]会随机打散行,但a和b的行仍然一一对应(a和b的行相同),应用:行代表人,a每一行代表每一个人的理科成绩,b每一行代表每一个人地体育成绩
索引和切片
直接索引
索引所得结果会将维度减小,如果索引维度和数据维度一致时,得到的值是一个标量
类似列表方式索引数据
索引特定的数据
index_select(dim,tensor)
第一个参数是在那个维度上选择;第二个参数是tensor类型数据,在该类型上选择特定的数据
…索引
…表示全部选择,如果在…的后面有数值,从最右边开始
mask按照条件索引
索引的结果会被打平
使用flatten index索引
torch.take(数据,tensor)
将数据打平,再根据打平后的索引取值
维度变换
view
注:维度变换前后元素个数需要保持一致
unsqueeze
添加维度
squeeze
直接使用会去除所有维度数值为1的维度
指定维度时,只去除维度数值为1的维度,如果大于1,则不作任何操作
expand
expand遵循broadcast原则,并不会真正的复制数据
repeat
repeat会复制数据,且在使用时,传入的tensor是与原tensor相乘
.t 转置
.t只能用于二维tensor
tranpose
转置之后,一定要使用contiguous,否则view时会报错
permute
permute可一次转置全部维度
Broading cast
过程:先在对应位置上插入一个维度,之后扩展到对应的维度
合并与分割
cat
按照指定的维度拼接,其余的维度的shape需保持一致,默认dim=0
stack
拼接时,会创建一个新的维度
split
传入列表时,根据列表分割
传入数字时,均分
对于数字,如果不够分时,最后一个有多少就分多少
chunk
chunk根据数量进行划分划分
基本运算
建议使用+ - * /
矩阵相乘
torch.mm仅适用于二维
torch.malmul适用于多维,与@运算符等价
torch.malmul运算时只计算最后两个维度,其余维度需保持一致
power
平方使用power,等价于**
exp log
近似
floor:小于该数的最大整数
ceil:大于该数的最小整数
trunc:只保留整数部分
frac:只保留小数部分
round:四舍五入
clamp
clamp:一个参数时,表示小于参数的值转换为参数
两个参数时,限定范围
统计属性
矩阵和向量的范数
norm-p
mean, sum, min, max, prod
prod:累乘
dim keepdim
top-k k-th
kthvalue是从小到大排列,从1开始排
compare
高阶OP
根据条件取a,b的值,类似于三目运算符
gather
例子:对于分类问题,假设是一个10分类问题,得到概率为前三的位置,根据位置在label中得到对应的物体,而每一次分类时有多张图片,即batch
使用gather时,行数需保持一致
loss函数和梯度
autograd.grad
使用自动求导公式,需要用requires_grad_设置,再重新生成图
或者在创建w时设置requires_grad=True
autograd.grad第一个参数为被求导参数,第二个为求导参数
loss.backward
backward会将梯度信息存储在参数的grad属性中
softmax
设置retain_graph=True能够该图重复使用
Logistic Regression
regression和classification的不同
对于分类问题
例如:分类时,选择概率最大的位置。假如p > 0.5选择该位置,原概率为0.4,之后更新为0.45,结果不变,导致gradient=0;原概率为0.49,之后更新为0.51,变化很大,梯度不连续。因此,使用MSE方法计算误差不合适
交叉熵
熵
特点:概率分布越不均匀,交叉熵越小
交叉熵
DKL(p|q)是p和q的相似程度,p和q越相似,值越小;反之,值越大。当p=q时,为0
注意:在使用cross_entropy时,无需使用softmax,因为已经自动包含了;如果已经使用了softmax,用nll_loss
LR多分类实战
w1, b1 = torch.randn(200, 784, requires_grad=True),\
torch.zeros(200, requires_grad=True)
w2, b2 = torch.randn(200, 200, requires_grad=True),\
torch.zeros(200, requires_grad=True)
w3, b3 = torch.randn(10, 200, requires_grad=True),\
torch.zeros(10, requires_grad=True)
torch.nn.init.kaiming_normal_(w1)
torch.nn.init.kaiming_normal_(w2)
torch.nn.init.kaiming_normal_(w3)
def forward(x):
x = x@w1.t() + b1
x = F.relu(x)
x = x@w2.t() + b2
x = F.relu(x)
x = x@w3.t() + b3
x = F.relu(x)
return x
optimizer = optim.SGD([w1, b1, w2, b2, w3, b3], lr=learning_rate)
criteon = nn.CrossEntropyLoss()
for epoch in range(epochs):
for batch_idx, (data, target) in enumerate(train_loader):
data = data.view(-1, 28*28)
logits = forward(data)
loss = criteon(logits, target)
optimizer.zero_grad()
loss.backward()
# print(w1.grad.norm(), w2.grad.norm())
optimizer.step()
if batch_idx % 100 == 0:
print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
注:在使用时,一定要注意参数的初始化
简便方法,直接使用pytorch中自带的函数和类
step1
step2
step3
train
nn和F的对比
nn更像是一个类,F可直接使用
GPU加速
在需要使用GPU的参数后面加上to(device);旧版写法加上cuda(),不建议使用
test部分
一般1次或多次epoch之后进行一次test
visdom可视化
在cmd中输入python -m visdom server运行,之后输入红色方框中的网址到浏览器中即可
使用
绘制曲线
第一个line:第一个参数代表y,第二个参数代表x,win窗口ID,opts窗口名称;主要用于初始化一个窗口
第二个line:y,x,窗口ID,更新方式
一个窗口中绘制多条曲线
可视化图片
过拟合和欠拟合
欠拟合
表现:test的准确度低且train的准确度也低
过拟合
表现:test精度低,但train精度极高,这种情况也可称为泛化能力弱( Generalization Performance)
交叉验证
一般将数据分为三个部分,train,val,test,其中test一般是不可得到的
为何将test设置为不可获得?
防止作弊,因为可以直接将test部分数据用来train;其次,我们用val进行验证时,总是会取结果最好的部分,即总是取使得loss最小的模型,不准确,常称为防止数据污染
交叉验证
交叉验证就是将train和val合并在一起,分为n份,随机去n-1份做为train,1份做为val
regularization
所谓regularization就是将模型参数也加入到loss函数中
L2-regularization
weight_decay就是lambda
L1-regularization
L1-regularization在pytorch中没有,需自己实现
动量、学习率衰减、dropout、early stopping
动量(momentum)
将上一次的梯度方向也考虑进来,更稳定,且找到局部最小值的时候,有可能跳过,从而找到真的的极小值点
学习率衰减
方法一:
调用ReduceLROnPlaTeau,会自动监管学习率;使用scheduler.step监管loss,若epoch patience次loss不降,就会更新学习率
方法二:
early stopping
dropout
注:在pytorch和tensorflow中,dropout参数代表的意义不同。在pytorch中,参数代表的是断开的概率,如果为0,表示不断开;在tensorflow中,参数代表的是连接的概率,为1时才表示不断开
stochastic并不是代表完全的随机分布,而是说分布服从一个概率函数,如服从正态分布等
卷积神经网络
注:在pytorch中,image的tensor顺序是[b, c, h, w]
nn.Conv2d
bias
F.conv2d
注:F后面接小写字母开头,它是一个函数;nn后面接大写字母开头,它是一个类
池化层
下采样
上采样
ReLU
Batch Norm
当多个数据的分布比较接近的时候,梯度迭代更加容易
Batch Norm方法:(x - u)/ σ
image数值是统计得到的
Batch Norm是在channel这一维度上计算得,传入参数是直接传入channel的数量
ResNet
nn.Module
自己实现一个线性层
注:使用的是nn.Parameter,目的是让它能够跟更新梯度,且参数被自动管理
Parameter
node children
一些常用的操作
(1)device:
将参数放到GPU上进行运算
注:放到GPU之后参数返回值有可能会变化,因此,常需要进行接收
(2)save和load
(3)train和test
注:是train还是test一定要区分清楚,比如dropout、batch norm就会有影响
(4)创建自己的层
数据增强
对于图片来说,常用的操作有翻转、旋转、截取等,使其获得多张图片,扩充数据
注:数据增强会有帮助,但不会太大,因此需要控制好数量
RNN原理
RNN的使用
注:out是最后一个输出,与输入的shape一致;ht是之后所有h的集合
RNN的缺点:容易出现梯度离散和梯度爆炸
LSTM
LSTM主要由四个部分组成
遗忘门:
记忆门:
更新门:
输出门:
LSTM的使用
Auto-Encoders
AE
将网络的前后两部分对称设置,中间层只用两个,本质仍然是一个全连接层
训练部分
VAE
另外一种解释:将图片视为几种函数的集合,从原图p(x)学会分布q(x),再从q(x)中sample数据,得到输出图像
KL描述p和q之间的相似程度,值越小,相似程度越大
q~N(0, 1), 即u2=0, σ2=1
sample的问题:如何计算梯度
使用Reparameterization trick
z是从q(x)中sample出来的,加上N(0,1)之后,均值方差仍然不变,但可以计算梯度了
GAN
gan的思想:gan主要由两个部分组成,生成器(generator)和辨别器(discriminator),其中生成器从一些随机信号中生成图片,辨别器判断真假。训练时,先训练辨别器,再训练生成器。如果辨别器辨认失败,进行更新学习,生成器生成图片被辨别是假的,也进行更新学习。就像警察和假钞制造者,警察不断提高辨别能力,而假钞制造者不断提高造假技术
如何训练:
pr(x):真实图片 pg(x)/pz(z):生成图片
对于D(辨别器),让它判断真实图片为真的概率最大,判断生成图片为真的概率最小
对于G(生成器),让它判断真实图片为真的概率最小,判断生成图片为真的概率最大
训练步骤:先训练D,不训练G;再训练G,不训练D
gan的缺点:
gan在训练的过程中,当p和q的分布峰值距离超过一定的范围时,会出现梯度消失,无法训练的现象。原因是当两者差距过大,loss会一直都很大
WGAN
为了解决梯度消失问题,wgan就被提出来了
基本思想:让q逼近p分布时所用步数最小
工程上为了满足这个条件,加上了梯度惩罚项