pytorch中一些常用知识点

整理pytorch中一些常用的,容易忘记的知识点,持续更新。。。

1. Module.children() vs Module.modules()区别

简单的说就是children()输出模块的第一层子节点,modules是深度遍历输出所有的子节点

import torch.nn as nn
m = nn.Sequential(nn.Linear(2,2), 
                  nn.ReLU(),
                  nn.Sequential(nn.Sigmoid(), nn.ReLU()))

list(m.children())

[Linear(in_features=2, out_features=2, bias=True), ReLU(), Sequential(
   (0): Sigmoid()
   (1): ReLU()
 )]

list(m.modules())

[Sequential(
   (0): Linear(in_features=2, out_features=2, bias=True)
   (1): ReLU()
   (2): Sequential(
     (0): Sigmoid()
     (1): ReLU()
   )
 ), Linear(in_features=2, out_features=2, bias=True), ReLU(), Sequential(
   (0): Sigmoid()
   (1): ReLU()
 ), Sigmoid(), ReLU()]

三层嵌套的Sequential也是这样

import torch.nn as nn
m = nn.Sequential(nn.Linear(2,2), 
                  nn.ReLU(),
                  nn.Sequential(nn.Sequential(nn.ReLU()), nn.Sigmoid(), nn.ReLU()))

list(m.children())

[Linear(in_features=2, out_features=2, bias=True), ReLU(), Sequential(
   (0): Sequential(
     (0): ReLU()
   )
   (1): Sigmoid()
   (2): ReLU()
 )]

list(m.modules())

[Sequential(
   (0): Linear(in_features=2, out_features=2, bias=True)
   (1): ReLU()
   (2): Sequential(
     (0): Sequential(
       (0): ReLU()
     )
     (1): Sigmoid()
     (2): ReLU()
   )
 ), Linear(in_features=2, out_features=2, bias=True), ReLU(), Sequential(
   (0): Sequential(
     (0): ReLU()
   )
   (1): Sigmoid()
   (2): ReLU()
 ), Sequential(
   (0): ReLU()
 ), ReLU(), Sigmoid(), ReLU()]

参考:
https://discuss.pytorch.org/t/module-children-vs-module-modules/4551
https://blog.csdn.net/dss_dssssd/article/details/83958518


2. GPU训练
2.1 单GPU
image = image.cuda(n) #这里的n为GPU的编号,不填的话默认为0

device = torch.device('cuda:n' if torch.cuda.is_available() else 'cpu')#这里的n为GPU的编号
image = image.to(device)#也可以直接image = image.to(n),其中n为GPU的编号
2.2 多GPU

推荐方式一的写法
方式一

os.environ["CUDA_VISIBLE_DEVICES"] = '3, 4' #设置仅编号为3,4的GPU可见,设置之后这两个GPU的编号变为0,1
#对model 的处理
#下面的写法其实省略了最后cuda括号中的0,模型必须在第一块GPU中
model = torch.nn.DataParallel(model).cuda() #或者model = torch.nn.DataParallel(model, device_ids=[0,1]).cuda() 或者 model = torch.nn.DataParallel(model.cuda())
image = image.cuda()

方式二

device = torch.device('cuda:3')
#肯定的是,下面的写法等价于model = torch.nn.DataParallel(model, device_ids=[3,4]).to(device)
model = torch.nn.DataParallel(model, device_ids=[3,4]).cuda(3) #模型必须在第一块GPU中
images = images.to(device)

3. DataLoader

DataLoader在pytorch中用来定义自己的数据,了解其参数含义以及内部源码非常有帮助。
Pytorch的DataLoader, DataSet, Sampler之间的关系
Pytorch Sampler详解
DataLoader源代码剖析


4. 模型保存与加载

        一般模型在训练的时候需要保存checkpoint,以免程序突然中止或者由于某些原因需要接着上次的训练接着进行训练。
        一般保存模型的卷积层等参数,学习率,以及训练的epoch数。
由于多GPU训练使用了 nn.DataParallel(net, device_ids=gpu_ids) 对网络进行封装,因此在原始网络结构中添加了一层module。如果在多GPU下面训练,单GPU下进行加载可以有两种方式:
方式一:

#保存模型
state = {
            'epoch': epoch_num,
            'state_dict': retinanet.module.state_dict(),
            'best_map': best_map,
            'lr': lr,
        }
        torch.save(state, checkpoint_path) #可以用这个直接复制 shutil.copyfile()
        
#加载模型:
retinanet = model.resnet50(num_classes=20, pretrained=False) #这里的resnet是被重写了的
checkpoint = torch.load(checkpoint_path)
retinanet.load_state_dict(checkpoint['state_dict'])

或者参考:https://blog.csdn.net/u013066730/article/details/99594892

方式二:

#保存模型
state = {
            'epoch': epoch_num,
            'state_dict': retinanet.state_dict(),
            'best_map': best_map,
            'lr': lr,
        }
        torch.save(state, checkpoint_path) #可以用这个直接复制 shutil.copyfile()
        
#加载模型:先定义模型,将模型转到多GPU下面,在进行加载
retinanet = model.resnet50(num_classes=20, pretrained=False)#这里的resnet是被重写了的
checkpoint = torch.load(checkpoint_path)
retinanet = torch.nn.DataParallel(retinanet).cuda()
retinanet.load_state_dict(checkpoint['state_dict'])

方式三:

#直接保存整个模型,这样会更加占用内存
torch.save(retinanet, checkpoint_path)
#加载模型:
retinanet = torch.load(checkpoint_path) #这样会让模型直接加载为多GPU的形式,不过实际用一块GPU加载是没有问题的

参考:
【Pytorch】多GPU训练网络与单GPU训练网络保存模型的区别

PyTorch之保存加载模型


5. GPU内存占用率与利用率问题

1.增加batch size,增加GPU的内存占用率,尽量用完内存,而不要剩一半,空的内存给另外的程序用,两个任务的效率都会非常低。

2.在数据加载时候,将num_workers线程数设置稍微大一点,推荐是8,16等,且开启pin_memory=True。,直接映射数据到GPU的专用内存,减少数据传输时间。
深度学习PyTorch,TensorFlow中GPU利用率较低,CPU利用率很低,且模型训练速度很慢的问题总结与分析

6.一些常用操作

PyTorch Cookbook(常用代码段整理合集)

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个使用PyTorch实现LSTM的完整代码,覆盖了LSTM的基本知识点: ```python import torch import torch.nn as nn import torch.optim as optim # 定义LSTM模型 class LSTMModel(nn.Module): def __init__(self, input_size, hidden_size, num_layers, output_size): super(LSTMModel, self).__init__() self.hidden_size = hidden_size self.num_layers = num_layers self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True) self.fc = nn.Linear(hidden_size, output_size) def forward(self, x): # 初始化hidden和cell状态 h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device) c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device) # LSTM层前向传播 out, _ = self.lstm(x, (h0, c0)) # 取最后一个时间步的hidden状态作为模型输出 out = self.fc(out[:, -1, :]) return out # 定义输入、输出和超参数 input_size = 10 hidden_size = 20 num_layers = 2 output_size = 1 batch_size = 16 seq_len = 5 # 随机生成输入数据和标签 x = torch.randn(batch_size, seq_len, input_size) y = torch.randn(batch_size, output_size) # 初始化模型并计算模型输出 model = LSTMModel(input_size, hidden_size, num_layers, output_size) output = model(x) # 计算损失并进行反向传播和参数更新 criterion = nn.MSELoss() loss = criterion(output, y) optimizer = optim.Adam(model.parameters(), lr=0.01) optimizer.zero_grad() loss.backward() optimizer.step() ``` 以上代码实现了一个具有2层LSTM的模型,输入数据形状为(batch_size, seq_len, input_size),输出数据形状为(batch_size, output_size)。模型的输出是最后一个时间步的hidden状态。损失函数采用均方误差损失函数,并采用Adam优化器进行参数更新。 下面是各个知识点的详细解释: 1. 模型定义:这里定义了一个继承自`nn.Module`的LSTM模型,其包括一个LSTM层和一个全连接层。在`__init__`方法,我们定义了LSTM层的参数,包括输入维度`input_size`、隐藏层维度`hidden_size`、层数`num_layers`和是否批次优先`batch_first`。在`forward`方法,我们首先初始化hidden和cell状态,然后将输入`x`传入LSTM层进行前向传播,取最后一个时间步的hidden状态作为模型输出,最后通过全连接层将输出映射到指定的输出维度`output_size`上。 2. 模型训练:我们首先随机生成输入数据`x`和标签`y`,然后初始化LSTM模型并将`x`传入模型得到输出`output`。接着我们定义损失函数为均方误差损失函数,并计算出当前模型对于输入数据`x`的损失`loss`。然后我们定义优化器为Adam优化器,并调用`optimizer.zero_grad()`方法清空之前的梯度。接着我们调用`loss.backward()`方法进行反向传播计算梯度,并调用`optimizer.step()`方法进行参数更新。最终我们得到了优化后的模型。 3. 数据形状:LSTM模型的输入数据形状为(batch_size, seq_len, input_size),其`batch_size`表示批次大小,`seq_len`表示时间步数,`input_size`表示每个时间步的输入维度。LSTM模型的输出数据形状为(batch_size, output_size),其`output_size`表示输出维度。在本例,我们随机生成了输入数据和标签,输入数据形状为(16, 5, 10),标签形状为(16, 1)。 4. 参数初始化:在模型定义时,我们没有显式地初始化模型参数,这是因为PyTorch默认会使用一种叫做Xavier初始化的方法来初始化参数。Xavier初始化方法可以使得参数的均值和方差都比较均匀,从而使得模型的表现更好。如果需要手动初始化参数,可以调用`nn.init`的函数进行初始化。 5. 模型输出:在本例,我们将LSTM模型的输出定义为最后一个时间步的hidden状态。这是因为LSTM模型可以通过hidden和cell状态来记忆和传递信息,而最后一个时间步的hidden状态包含了所有时间步的信息,因此可以作为模型的输出。如果需要使用其他方法来获得模型输出,可以根据具体需求进行修改。 6. 损失函数:损失函数用于衡量模型对于训练数据的拟合程度,本例我们使用了均方误差损失函数。均方误差损失函数是最常用的损失函数之一,其计算方式为预测值与真实值之间的差的平方和,并将其除以样本数量。如果需要使用其他损失函数,可以根据具体需求进行修改。 7. 优化器:优化器用于更新模型参数,本例我们使用了Adam优化器。Adam优化器是一种基于梯度的优化方法,其可以自适应地调整学习率,并且具有较快的收敛速度和较好的性能。如果需要使用其他优化器,可以根据具体需求进行修改。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值