pytorch基础知识

 1. 动态图和静态图的区别?自动微分是什么?

 一文详解pytorch的“动态图”与“自动微分”技术 - 知乎

2. 教程

https://pytorch.apachecn.org/#/docs/1.7/043

搭建神经网络

  1. 定义神经网络,得到一个model
  2. 定义损失函数: torch.nn.xxLoss
  3. 定义优化器,构造一个optimizer对象: torch.optim.xx

训练神经网络

  1. 正向传播
  2. 根据损失函数计算loss
  3. 反向传播:loss.backward()
  4. 梯度下降:optimizer.step()
  5. 梯度归零:optimizer.zero_grad()

张量

  1. 生成张量
    1. torch.tensor(data)
    2. torch.from_numpy(np_array)
    3. torch.xx_like(data, dtype=torch.float) # 重写 data 的数据类型
    4. torch.xx(shape) 如:torch.rand(shape)
  2. 属性
    1. tensor.shape、tensor.dtype、tensor.device
  3. 运算(tensor = tensor.to('cuda')  # tensor导入GPU内)
    1. 索引和切片
    2. 拼接: torch.cat
    3. 逐个元素相乘: *, 矩阵乘法:@
    4. inplace 操作:如: tensor.add_ (省内存,但是易出错)
  4. numpy <--> torch (共内存区域, 同时改变)
    1. 张量变换为Numpy array: tensor.numpy()
    2. Numpy array数组转为张量:torch.from_numpy(xx)

自动求导 (Autograd): PyTorch 的自动差分引擎

loss = (prediction - labels).sum()
loss.backward() # backward pass

当我们在误差张量上调用.backward() 时,开始反向传播。 然后,Autograd 会为每个模型参数计算梯度并将其存储在参数的.grad属性中。 

optim.step() #gradient descent

调用.step()启动梯度下降。 优化器通过.grad中存储的梯度来调整每个参数。


创建张量要求对它求导:

a = torch.tensor([2., 3.], requires_grad=True)

loss.backward() 两种情况:

  1. 若loss 是向量:
external_grad = torch.tensor([1., 1.])
loss.backward(gradient=external_grad)
# gradient是与loss形状相同的张量,它表示loss相对于本身的梯度,都是1

        2. 若loss 是标量:

loss.sum().backward()

计算图:

        概念:有向无环图。像一棵倒立的数。下面是输入张量,根是输出张量。

问题1:什么是动态图?

        每次 .backward() 调用之后, 自动构建新图。因此可以向python一样断点调试等。

即使只有一个输入张量具有 requires_grad=True操作的输出张量也将需要梯度。

 .requires_grad = False : 冻结参数, 用于微调模型。

torch.no_grad() 中的上下文管理器可以冻结参数。

x = torch.tensor([1], requires_grad=True)
with torch.no_grad():
    y = x * 2
y.requires_grad # False
@torch.no_grad()
def doubler(x):
    return x * 2
z = doubler(x)
z.requires_grad # False

神经网络:torch.nn

定义网络:

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        # 自定义的层
        # self.层名 = ...

    def forward(self, x):
        # 操作
        return x

net = Net()
print(net)

只需要定义forward函数,就可以使用autograd为您自动定义backward函数(计算梯度

模型的可学习参数由net.parameters()返回

torch.nn 仅支持小批量,不支持单个样本的输入。

例如,nn.Conv2d将采用(b,c,h,w)的 4D 张量。

如果只有一个样本,只需使用input.unsqueeze(0)添加一个假批量尺寸(1,c,h,w)

损失函数:nn.MSELoss


CV: torchvision包有:torchvision.datasetstorch.utils.data.DataLoader

GPU上训练

  1. net.to(device)
  2. inputs, labels = data[0].to(device), data[1].to(device)

定义新的 Autograd 函数

可以通过定义torch.autograd.Function的子类并实现forwardbackward函数来轻松定义自己的 Autograd 运算符。 然后,我们可以通过构造实例并像调用函数一样调用新的 Autograd 运算符,并传递包含输入数据的张量。

class LegendrePolynomial3(torch.autograd.Function):

    """

    We can implement our own custom autograd Functions by subclassing

    torch.autograd.Function and implementing the forward and backward passes

    which operate on Tensors.

    """

    @staticmethod

    def forward(ctx, input):

        """

        In the forward pass we receive a Tensor containing the input and return

        a Tensor containing the output. ctx is a context object that can be used

        to stash information for backward computation. You can cache arbitrary

        objects for use in the backward pass using the ctx.save_for_backward method.

        """

        ctx.save_for_backward(input)

        return 0.5 * (5 * input ** 3 - 3 * input)


    @staticmethod

    def backward(ctx, grad_output):

        """

        In the backward pass we receive a Tensor containing the gradient of the loss

        with respect to the output, and we need to compute the gradient of the loss

        with respect to the input.

        """

        input, = ctx.saved_tensors

        return grad_output * 1.5 * (5 * input ** 2 - 1)

使用:

       P3 = LegendrePolynomial3.apply

       y_pred = a + b * P3(c + d * x)

可以使用常规的 Python 流控制来实现循环(如for),并且可以通过在定义forward时简单地多次重复使用相同的参数来实现权重共享


使用Dataset

TensorDataset是一个数据集包装张量。 通过定义索引的长度和方式,这也为我们提供了沿张量的第一维进行迭代,索引和切片的方法。

from torch.utils.data import TensorDataset

train_ds = TensorDataset(x_train, y_train)

xb,yb = train_ds[i*bs : i*bs+bs]


使用DataLoader

DataLoader负责批量管理, DataLoader使迭代迭代变得更加容易。

from torch.utils.data import DataLoader

train_dl = DataLoader(train_ds, batch_size=bs)

for xb,yb in train_dl:

pred = model(xb)


# 验证集

valid_ds = TensorDataset(x_valid, y_valid)

valid_dl = DataLoader(valid_ds, batch_size=bs * 2)

总是在训练之前调用model.train(),并在推理之前调用model.eval(),因为诸如nn.BatchNorm2dnn.Dropout之类的层会使用它们,以确保这些不同阶段的行为正确。

    model.eval()

    with torch.no_grad():

        valid_loss = sum(loss_func(model(xb), yb) for xb, yb in valid_dl)

创建fit()和get_data()

def loss_batch(model, loss_func, xb, yb, opt=None):

    loss = loss_func(model(xb), yb)

    if opt is not None:

        loss.backward()

        opt.step()

        opt.zero_grad()

return loss.item(), len(xb)



import numpy as np

def fit(epochs, model, loss_func, opt, train_dl, valid_dl):

    for epoch in range(epochs):

        model.train()

        for xb, yb in train_dl:

            loss_batch(model, loss_func, xb, yb, opt)

        model.eval()

        with torch.no_grad():

            losses, nums = zip(

                *[loss_batch(model, loss_func, xb, yb) for xb, yb in valid_dl]

            )

        val_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)

        print(epoch, val_loss)

def get_data(train_ds, valid_ds, bs):

    return (

        DataLoader(train_ds, batch_size=bs, shuffle=True),

        DataLoader(valid_ds, batch_size=bs * 2),

)

train_dl, valid_dl = get_data(train_ds, valid_ds, bs)

model, opt = get_model()

fit(epochs, model, loss_func, opt, train_dl, valid_dl)

nn.Sequential

Sequential对象以顺序方式运行其中包含的每个模块

从给定的函数定义自定义层, 然后在使用Sequential定义网络时可以使用该层。


 1. Conv2d

CLASS torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros', device=None, dtype=None)

dilation: Default: 1

2. MaxPool2d

CLASS torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PyTorch是一个开源的机器学习框架,主要用于构建深度学习模型。下面是一些PyTorch基础代码知识: 1. 张量(Tensor)操作: - 创建张量:使用`torch.tensor()`函数可以创建一个张量。 - 张量的属性:可以使用`.shape`属性获取张量的形状,使用`.dtype`属性获取张量的数据类型。 - 张量的运算:可以进行加减乘除等基本运算,也可以使用函数`torch.add()`, `torch.sub()`, `torch.mul()`, `torch.div()`等进行运算。 2. 自动求导(Autograd): - 自动求导:PyTorch使用自动求导机制来计算梯度。要启用自动求导,只需将`requires_grad=True`设置为张量的参数。 - 梯度计算:通过调用`.backward()`方法可以计算张量的梯度。 - 禁用梯度跟踪:可以使用`torch.no_grad()`上下文管理器来禁用梯度的跟踪。 3. 神经网络模块: - 搭建网络:使用`torch.nn.Module`类可以定义神经网络模块。需要实现两个方法:`__init__()`和`forward()`。 - 参数优化:使用`torch.optim`模块可以定义优化器,如SGD、Adam等。可以通过`optimizer.zero_grad()`清零梯度,`optimizer.step()`更新参数。 4. 数据加载: - 数据集:可以使用`torch.utils.data.Dataset`类来定义自己的数据集。 - 数据加载器:使用`torch.utils.data.DataLoader`类可以创建数据加载器,用于批量加载数据。 5. 训练模型: - 训练循环:通常使用两个嵌套的循环来训练模型,外循环用于迭代训练轮数,内循环用于迭代数据批次。 - 前向传播和反向传播:在内循环中,通过前向传播计算输出,然后计算损失,最后使用反向传播计算梯度并更新参数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

理心炼丹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值