Pytorch基础知识

1. 基础知识

1. 张量

1.初始化

torch.rand(col, row)	# 使用(0~1)均匀分布随机初始化二维数组
torch.ones(col, row)	# 填充1初始化
torch.zero(col, row)	# 填充0初始化
torch.eye(col, row)		# 对角线为一,其它为0初始化

2.基本类型

tensor = torch.tensor([3.1433223]) 
torch.DoubleTensor(col, row)	# 64位浮点
torch.FloatTensor(col, row)		# 32位浮点
torch.HalfTensor(col, row)		# 16位浮点

torch.LongTensor(col, row)		# 64位整数
torch.IntTensor(col, row)		# 32位整数
torch.ShortTensor(col, row)		# 16位整数

torch.CharTensor(col, row)		# 8位整数(带符号)
torch.ByteTensor(col, row)		# 8位整数(无符号)

#转换
tensor.long()	# 64位整数
tensor.int()	# 32位整数
tensor.short()	# 16位整数

tensor.double()	# 64位浮点
tensor.float()	# 32位浮点
tensor.half()	# 16位浮点

tensor.cahr()	# 8位整数(带符号)
tensor.byte()	# 8位整数(无符号)

3.Numpy转换

torch.XXX(col, row).numpy()					# tensor转换为numpy
torch.from_numpy(numpy.XXX((col, row)))		 # numpy转换为tensor

4.设备间转换

gpu_a=cpu_a.cuda()		# cup转gpu
cpu_a=gpu_a.cpu()		# gpu转cpu

5.常用方法

max_value, max_idx = torch.max(input, dim=0)		# max_value最大值,max_idx最大值索引,dim 1为行、0为列
sum_x = torch.sum(input, dim=1)					   # sum_x求和,dim 1为行、0为列
x.add_(y)										 # 将y加到a中

2.Autograd

在张量创建时,通过设置 requires_grad 标识为Ture来告诉Pytorch需要对该张量进行自动求导。
当计算完成后调用.backward()方法自动计算梯度并且将计算结果保存到grad属性中。
使用with torch.no_grad()上下文管理器临时禁止对已设置requires_grad=True的张量进行自动求导

x = torch.rand(5, 5, requires_grad=True)
y = torch.rand(5, 5, requires_grad=True)
z=torch.sum(x+y)
z.backward()
print(x.grad,y.grad)
with torch.no_grad()
	print((x +y*2).requires_grad)	# False

3.神经网络包nn和优化器optm

1. 定义一个网络

class Net(nn.Module):
    def __init__(self):
        # nn.Module子类的函数必须在构造函数中执行父类的构造函数
        super(Net, self).__init__()
        # 卷积层 '1'表示输入图片为单通道, '6'表示输出通道数,'3'表示卷积核为3*3
        self.conv1 = nn.Conv2d(1, 6, 3) 
        #线性层,输入1350个特征,输出10个特征
        self.fc1   = nn.Linear(1350, 10)  #这里的1350是如何计算的呢?这就要看后面的forward函数
    #正向传播 
    def forward(self, x): 
        print(x.size()) # 结果:[1, 1, 32, 32]
        # 卷积 -> 激活 -> 池化 
        x = self.conv1(x) #根据卷积的尺寸计算公式,计算结果是30,具体计算公式后面第二章第四节 卷积神经网络 有详细介绍。
        x = F.relu(x)
        print(x.size()) # 结果:[1, 6, 30, 30]
        x = F.max_pool2d(x, (2, 2)) #我们使用池化层,计算结果是15
        x = F.relu(x)
        print(x.size()) # 结果:[1, 6, 15, 15]
        # reshape,‘-1’表示自适应
        #这里做的就是压扁的操作 就是把后面的[1, 6, 15, 15]压扁,变为 [1, 1350]
        x = x.view(x.size()[0], -1) 
        print(x.size()) # 这里就是fc1层的的输入1350 
        x = self.fc1(x)        
        return x

net = Net()
print(net)

input = torch.randn(1, 1, 32, 32) # 这里的对应前面forward的输入是32
out = net(input)

# 在反向传播前,先要将所有参数的梯度清零
net.zero_grad() 
out.backward(torch.ones(1,10)) # 反向传播的实现是PyTorch自动实现的,我们只要调用这个函数即可

2.损失函数

在nn中PyTorch还预制了常用的损失函数
nn.L1Loss L1损失函数 l o s s ( x i , y i ) = v m a t r i x x i − y i ∣ loss(x_i,y_i) = vmatrixx_i-y_i| loss(xi,yi)=vmatrixxiyi
nn.MSELoss L2损失函数 l o s s ( x i , y i ) = ( x i − y i ) 2 loss(x_i,y_i) = (x_i-y_i)^2 loss(xi,yi)=(xiyi)2
nn.SmoothL1Loss Huber Loss损失函数 l o s s ( x i , y i ) = { 1 2 ( x i − y i ) 2 i f ∣ x i − y i ∣ < 1 ∣ x i − y i ∣ − 1 2 otherwise loss(x_i,y_i) = \begin{cases} \frac{1}{2}(x_i-y_i)^2& {if|x_i-y_i|<1}\\ |x_i-y_i| - \frac{1}{2}& \text{otherwise} \end{cases} loss(xi,yi)={21(xiyi)2xiyi21ifxiyi<1otherwise
nn.BCELoss 二分类交叉熵损失函数 l o s s ( x i , y i ) = − ω i [ y i l o g x i + ( 1 − y i ) l o g ( 1 − x i ) ] loss(x_i,y_i)=-\omega_i[y_ilogx_i+(1-y_i)log(1-x_i)] loss(xi,yi)=ωi[yilogxi+(1yi)log(1xi)]

y = torch.arange(0,10).view(1,10).float()
criterion = nn.MSELoss()
loss = criterion(out, y)
#loss是个scalar,我们可以直接用item获取到他的python类型的数值

3.优化器

在反向传播计算完所有参数的梯度后,还需要使用优化方法来更新网络的权重和参数

  1. SGD

    torch.optim.SGD(params, lr=<required parameter>, momentum=0, dampening=0, weight_decay=0, nesterov=False)
    
  2. AdaGrad

    torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0, initial_accumulator_value=0)
    
  3. RMSProp

    torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)
    
  4. Adam

    torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)
    
    import torch.optim
    out = net(input) # 这里调用的时候会打印出我们在forword函数中打印的x的大小
    criterion = nn.MSELoss()
    loss = criterion(out, y)
    # 新建一个优化器,SGD只需要要调整的参数和学习率
    optimizer = torch.optim.SGD(net.parameters(), lr = 0.01)
    # 先梯度清零(与net.zero_grad()效果一样)
    optimizer.zero_grad() 
    loss.backward()
    
    # 更新参数
    optimizer.step()
    

4.数据的加载和预处理

1.Dataset

Dataset是一个抽象类,为了能够方便的读取,需要将要使用的数据包装为Dataset类。

from torch.utils.data import Dataset
import pandas as pd
#定义一个数据集
class BulldozerDataset(Dataset):
    """ 数据集演示 """
    def __init__(self, csv_file):
        """实现初始化方法,在初始化的时候将数据读载入"""
        self.df=pd.read_csv(csv_file)
    def __len__(self):
        '''
        返回df的长度
        '''
        return len(self.df)
    def __getitem__(self, idx):
        '''
        根据 idx 返回一行数据
        '''
        return self.df.iloc[idx].SalePrice

ds_demo= BulldozerDataset('median_benchmark.csv')
#实现了 __len__ 方法所以可以直接使用len获取数据总数
len(ds_demo)
#用索引可以直接访问对应的数据,对应 __getitem__ 方法
ds_demo[0]

2. Dataloader

对Dataset的读取操作,常用参数有:batch_size(每个batch的大小)、 shuffle(是否进行shuffle操作)、 num_workers(加载数据的时候使用几个子进程)。

dl = torch.utils.data.DataLoader(ds_demo, batch_size=10, shuffle=True, num_workers=0)
idata=iter(dl)		# 获得dl一批数据

3.torchvision 包

PyTorch中专门用来处理图像的库

1.torchvision.datasets

​ PyTorch团队自定义的dataset,这些dataset帮我们提前处理好了很多的图片数据集
​ MNIST,COCO,Captions,Detection,LSUN,ImageFolder,Imagenet-12,CIFAR,STL10,SVHN,PhotoTour

import torchvision.datasets as datasets
trainset = datasets.MNIST(root='./data', # 表示 MNIST 数据的加载的目录
                                      train=True,  # 表示是否加载数据库的训练集,false的时候加载测试集
                                      download=True, # 表示是否自动下载 MNIST 数据集
                                      transform=None) # 表示是否需要对数据进行预处理,none为不进行预处理
2.torchvision.models

​ 不仅提供了常用图片数据集,还提供了训练好的模型
​ AlexNet,VGG,ResNet,SqueezeNet,DenseNet

import torchvision.models as models
resnet18 = models.resnet18(pretrained=True)
3.torchvision.transforms

​ 提供了一般的图像转换操作类,用作数据处理和数据增强

2.基础及数学原理

1. 监督学习和无监督学习

  • 监督学习:通过已有的训练样本去训练得到一个最优模型。
  • 无监督学习:直接对数据进行建模。
  • 半监督学习:在训练阶段结合了大量未标记的数据和少量标签数据。
  • 强化学习:设定一个回报函数(reward function),通过这个函数来确认否越来越接近目标

2.线性回归

性回归分析:自变量与因变量关系可用一条线近似表示

3. 损失函数(Loss Function)

常见(PyTorch内置)的损失函数:

1. nn.L1Loss:

l o s s ( x , y ) = 1 / n ∑ ∣ x i − y i ∣ loss(x,y)=1/n\sum|x_i-y_i| loss(x,y)=1/nxiyi

2. 负对数似然损失函数nn.NLLLoss:

用于多分类的负对数似然损失函数
l o s s ( x , c l a s s ) = − x [ c l a s s ] loss(x, class) = -x[class] loss(x,class)=x[class]
如果传递了weights参数,会对损失进行加权
l o s s ( x , c l a s s ) = − w e i g h t s [ c l a s s ] ∗ x [ c l a s s ] loss(x, class) = -weights[class] * x[class] loss(x,class)=weights[class]x[class]

3. 均方损失函数nn.MSELoss:

l o s s ( x , y ) = 1 / n ∑ ( x i − y i ) 2 loss(x,y)=1/n\sum(x_i-y_i)^2 loss(x,y)=1/n(xiyi)2

4. 多分类用的交叉熵损失函数nn.CrossEntropyLoss:

多分类用的交叉熵损失函数,LogSoftMax和NLLLoss集成到一个类中,会调用nn.NLLLoss函数,我们可以理解为CrossEntropyLoss()=log_softmax() + NLLLoss()
l o s s ( x , c l a s s ) = − log e x p ( x [ c l a s s ] ) ∑ j e x p ( x [ j ] ) )   = − x [ c l a s s ] + l o g ( ∑ j e x p ( x [ j ] ) ) \begin{aligned} loss(x, class) &= -\text{log}\frac{exp(x[class])}{\sum_j exp(x[j]))}\ &= -x[class] + log(\sum_j exp(x[j])) \end{aligned} loss(x,class)=logjexp(x[j]))exp(x[class]) =x[class]+log(jexp(x[j]))

5. nn.BCELoss:

计算 x 与 y 之间的二进制交叉熵。
l o s s ( o , t ) = − 1 n ∑ i ( t [ i ] ∗ l o g ( o [ i ] ) + ( 1 − t [ i ] ) ∗ l o g ( 1 − o [ i ] ) ) loss(o,t)=-\frac{1}{n}\sum_i(t[i]* log(o[i])+(1-t[i])* log(1-o[i])) loss(o,t)=n1i(t[i]log(o[i])+(1t[i])log(1o[i]))
与NLLLoss类似,也可以添加权重参数
l o s s ( o , t ) = − 1 n ∑ i w e i g h t s [ i ] ∗ ( t [ i ] ∗ l o g ( o [ i ] ) + ( 1 − t [ i ] ) ∗ l o g ( 1 − o [ i ] ) ) loss(o,t)=-\frac{1}{n}\sum_iweights[i]* (t[i]* log(o[i])+(1-t[i])* log(1-o[i])) loss(o,t)=n1iweights[i](t[i]log(o[i])+(1t[i])log(1o[i]))

4. 梯度下降

1. 梯度:

几何上讲,梯度就是函数变化增加最快的地方,沿着梯度向量的方向,更加容易找到函数的最大值。反过来说,沿着梯度向量相反的方向梯度减少最快,也就是更加容易找到函数的最小值。

2. Mini-batch的梯度下降法

如果训练数据集很大的时候处理速度会很慢,而且也不可能一次的载入到内存或者显存中,所以我们会把大数据集分成小数据集,一部分一部分的训练,这个训练子集即称为Mini-batch。

  • 如果训练样本的大小比较小时,能够一次性的读取到内存中,那我们就不需要使用Mini-batch,
  • 如果训练样本的大小比较大时,一次读入不到内存或者现存中,那我们必须要使用 Mini-batch来分批的计算

3. torch.optim

一个实现了各种优化算法的库。

1. 随机梯度下降算法SGD

不推荐

torch.optim.SGD(params,lr=<requiredparameter>,momentum=0,dampening=0,weight_decay=0,nesterov=False)
2. 随机平均梯度下降ASGD

很少见

torch.optim.ASGD(params, lr=0.01, lambd=0.0001, alpha=0.75, t0=1000000.0, weight_decay=0)
3. AdaGrad算法

优点:它可以自动调节学习率,不需要人为调节
缺点:仍依赖于人工设置一个全局学习率,随着迭代次数增多,学习率会越来越小,最终会趋近于0
不推荐

torch.optim.Adagrad(params, lr=0.01, lr_decay=0, weight_decay=0)
4. AdaDelta算法

是Adagard的改进版,对学习率进行自适应约束,但是进行了计算上的简化,加速效果不错,训练速度快
优点:避免在训练后期,学习率过小;初期和中期,加速效果不错,训练速度快
缺点:还是需要自己手动指定初始学习率,初始梯度很大的话,会导致整个训练过程的学习率一直很小,在模型训练的后期,模型会反复地在局部最小值附近抖动,从而导致学习时间变长
可以试一试更好的

torch.optim.Adadelta(params, lr=1.0, rho=0.9, eps=1e-06, weight_decay=0)
5. Rprop(弹性反向传播)

不推荐优化方法适用于full-batch,不适用于mini-batch,因此基本上没什么用

torch.optim.Rprop(params, lr=0.01, etas=(0.5, 1.2), step_sizes=(1e-06, 50))
6. RMSProp均方根传递

RProp的改进版,也是Adagard的改进版
优点:可缓解Adagrad学习率下降较快的问题,并且引入均方根,可以减少摆动,适合处理非平稳目标,对于RNN效果很好
缺点:依然依赖于全局学习率
推荐

torch.optim.RMSprop(params, lr=0.01, alpha=0.99, eps=1e-08, weight_decay=0, momentum=0, centered=False)
7. Adam

将Momentum算法和RMSProp算法结合起来使用的一种算法
基本上是最最常用的优化方法

torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)
8. Adamax

Adam的改进版,对Adam增加了一个学习率上限的概念
是Adam的一个变种,差不了多少

torch.optim.Adamax(params, lr=0.002, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)
9. SparseAdam

针对稀疏张量的一种“阉割版”Adam优化方法
推荐,在处理稀疏张量的时候尤其推荐

torch.optim.SparseAdam(params,lr=0.001,betas=(0.9,0.999),eps=1e-08)
10. AdamW

Adam的进化版,是目前训练神经网络最快的方式
优点:比Adam收敛得更快
缺点:只有fastai使用,缺乏广泛的框架,而且也具有很大的争议性

torch.optim.AdamW(params,lr=0.001,betas=(0.9,0.999),eps=1e-08,weight_decay=0.01,amsgrad=False)
11. L-BFGS
torch.optim.LBFGS(params, lr=1, max_iter=20, max_eval=None, tolerance_grad=1e-05, tolerance_change=1e-09, history_size=100,line_search_fn=None)

5. 方差/偏差

  • 偏差度量了学习算法的期望预测与真实结果的偏离程序,即刻画了学习算法本身的拟合能力
  • 方差度量了同样大小的训练集的变动所导致的学习性能的变化,即模型的泛化能力

高偏差:(错误值过多)欠拟合。
增加网络结构,如增加隐藏层数目。
训练更长时间。
寻找合适的网络架构,使用更大的NN结构。

高方差:(将偏离过多的量拟合)过拟合。
使用更多的数据。
正则化( regularization)。
寻找合适的网络结构。

6. 正则化

减小方差的策略。
torch.optim集成的`优化器只有L2正则化方法

3 神经网络简介

1. 神经网络的表示

将神经元拼接起来,两层神经元,即输入层+输出层(M-P神经元),构成感知机。输入层与输出层之间的所有层神经元,称为隐藏层

2. 激活函数

激活函数都是非线性的

1. sigmoid 函数

a = 1 1 + e − z a=\frac{1}{1+e^{-z}} a=1+ez1 导数 : a ′ = a ( 1 − a ) a^\prime =a(1 - a) a=a(1a)

sigmoid_函数
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值