Python 在批量梯度下降和Q-学习中使用辍学的困惑

Python 在批量梯度下降和Q-学习中使用辍学的困惑,python,machine-learning,pytorch,Python,Machine Learning,Pytorch,我正在使用PyTorch并将退出层添加到我的内层 class MLP(nn.Module): #def __init__(self, n_inputs, n_action, n_hidden_layers=2, hidden_dim=8, drop=0.25): def __init__(self, console_file, n_inputs, n_action, layers_list, drop=0.25): super(MLP, self).__init__()

我正在使用PyTorch并将退出层添加到我的内层

class MLP(nn.Module):
  #def __init__(self, n_inputs, n_action, n_hidden_layers=2, hidden_dim=8, drop=0.25):
  def __init__(self, console_file, n_inputs, n_action, layers_list, drop=0.25):
    super(MLP, self).__init__()
    print("Layers structure:")
    console_file.write("Layers structure:\n")
    print(f"inputs: {n_inputs}")
    console_file.write(f"inputs: {n_inputs}\n")
    self.layers = []
    for i, layer_size in enumerate(layers_list):
      if i == 0:
        layer = nn.Linear(n_inputs, layer_size)
      else:
        layer = nn.Linear(layers_list[i-1], layer_size)
      self.layers.append(layer)
      print(f"layer {i}: {layer_size}")
      console_file.write(f"layer {i}: {layer_size}\n")
      self.layers.append(nn.LeakyReLU(0.1))
      if drop > 0.01:
        #self.layers.append(nn.Dropout(p = drop**(len(layers_list)-i)))
        self.layers.append(nn.Dropout(p = drop))
        #print(f"drop {i}: {drop**(len(layers_list)-i)}")
        print(f"drop {i}: {drop}")
        #console_file.write(f"drop {i}: {drop**(len(layers_list)-i)}\n")
        console_file.write(f"drop {i}: {drop}\n")
    # final layer
    self.layers.append(nn.Linear(layers_list[-1], n_action))
    self.layers = nn.Sequential(*self.layers)
    print(f"outputs: {n_action}")
    console_file.write(f"outputs: {n_action}\n")
    print("========= NN structure =========\n")
    console_file.write("========= NN structure =========\n\n")
  def forward(self, X):
    return self.layers(X)

  def save_weights(self, path):
    torch.save(self.state_dict(), path)

  def load_weights(self, path):
    self.load_state_dict(torch.load(path))
我确保在训练期间打开训练,并在训练之外打开评估模式(删除退出层)

我的困惑是,如果PyTorch始终跟踪在正向传播和随后选择随机输出和奖励批次之间它禁用的神经元,并且在特定神经元禁用的正向传播中产生的特定情况下执行反向传播

def train_one_step(model, criterion, optimizer, inputs, targets):  
  # convert to tensors
  inputs = torch.from_numpy(inputs.astype(np.float32))
  targets = torch.from_numpy(targets.astype(np.float32))

  # zero the parameter gradients
  optimizer.zero_grad()

  # Forward pass
  outputs = model(inputs)
  loss = criterion(outputs, targets)

  # Backward and optimize
  loss.backward()
  optimizer.step()
输入和目标来自随机选择(批量缓冲历史)

对我来说,在正向传播和反向传播之间禁用相同的神经元是有意义的,但因为我在这个主题上找不到任何东西,一切都表明,退出将随机应用于我,因此对我来说是荒谬的。
前向传播和后向传播需要完全相同(而且PyTorch设法通过一些标记记住,因为我在批处理过程中似乎没有通过任何标记),或者我需要理解它们为什么会随机不同。

我不确定问题出在哪里,但让我试着解释一下它们是如何工作的

.train()
.eval()
仅调用
True
False

下拉
层在向前传递过程中对噪声进行采样。下面是forward的一个示例(为了可读性,我删除了alpha的
if
s和feature Dropout):

模板
Ctype _dropout _impl(T&input,双p,布尔序列){

火炬检查(p>=0&&p您所说的“选择了输出和奖励的随机批次”是什么意思?在执行反向传播之前,会处理数千次正向传递,根据批次选择(输入、目标)会发生以下情况如果在计算特定输出、奖励之前使用了退出层,则基于特定输入#向前传递输出=模型(输入)损失=标准(输出、目标)#向后和优化损失。向后()优化器。步骤()所以我看不出它怎么会记得每个案例都使用了什么辍学,特别是因为它计算了一个新的模型(输入),其中目标包含了以前计算的奖励;我想在这种情况下不可能正确使用辍学scenario@Dan也许你粘贴了错误的片段…你的意思是什么“在执行反向传播之前,需要处理数千次正向传递”?在代码中,正向(
模型(输入)
)后面紧跟着反向(
.backward()
)和梯度更新(
.step()
)。目标是预先计算和批处理的,模型(输入)作为一个批次重新计算;在我看来,接受培训的系统和旧版本之间总会存在差异,但更重要的是,我认为没有理由相信会发生相同的辍学;请注意,根据系统的大小,输入、目标和输出都是多个的batch@Dan拜托,你能更新任务吗用一段代码或伪代码来演示这是如何完成的?当前的代码片段没有给我们关于这个过程的任何线索,因此很难理解实际问题
def train_one_step(model, criterion, optimizer, inputs, targets):  
  # convert to tensors
  inputs = torch.from_numpy(inputs.astype(np.float32))
  targets = torch.from_numpy(targets.astype(np.float32))

  # zero the parameter gradients
  optimizer.zero_grad()

  # Forward pass
  outputs = model(inputs)
  loss = criterion(outputs, targets)

  # Backward and optimize
  loss.backward()
  optimizer.step()