pytorch基础学习(5)

  1. 最常见的是nn.Sequential容器,它以若若干继承了nn.Module类的对象为参数进行构造,将它们按传入顺序组合起来,在forward时会按这个顺序依次调用,当然要保证前一模块的输出能适合于下一模块的输入才行。
  2. 使用nn.Module类创建的模块,可以用.parameters()或者.named_parameters()返回 其内的所有参数的迭代器
    print(list(net.parameters()))
    print('-' * 10)
    print(dict(net.named_parameters()))
    其中.named_parameters()还能看到参数名,默认情况下会使用所在的层数+参数类型的方式,从0层开始编号。
  3. 模块之间通过嵌套组合会形成树形结构,使用.childern()可以获取其直接孩子结点,使用.modules()可以获取其所有子结点:
    print(list(my_net.children()))  # 直接孩子
    print('-' * 10)
    print(list(my_net.modules()))  # 所有孩子
  4. 设备切换:
    1. 使用.to(device)可以在具体的CPU/GPU上切换,这会将其所有子模块也一起转移过去运行。
    2. 注意,模块的.to(device)是原地操作并返回自己的引用,而Tensor的.to(device)不会在当前Tensor上操作,返回的才是在目标设备上对应创建的Tensor。
  5. 检查点:
    1. 在训练前可以检查是否有检查点文件,使用torch.load()载入检查点文件,然后传入net.load_state_dict()中网络模型设置参数:
      net.load_state_dict(torch.load('ckpt.mdl'))
    2. 在训练过程中,每隔一定的迭代次数可以保存一下检查点,将当前网络模型的状态传进去:
      torch.save(net.state_dict(), 'ckpt.mdl')
  6. 为网络使用.train()方法切换到训练模式,使用.eval()方法切换到测试模式。
  7. 如果在继承nn.Module类来实现模块时,出现需要操作Tensor的部分,那么应当使用nn.Parameters将其包装起来,而不应直接使用Tensor。如果直接使用Tensor,那么没法用.parameters()获取到所有参数,也就没法直接传给优化器去记录要优化的包括这些参数了:
    # 线性层的参数w和b,对w而言输出维度放在前面:计算的时候:x = x @ self.w.t() + self.b
    self.w = nn.Parameter(torch.randn(outp, inp))
    self.b = nn.Parameter(torch.randn(outp))
    使用nn.Parameters包装Tensor时,自动设置了requires_grad=True,也即默认情况下认为它是反向传播优化的参数之一。
  8. 如果发生梯度爆炸,可以进行梯度裁剪:

    model.zero_grad()
    loss.backward()
    for p in model.parameters():
        # print(p.grad.norm())  # 查看参数p的梯度
        torch.nn.utils.clip_grad_norm_(p, 10)  # 将梯度裁剪到小于10
    optimizer.step()

猜你喜欢

转载自blog.csdn.net/weixin_45647721/article/details/128163597