Pytorch基础知识

Tensor

  • Tensor是Pytorch中重要的数据结构,它可以是一个数、一维数组、二维数组或更高维的数组。Tensor和Numpy的narrays类似,但是Tensor可以使用GPU加速。

  • Tensor基本示例
    包的导入:

    import torch as t
    

    定义一个矩阵(不初始化):

    #创建5*3的矩阵(未初始化)
    x = t.Tensor(5,3)
    x
    

    在这里插入图片描述
    创建均匀分布初始化的数组:

    x = t.rand(5,3)
    x
    

    在这里插入图片描述
    查看Tensor的形状:

    print(x.size())
    

    在这里插入图片描述
    Tensor的加法(方法一):

    y = t.rand(5,3)
    t.add(x,y)
    

    在这里插入图片描述
    Tensor的加法(方法二):

    x+y
    

    在这里插入图片描述
    Tensor的加法(方法三):

    result = t.Tensor(5,3)
    t.add(x,y,out=result)
    result
    

    在这里插入图片描述
    函数名后面带下划线_的函数会修改Tensor本身。例如:x.add_(y)和x.t_()会改变x,但x.add(y)和x.t()会返回一个新的Tensor,而x不变。

  • Tensor和Numpy的数组间的操作非常容易且快速,Tensor不支持的操作,可以先转为numpy数组处理,之后再转回Tensor。

    a = t.ones(5)
    a
    b = a.numpy()
    b
    

    在这里插入图片描述

  • Tensor与Numpy的互相转化

    import numpy as np
    a = np.ones(5)
    b = t.from_numpy(a)
    print(a)
    print(b)
    

    在这里插入图片描述

  • Tensor和Numpy对象共享内存,所以它们之间的转换很快,而且几乎不会消耗资源。因此,一个改变了,另一个也会改变。

    b.add_(1)
    print(a)
    print(b)```
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210623141837234.png)
    

Autograd:自动微分

  • 深度学习算法的本质是通过反向传播求导数,pytorch的Autogard模块实现了此功能。Autogard.Variable是Autogard中的核心类,它简单封装了Tensor,并支持几乎所有Tensor的操作,可以调用它的.backward实现反向传播,自动计算所有梯度。

  • Variable主要包含三个属性:
    data:保存Variable所包含的Tensor
    grad:保存data对应的梯度,其本身也是一个Tensor
    grad_fn:指向一个function,这个函数用来反向传播计算输入的梯度

  • Variable的简单使用
    导入:

    from torch.autograd import Variable
    

    创建:

    x = Variable(t.ones(2,2),requires_grad=True)
    x
    

    在这里插入图片描述
    求和:

    y = x.sum()
    y
    

    在这里插入图片描述
    梯度计算:

    y.grad_fn
    y.backward()
    

卷积神经网络

  • 网络结构:数据输入层/ Input layer、卷积计算层/ CONV layer、ReLU激励层 / ReLU layer、池化层 / Pooling layer、全连接层 / FC layer
  • 数据输入层:主要是对原始图像数据进行预处理
  • 卷积层:当给定一张新图时,CNN并不能准确地知道这些特征到底要匹配原图的哪些部分,所以它会在原图中把每一个可能的位置都进行尝试,相当于把这个feature(特征)变成了一个过滤器。这个用来匹配的过程就被称为卷积操作。
    卷积的操作如图所示:
    在这里插入图片描述
    要计算一个feature(特征)和其在原图上对应的某一小块的结果,只需将两个小块内对应位置的像素值进行乘法运算,然后将整个小块内乘法运算的结果累加起来,最后再除以小块内像素点总个数即可。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    根据卷积的计算方式,第一块特征匹配后的卷积计算如下,结果为1
    在这里插入图片描述
    对于其它位置的匹配,也是类似(例如中间部分的匹配)
    在这里插入图片描述
    计算之后的卷积如下:
    在这里插入图片描述
    以此类推,对三个特征图像不断地重复着上述过程,通过每一个feature(特征)的卷积操作,会得到一个新的二维数组,称之为feature map。其中的值,越接近1表示对应位置和feature的匹配越完整,越是接近-1,表示对应位置和feature的反面匹配越完整,而值接近0的表示对应位置没有任何匹配或者说没有什么关联。如下图所示:
    在这里插入图片描述
    可以看出,当图像尺寸增大时,其内部的加法、乘法和除法操作的次数会增加得很快,每一个filter的大小和filter的数目呈线性增长。由于有这么多因素的影响,很容易使得计算量变得相当庞大。
  • 池化层
    为了有效地减少计算量,CNN使用的另一个有效的工具被称为“池化(Pooling)”。池化就是将输入图像进行缩小,减少像素信息,只保留重要信息。
    池化的操作也很简单,通常情况下,池化区域是22大小,然后按一定规则转换成相应的值,例如取这个池化区域内的最大值(max-pooling)、平均值(mean-pooling)等,以这个值作为结果的像素值。
    下图显示了左上角2
    2池化区域的max-pooling结果,取该区域的最大值max(0.77,-0.11,-0.11,1.00),作为池化后的结果,如下图:
    在这里插入图片描述
    池化区域往左,第二小块取大值max(0.11,0.33,-0.11,0.33),作为池化后的结果,如下图:
    在这里插入图片描述
    其它区域也是类似,取区域内的最大值作为池化后的结果,最后经过池化后,结果如下:
    在这里插入图片描述
    对所有的feature map执行同样的操作,结果如下:
    在这里插入图片描述
    最大池化(max-pooling)保留了每一小块内的最大值,也就是相当于保留了这一块最佳的匹配结果(因为值越接近1表示匹配越好)。也就是说,它不会具体关注窗口内到底是哪一个地方匹配了,而只关注是不是有某个地方匹配上了。
    通过加入池化层,图像缩小了,能很大程度上减少计算量,降低机器负载。
  • 激励层
    常用的激活函数有sigmoid、tanh、relu等等,前两者sigmoid/tanh比较常见于全连接层,后者ReLU常见于卷积层。
    在这里插入图片描述
    在卷积神经网络中,激活函数一般使用ReLU(The Rectified Linear Unit,修正线性单元),它的特点是收敛快,求梯度简单。计算公式也很简单,max(0,T),即对于输入的负值,输出全为0,对于正值,则原样输出。
    ReLU激活函数操作过程:
    第一个值,取max(0,0.77),结果为0.77,如下图:
    在这里插入图片描述
    第二个值,取max(0,-0.11),结果为0,如下图
    在这里插入图片描述
    以此类推,经过ReLU激活函数后,结果如下:
    在这里插入图片描述
    对所有的feature map执行ReLU激活函数操作,结果如下:
    在这里插入图片描述
  • 深度神经网络
    通过将上面所提到的卷积、激活函数、池化组合在一起,就变成下图:
    在这里插入图片描述
    通过加大网络的深度,增加更多的层,就得到了深度神经网络,如下图:
    在这里插入图片描述
  • 全连接层
    全连接层在整个卷积神经网络中起到“分类器”的作用,即通过卷积、激活函数、池化等深度网络后,再经过全连接层对结果进行识别分类。
    首先将经过卷积、激活函数、池化的深度网络后的结果串起来,如下图所示:
    在这里插入图片描述
    由于神经网络是属于监督学习,在模型训练时,根据训练样本对模型进行训练,从而得到全连接层的权重(如预测字母X的所有连接的权重)
    在这里插入图片描述
    在利用该模型进行结果识别时,根据刚才提到的模型训练得出来的权重,以及经过前面的卷积、激活函数、池化等深度网络计算出来的结果,进行加权求和,得到各个结果的预测值,然后取值最大的作为识别的结果(如下图,最后计算出来字母X的识别值为0.92,字母O的识别值为0.51,则结果判定为X)
    在这里插入图片描述
    上述这个过程定义的操作为”全连接层“(Fully connected layers),全连接层也可以有多个,如下图:
    在这里插入图片描述
  • 卷积神经网络
    将以上所有结果串起来后,就形成了一个“卷积神经网络”(CNN)结构,如下图所示:
    在这里插入图片描述

定义网络

#定义网络
import torch.nn as nn
import torch.nn.functional as F

class Net(nn.Module):
    def __init__(self):
        #nn.Module.__init__(self)
        super(Net,self).__init__()
        #卷积层
        #输入图片为单通道,输出为6通道,卷积核为5*5
        self.conv1 = nn.Conv2d(1,6,5)
        #输入图片为6通道,输出为16通道,卷积核为5*5
        self.conv2 = nn.Conv2d(6,16,5)
        #全连接层y=Wx+b
        self.fc1 = nn.Linear(16*5*5,120)
        self.fc2 = nn.Linear(120,84)
        self.fc3 = nn.Linear(84,10)
        
    def forward(self,x):
        #卷积-激活-池化
        x = F.max_pool2d(F.relu(self.conv1(x)),(2,2))
        x = F.max_pool2d(F.relu(self.conv2(x)),2)
        x = x.view(x.size()[0],-1)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x
net = Net()
print(net)

在这里插入图片描述
只要在nnModule的子类中定义了forward函数,backward函数就会被自动实现(利用Autograd)

参数查看

params = list(net.parameters())
print(len(params))

for name,parameters in net.named_parameters():
    print(name,":",parameters.size())

在这里插入图片描述

损失函数

nn实现了神经网络中大多数的损失函数,例如nn.MSELoss用来计算均方误差,nn.CrossEntropyLoss用来计算交叉熵损失。

import torch as t
from torch.autograd import Variable
input = Variable(t.randn(1,1,32,32))
output = net(input)
target = Variable(t.arange(0,10))
criterion = nn.MSELoss()
loss = criterion(output,target)
loss

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值