• PyTorch简明教程 | 1-基础操作和CNN简介


    from __future__ import print_function
    import torch
    
    
    ##1 基本操作
    #构建tensor
    x = torch.empty(5, 3)
    x = torch.rand(5, 3)
    x = torch.zero(5, 3, dtype=torch.long)
    
    #Operation
    y = torch.rand(5, 3)
    torch.add(x, y)
    result = torch.empty(5, 3)
    torch.add(x, y, out=result) #x+y结果放到result里
    y.add_(x)
    x.copy_(y)
    
    #Tensor变换
    print(x[:, 1]) #打印第一列
    x = torch.randn(4, 4)
    y = x.view(16)
    z = x.view(-1, 8) #-1意思是让torch自己推断第一维大小
    
    ##torch几个维度查看和变换的函数
    torch.size()
    b = a.view(-1, 3, 2)  #前后尺寸要一致
    
    torch.squeeze() / torch.unsqueeze() 
    #torch.squeeze(n)函数表示压缩tensor中第n维为1的维数
    >>> b.squeeze(2).size()
    torch.Size([1, 3, 2])
    >>> b.squeeze(0).size()
    torch.Size([3, 2])
    #torch.unsqueeze(n)则是在第n维增加一个维数=1
    
    torch.permute() #按照自己期望的位置重新排序
    permute(2, 0, 1)  #注意数字是维度的index而不是数值
    
    #numpy互转
    #np和torch共享地址,修改一个会改变另一个
    a = np.ones(5)
    b = torch.from_numpy(a)
    np.add(a, 1, out=a)
    print(a)
    # [2. 2. 2. 2. 2.]
    print(b)
    # tensor([ 2.,  2.,  2.,  2.,  2.], dtype=torch.float64)
    
    #CUDA tensor
    if torch.cuda.is_available():
        device = torch.device("cuda")            # 一个CUDA device对象。
        y = torch.ones_like(x, device=device)    # 直接在GPU上创建tensor
        x = x.to(device)                         # 也可以使用``.to("cuda")``把一个tensor从CPU移到GPU上
        z = x + y
        print(z)
        print(z.to("cpu", torch.double))         # ``.to``也可以在移动的过程中修改dtype
    
    ##2 自动求导
    # requires_grad是True,那么PyTorch就会追踪所有与之相关的operation。反向传播backward()
    # 在测试时,with torch.no_grad() 不计算梯度
    # Function类,与tensor相互连接从而形成一个有向无环图,记录历史。每个tensor有一个grad_fn属性来引用创建这个tensor的Function
    
    x = torch.ones(2, 2, requires_grad=True)
    
    #梯度
    out.backward()
    print(x.grad)  #d(out)/dx
    
    print((x ** 2).requires_grad)
    
    with torch.no_grad():  #用来停止梯度计算
        print((x ** 2).requires_grad)
    
    
    ##3 神经网络
    #torch.nn来创建
    
    #1)定义网络
    import torch
    import torch.nn as nn
    # import torch.nn.function as F
    
    class Net(nn.Module):
        def __init__(self):
            super(Net, self).__init__()
            # 输入是1个通道的灰度图,输出6个通道(feature map),使用5x5的卷积核
            self.conv1 = nn.Conv2d(1, 6, 5)
            # 第二个卷积层也是5x5,有16个通道
            self.conv2 = nn.Conv2d(6, 16, 5)
            #全连接
            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 = view(-1, self.num_flat_features(x))
            x = F.relu(self.fc1(x))
            x = F.relu(self.fc2(x))
            x = self.fc3(x)
            return x
    
            def num_flat_features(self, x):
                size = x.size()[1:]  # 除了batch维度之外的其它维度。
                num_features = 1
                for s in size:
                    num_features *= s
                return num_features
    
    net = Net()
    print(net)
    
    params = list(net.parameters()) #得到模型所有的参数
    print(len(params))
    print(params[0].size())  # conv1的weight
    
    
    #2)测试网络
    input = torch.randn(1, 1, 32, 32)
    out = net(input)
    print(out)
    
    #清空梯度
    net.zero_grad()
    out.backward(torch.randn(1, 10))
    #注意:torch.nn只支持mini-batches的输入。整个torch.nn包的输入都必须第一维是batch,即使只有一个样本也要弄成batch是1的输入。
    #nn.Conv2d的输入是一个4D的Tensor,shape是nSamples x nChannels x Height x Width。
    #如果你只有一个样本(nChannels x Height x Width),那么可以使用input.unsqueeze(0)来增加一个batch维。
    
    #3)损失函数
    output = net(input)
    criterion = nn.MSELoss()
    loss = criterion(output, target)
    
    #4)计算梯度
    net.zero_grad()     # 清掉tensor里缓存的梯度值。
    loss.backward()
    
    #5)更新参数
    import torch.optim as optim
    # 创建optimizer,需要传入参数和learning rate
    optimizer = optim.SGD(net.parameters(), lr=0.01)
    
    #清除梯度,optimizer.zero_grad()一次清除所有。
    optimizer.zero_grad()
    output = net(input)
    loss = criterion(output, target)
    loss.backward()
    optimizer.step()
  • 相关阅读:
    使用Stream流递归 组合树形结构
    MySQL 8 通用表表达式
    sa-token 权限认证
    先更新缓存还是先更新数据库?
    钉钉 回调事件 消息加解密
    commons-io
    stream和parallelstream的区别
    消除if...else
    springboot 扩展xml请求和响应
    springboot admin 邮箱
  • 原文地址:https://www.cnblogs.com/geo-will/p/13546546.html
Copyright © 2020-2023  润新知