这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

今天来聊一聊关于 PyTorch 使用中的一些小技巧,其中可能已经接强化学习触过,或者没有接触过。如果这些小技巧对于宫颈癌使用或者学习 Pytorch 有所帮助,还希望您给点个赞,表示对我分享的肯定。

创建 tensor 直接指定其app小胖子运行设备

在创建 tensor 时候,直接指定设备,要工商银行比创建 tensor 之后,再去更改其所运行设备要节省时间。

start_time = time.time()
for _ in range(100):
  cpu_tensor = torch.ones((1000,64,64))
  gpu_tensor = cpu_tensor.cuda()
print("total time:{:.3f}".format(time.time() - start_time))
total time:10.020
start_time = time.time()
for _ in range(100):
  cpu_tensor = torch.ones((1000,64,64),device='cuda')
print("total time:{:.3f}".format(time.time() - start_time))
total time:0.015
class ExampleModel(nn.Module):
  def __init__(self):
    super().__init__()
    input_size = 2
    output_size = 3
    hidden_size = 16
    self.input_layer = nn.Linear(input_size,hidden_size)
    self.input_activation = nn.ReLU()
    self.mid_layer = nn.Linear(hidden_size,hidden_size)
    self.mid_activation = nn.ReLU()
    self.output_size = nn.Linear(hidden_size,output_size)
  def forward(self,x):
    z = self.input_layer(x)
    z = self.input_activation(z)
    z = self.mid_layer(z)
    z = self.mid_activation(z)
    out = self.output_size(z)
    return out

定义一个网络结果比较简单,网络是输入层、隐藏层和输出层所组成的简单网络结构,激活函数采用 ReLU

example_model = ExampleModel()
print(example_model)
print('Output: shape {}'.format(example_model(torch.ones([100,2])).shape))
ExampleModel(
    (input_layer): Linear(in_features=2, out_features=16, bias=True) 
    (input_activation): ReLU() 
    (mid_layer): Linear(in_features=16, out_features=16, bias=True) (mid_activation): ReLU()
    (output_size): Linear(in_features=16, out_features=3, bias=True) 
) 
Output: shape torch.Size([100, 3])

虽然这样做是可以 work,但是这并不是 better way,比较好的方式是使用 nn.Sequential 将这些层组织在一起,看起来代码比较简洁。

class ExampleSequential(nn.Module):
  def __init__(self):
    super().__init__()
    input_size = 2
    output_size = 3
    hidden_size = 16
    self.layers = nn.Sequential(
      nn.Linear(input_size,hidden_size),
      nn.ReLU(),
      nn.Linear(hidden_size,hidden_size),
      nn.ReLU(),
      nn.Linear(hidden_size,output_size)
    )
  def forward(self,x):
    out = self.layers(x)
    return out
example_sequential = ExampleSequential()
print(example_sequential)
print('Output: shape {}'.format(example_sequential(torch.ones([100,2])).shape))

在 forward 时候我们只需要调用nn.Sequential 层即可,appear无需向上面繁琐地调用多个层,appstore而且在输入网工商银行络结构时,我们也可以看到 Sequential 内部包含按一定顺序排列的层。

ExampleSequential(
(layers): Sequential( 
    (0): Linear(in_features=2, out_features=16, bias=True) 
    (1): ReLU() 
    (2): Linear(in_features=16, out_features=16, bias=True) 
    (3): ReLU() 
    (4): Linear(in_features=16, out_features=3, bias=True)
    ) 
) 
Output: shape torch.Size([100, 3])

使用 List 作为 Layer 容器带来潜在隐患

class ExampleListModel(nn.Module):
  def __init__(self):
    super().__init__()
    input_size = 2
    output_size = 3
    hidden_size = 16
    self.input_layer = nn.Linear(input_size,hidden_size)
    self.input_activation = nn.ReLU()
    self.mid_layers = []
    for _ in range(5):
      self.mid_layers.append(nn.Linear(hidden_size,hidden_size))
      self.mid_layers.append(nn.ReLU())
    self.output_layer = nn.Linear(hidden_size,output_size)
  def forward(self,x):
    z = self.input_layer(x)
    z = self.input_activation(z)
    for layer in self.mid_layers:
      z = layer(z)
    out = self.output_layer(z)
    return out

在这段代码中和上面例子差别不大,就是在隐藏层,这里堆叠了 5 个隐藏层,因为这些隐藏层结构相同apple苹果官网,所以将他们放进一个 Lapp小胖子ist 然后在 forward 时,通过遍历 List 来实现对其调用。这样做看似没毛病,供品夫人而且运行起来也是 work。

example_list_model = ExampleListModel()
print(example_list_model)
print('Output: shape {}'.format(example_list_model(torch.ones([100,2])).shape))

不过我们看看输出,这里好像是少了刚刚放进 List 的那 5 个 Linear。所以放强化学习进 ListAPP 中这些 Layer 因为没有在 Moapp小胖子del 中进行供品夫人注册,所以 Model 是无法管理和追踪这些 layer 的,所以也就会出现下面问题,当 model 更改了其所运行设备,这些更改却没法应用到这些层上。


ExampleListModel( 
(input_layer): Linear(in_features=2, out_features=16, bias=True) 
(input_activation): ReLU() 
(output_layer): Linear(in_features=16, out_features=3, bias=True) ) Output: shape torch.Size([100, 3])

不过我们想要将模型迁移运行到 GPU 上问题就来了,即使我们在创建输入 tensor 指定设备,并且通过调用模型实例的 cuda 函数,将 model 迁appear移到枸杞 cuda 设备上,因为放进到 List 中这些隐藏层并没有在 model 中进行注册,所以他们龚俊还保持运行在 CPU 设备,因而会报错。

gpu_input = torch.ones([100,2],device='cuda')
gpu_example_list_model = example_list_model.cuda()
print("Output: shape {}".format(gpu_example_list_model(gpu_input).shape))
RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cpu and cuda:0! (when checking argument for argument mat1 in method wrapper_addmm)

其实问题很好apple苹果官网appstore决,我们只要上面代码基础上进行如下公积金修改,引入nn.Sequential即可

class ExampleListModel(nn.Module):
  def __init__(self):
    super().__init__()
    input_size = 2
    output_size = 3
    hidden_size = 16
    self.input_layer = nn.Linear(input_size,hidden_size)
    self.input_activation = nn.ReLU()
    self.mid_layers = []
    for _ in range(5):
      self.mid_layers.append(nn.Linear(hidden_size,hidden_size))
      self.mid_layers.append(nn.ReLU())
    self.mid_layers = nn.Sequential(*self.mid_layers)
    self.output_layer = nn.Linear(hidden_size,output_size)
  def forward(self,x):
    z = self.input_layer(x)
    z = self.input_activation(z)
    z = self.mid_layers(z)
    # for layer in self.mid_layers:
    #   z = layer(z)
    out = self.output_layer(z)
    return out
example_list_model = ExampleListModel()
print(example_list_model)
print('Output: shape {}'.format(example_list_model(torch.ones([100,2])).shape))
ExampleListModel(
  (input_layer): Linear(in_features=2, out_features=16, bias=True)
  (input_activation): ReLU()
  (mid_layers): Sequential(
    (0): Linear(in_features=16, out_features=16, bias=True)
    (1): ReLU()
    (2): Linear(in_features=16, out_features=16, bias=True)
    (3): ReLU()
    (4): Linear(in_features=16, out_features=16, bias=True)
    (5): ReLU()
    (6): Linear(in_features=16, out_features=16, bias=True)
    (7): ReLU()
    (8): Linear(in_features=16, out_features=16, bias=True)
    (9): ReLU()
  )
  (output_layer): Linear(in_features=16, out_features=3, bias=True)
)
Output: shape torch.Size([100, 3])
gpu_input = torch.ones([100,2],device='cuda')
gpu_example_list_model = example_list_model.cuda()
print("Output: shape {}".format(gpu_example_list_model(gpu_input).shape))
Output: shape torch.Size([100, 3])

用处不小的 distributions 模块

distributions 这个包是提供了随机分布一些功能,平时也是很工作总结少用到这个包里面功能,这里拿出来跟大家分享分享,以备遇到时候不陌生,而且可以作为备用工apple苹果官网具,需要时候知道如何使用这个包里提供公积金工具。

example_model = ExampleModel()
input_tensor = torch.rand(3,2)
output = example_model(input_tensor)

Categ强化学习orical 和其采用可以用于强化学习的对动作的采样

如何使用 detach公积金 和 item

example_model = ExampleModel()
data_batches = [torch.rand((10,2)) for  _ in range(5)]
criterion = nn.MSELoss(reduce='mean')
losses = []
for batch in data_batches:
  output = example_model(batch)
  target = torch.rand((10,3))
  loss = criterion(output,target)
  losses.append(loss)
print(losses)

输出 losses

[tensor(0.2293, grad_fn=<MseLossBackward0>), tensor(0.3611, grad_fn=<MseLossBackward0>), tensor(0.2629, grad_fn=<MseLossBackward0>), tensor(0.3523, grad_fn=<MseLossBackward0>), tensor(0.3340, grad_fn=<MseLossBackward0>)]
losses = []
for batch in data_batches:
  output = example_model(batch)
  target = torch.rand((10,3))
  loss = criterion(output,target)
  losses.append(loss.item())
print(losses)
[0.28973084688186646, 0.28803274035453796, 0.22044895589351654, 0.18474963307380676, 0.19146400690078735]

如何将模型从 GPU 中移除

import gc
example_model = ExampleModel().cuda()
del example_model
gc.collect()
torch.cuda.empty_cache()

在验证之前需要调用 e枸杞val()

example_model = ExampleModel()
# Do training
example_model.eval()
# Do testing