zoukankan      html  css  js  c++  java
  • Pytorch(一)

    一、Pytorch介绍

    Pytorch 是Torch在Python上的衍生物

    和Tensorflow相比:

    Pytorch建立的神经网络是动态的,而Tensorflow建立的神经网络是静态的

    Tensorflow的高度工业化,它的底层代码很难看懂

    官网:http://pytorch.org/

    Pytorch主要有两个模块:

    一个是torch,一个是torchvision,torch是主模块,用来搭建神经网络。torchvision是辅模块,有数据库,还有一些已经训练好的神经网络等着你直接用比如(VGG,AlexNet,ResNet)


    二、基础知识

    1.与Numpy交互

    (1)数据转换

    import torch
    import numpy as np
    
    # 创建一个np array
    a = np.array([[1,2], [3,4]])
    b = torch.from_numpy(a)      # 根据np array创建torch 张量
    c = b.numpy()                # 根据张量, 导出np array
    (2)数据运算

    torch中tensor的运算与numpy array运算相似,比如

    np.abs()--->torch.abs()

    np.sin()---->torch.sin()等

    2.变量Variable

    image

    (1)Variable组成

    在Torch中Variable由三部分组成:data部分是Torch的Tensor,grad部分是这个变量的梯度缓存区,creator部分是这个Variable的创造节点,如果用一个Variable进行计算,那返回的也是同类型的Variable

    (2)使用

    导入

    import torch

    from torch.autograd import Variable

    定义Variable的同时有一项requires_grad是关于参不参与误差反向传播,要不要计算梯度

    注意Variable 和Tensor的区别:

    Variable计算时,它在后台默默地搭建着一个庞大地系统,叫做计算图。computional graph将所有地计算步骤(节点)都连接起来,最后进行误差反向传递地时候,一次性将所有Variable里面地修改梯度都计算出来,而tensor只是一个数据结构。

    构建计算图

    y = w * x + b # y = 2 * x + 3

    (3)计算梯度

    # 对y求梯度
    y.backward()
    
    # 打印一下各个变量的梯度
    print(x.grad)    # y对x的梯度: x.grad = 2 
    print(w.grad)    # y对w的梯度: w.grad = 1 
    print(b.grad)    # y对b的梯度: b.grad = 1

    (4)Variable里面地数据

    直接print(variable)只会输出Variable形式地数据,在很多时候是用不了地(比如想要用plt绘图),所以我们要转换一下,将它变成tensor形式

    获取tensor数据:Print(variable.data),也可以将其转为numpy形式:print(variable.data.numpy())

    3.Pytorch中的激活函数

    导入包:import torch.nn.functional as F

    平时常用的:relu、sigmoid,tanh,softplus

    激活函数:激活函数的输入与输出都是variable

    4.Pytorch中的数据加载器和batch

    (1)生成数据生成并构建Dataset子集

    import torch
    import torch.utils.data as Data
    
    torch.manual_seed(1)    
    
    BATCH_SIZE = 5
    
    x = torch.linspace(1, 10, 10)       # 输入数据
    y = torch.linspace(10, 1, 10)       # 输出数据
    
    # 打包成TensorDataset对象,成为标准数据集
    torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y)


    (2)生成batch数据

    PyTorch用类torch.utils.data.DataLoader加载数据,并对数据进行采样,生成batch迭代器

    # 创建数据加载器
    loader = Data.DataLoader(
        dataset=torch_dataset,      # TensorDataset类型数据集
        batch_size=BATCH_SIZE,      # mini batch size
        shuffle=True,               # 设置随机洗牌
        num_workers=2,              # 加载数据的进程个数
    )
    
    for epoch in range(3):   # 训练3轮
        for step, (batch_x, batch_y) in enumerate(loader):  # 每一步
            # 在这里写训练代码...
            print('Epoch: ', epoch, '| Step: ', step, '| batch x: ', batch_x.numpy(), '| batch y: ', batch_y.numpy())


    6.GPU运算

    Pytorch中使用GPU计算简单,通过调用.cuda()方法,很容易实现GPU支持

    torch.cuda会记录当前选择的GPU,并且分配的所有CUDA张量将在上面创建

    可以使用torch.cuda.device上下文管理器更改所选设备

    7.加载预训练模型

    import torchvision
    
    # 下载并加载resnet.
    resnet = torchvision.models.resnet18(pretrained=True)
    
    # 如果你只想要finetune模型最顶层的参数
    for param in resnet.parameters():
        # 将resent的参数设置成不更新
        param.requires_grad = False
    
    # 把resnet的全连接层fc 替换成自己设置的线性层nn.Linear
    # 比如说,输入维度是resnet.fc.in_features, 输出是100维
    resnet.fc = nn.Linear(resnet.fc.in_features, 100) 
    
    # 测试一下
    images = Variable(torch.randn(10, 3, 256, 256))
    outputs = resnet(images)
    print (outputs.size())   # (10, 100)

    8.简单回归

    import torch
    from torch.autograd import Variable
    import matplotlib.pyplot as plt
    
    torch.manual_seed(1)
    
    x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)  # 张量 x: (100, 1)
    y = x.pow(2) + 0.2*torch.rand(x.size())                 # 加入噪声的张量 y: (100, 1)
    
    # 将张量转为 Variable
    x, y = Variable(x), Variable(y)
    
    # 画一下
    plt.scatter(x.data.numpy(), y.data.numpy())
    plt.show()
    
    class Net(torch.nn.Module):
        def __init__(self, n_feature, n_hidden, n_output):
            super(Net, self).__init__()
            self.hidden = torch.nn.Linear(n_feature, n_hidden)   # 隐层
            self.relu = torch.nn.ReLU()                          # 选择激活层
            self.predict = torch.nn.Linear(n_hidden, n_output)   # 输出层
    
        def forward(self, x):
            x = self.hidden(x)                                   # 计算隐层
            x = self.relu(x)                                     # 计算激活层
            x = self.predict(x)                                  # 输出层
            return x
    net = Net(n_feature=1, n_hidden=10, n_output=1)              # 定义网络
    print(net)
                                                  #打印网络结构
    # 选择损失函数和优化方法
    loss_func = torch.nn.MSELoss()
    optimizer = torch.optim.SGD(net.parameters(), lr=0.2)
    plt.ion()   # hold住图
    for t in range(100):
        prediction = net(x)                                      # 用网络预测一下
        loss = loss_func(prediction, y)                          # 计算损失
        optimizer.zero_grad()                                    # 清除上一步的梯度
        loss.backward()                                          # 反向传播, 计算梯度
        optimizer.step()                                         # 优化一步
        if t % 5 == 0:
            plt.cla()
            plt.scatter(x.data.numpy(), y.data.numpy())
            plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
            plt.text(0.5, 0, 'Loss=%.4f' % loss.data[0], fontdict={'size': 20, 'color': 'red'})
            plt.pause(1)
            print(t)
    plt.ioff()
    plt.show()

    9.快速构建序列网络

    torch.nn.Sequential是一个Sequential容器,模块将按照构造函数中传递的顺序添加到模块中。另外 ,也可以传入一个有序模块。

    # Sequential使用实例
    
    model = nn.Sequential(
              nn.Conv2d(1,20,5),
              nn.ReLU(),
              nn.Conv2d(20,64,5),
              nn.ReLU()
            )
    
    # Sequential with OrderedDict使用实例
    model = nn.Sequential(OrderedDict([
              ('conv1', nn.Conv2d(1,20,5)),
              ('relu1', nn.ReLU()),
              ('conv2', nn.Conv2d(20,64,5)),
              ('relu2', nn.ReLU())
            ]))

    为了方便比较,我们先用普通方法搭建一个神经网络。


    import torch
    
    
    # 继承方式实现, 能够自定义forward
    class ModuleNet(torch.nn.Module):
        def __init__(self, n_feature, n_hidden, n_output):
            super(ModuleNet, self).__init__()
            self.hidden = torch.nn.Linear(n_feature, n_hidden)   # 隐层
            self.relu = torch.nn.ReLU()                          # 选择激活层
            self.predict = torch.nn.Linear(n_hidden, n_output)   # 输出层
    
        def forward(self, x):
            x = self.hidden(x)                                   # 计算隐层
            x = self.relu(x)                                     # 计算激活层
            x = self.predict(x)                                  # 输出层
            return x
    
    module_net = ModuleNet(1, 10, 1)

    上面ModuleNet继承了一个torch.nn.Module中的神经网络结构, 然后对其进行了修改;接下来我们来使用torch.nn.Sequential来快速搭建一个神经网络。

    #用序列化工具, 给予Pytorch 内部集成的网络层 快速搭建
    seq_net = torch.nn.Sequential(
        torch.nn.Linear(1, 10),
        torch.nn.ReLU(),
        torch.nn.Linear(10, 1)
    )

    我们来打印一下2个神经网络的数据,查看区别:

    print(module_net)     # 打印网络结构
    """
    ModuleNet (
      (hidden): Linear (1 -> 10)
      (relu): ReLU ()
      (predict): Linear (10 -> 1)
    )
    """
    
    print(seq_net)        # 打印网络结构
    """
    Sequential (
      (0): Linear (1 -> 10)
      (1): ReLU ()
      (2): Linear (10 -> 1)
    )
    """



  • 相关阅读:
    codeforces 459 B.Pashmak and Flowers 解题报告
    poj 1789 Truck History 解题报告
    poj 1258 Agri-Net 解题报告
    poj 1860 Currency Exchange 解题报告
    poj 1094 Sorting It All Out 解题报告
    poj 3368 Frequent values 解题报告
    hdu 1548 A strange lift 解题报告
    BestCoder4 1002 Miaomiao's Geometry (hdu 4932) 解题报告
    hdu 1400 Mondriaan's Dream 解题报告
    打电话主要代码(意图用法)
  • 原文地址:https://www.cnblogs.com/yifdu25/p/8975250.html
Copyright © 2011-2022 走看看