Pytorch基础(学习笔记)

1.Tensor

Tensor和Numpy的ndarrays类似,但Tensor可以使用GPU进行加速。

下划线函数的inplace操作

注意,函数名后面带下划线_ 的函数会修改Tensor本身。

import torch as t
x = t.rand([2,2])
y = t.rand([2,2])
print(y)
y.add(x)
print(y) # 不变
y.add_(x)
print(y) # 变化
# 结果:
tensor([[0.9616, 0.9189],
        [0.5522, 0.4739]])
tensor([[0.9616, 0.9189],
        [0.5522, 0.4739]])
tensor([[1.1670, 1.2176],
        [1.2937, 1.0055]])

Tensor和Numpy的数组之间的互操作

可直接转换,共享内存

import torch as t
import numpy as np

a_tensor = t.ones(5)
b_np = np.ones(5)
print(a_tensor)
print(b_np)
a_np = a_tensor.numpy()
print(a_np)         # tensor->numpy
print(t.from_numpy(b_np))  # numpy->tensor

a_tensor.add_(1)    # 修改tensor
print(a_tensor) 
print(a_np)         # 对应的numpy也同时变化
# 结果
tensor([1., 1., 1., 1., 1.])
[1. 1. 1. 1. 1.]
[1. 1. 1. 1. 1.]
tensor([1., 1., 1., 1., 1.], dtype=torch.float64)
tensor([2., 2., 2., 2., 2.])
[2. 2. 2. 2. 2.]

Tensor可通过.cuda 方法转为GPU的Tensor,从而享受GPU带来的加速运算。

autograd.Variable(新版本已和Tensor合并)

autograd.Variable是Autograd中的核心类,它简单封装了Tensor,并支持几乎所有Tensor有的操作。Tensor在被封装为Variable之后,可以调用它的.backward实现反向传播,自动计算所有梯度。其数据结构包括:变量data,梯度grad,梯度函数grad_fn。

from torch.autograd import Variable

x = Variable(t.rand(2, 2), requires_grad = True)
y = x.sum()
y.backward()
print(x)
print(y)
print(y.grad_fn)
print(x.grad)
# 注意:grad在反向传播过程中是累加的(accumulated),这意味着每一次运行反向传播,梯度都会累加之前的梯度,所以反向传播之前需把梯度清零。
x.grad.data.zero_()
# 结果
tensor([[0.1720, 0.5072],
        [0.5559, 0.0120]], requires_grad=True)
tensor(1.2471, grad_fn=<SumBackward0>)
<SumBackward0 object at 0x000000000287CEC8>
tensor([[1., 1.],
        [1., 1.]])

2.神经网络 torch.nn

Autograd实现了反向传播功能,但是直接用来写深度学习的代码在很多情况下还是稍显复杂,torch.nn是专门为神经网络设计的模块化接口。nn构建于 Autograd之上,可用来定义和运行神经网络。nn.Module是nn中最重要的类,可把它看成是一个网络的封装,包含网络各层定义以及forward方法,调用forward(input)方法,可返回前向传播的结果。

网络定义

import torch.nn as nn
import torch.nn.functional as F
import torch as t

# 需要继承nn.Module
class Net(nn.Module):
    # 可学习参数的层放在构造函数__init__中
    def __init__(self):
        # nn.Module子类的函数必须在构造函数中执行父类的构造函数
        # 下式等价于nn.Module.__init__(self)
        super(Net, self).__init__()

        self.conv1 = nn.Conv2d(1, 6, 5)
        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)

    # 不具有可学习的参数,则既可以放在构造函数中,也可以不放,但建议直接放在forward中
    # 定义了forward函数,backward函数就会自动被实现
    def forward(self, x):
        # 输入必须是4维的,形如 nSamples×nChannels×Height×Width 。
        x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        # reshape,‘-1’表示自适应
        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)

# 查看所有参数
params = list(net.parameters())
print("参数个数",len(params))

# 参看参数名称及大小
for name,parameters in net.named_parameters():
    print(name,':',parameters.size())

# 测试网络输出
input = t.randn(1, 1, 32, 32)
out = net(input)
print("网络输出",out.size())

这里的forward方法中,使用了torch.nn.functional,torch.nn中大多数layer在torch.nn.funtional中都有一个与之对应的函数。二者的区别在于:torch.nn.Module中实现layer的都是一个特殊的类如。如果模型有可学习的参数,最好使用nn.Module对应的相关layer,否则二者都可以使用,没有什么区别。

训练过程

import torch.optim as optim
#新建一个优化器,指定要调整的参数和学习率
optimizer = optim.SGD(net.parameters(), lr = 0.01)

# 在训练过程中
# 先梯度清零(与net.zero_grad()效果一样)
optimizer.zero_grad() 

# 计算损失
output = net(input)
loss = criterion(output, target)

#反向传播
loss.backward()

#更新参数
optimizer.step()

pytorch更新内容可参考:PyTorch 重磅更新,不只是支持 Windows

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值