for e in range(100): #epoch==e
train_main_loss, train_aux_loss = 0, 0
# 训练集
for batch_x, batch_y, batch_y_aux in tqdm_notebook(train_loader):# tqdm_notebook显示进展效果
'''
先将梯度值归零,:optimizer.zero_grad();
然后反向传播计算得到每个参数的梯度值:loss.backward();
最后通过梯度下降执行一步参数更新:optimizer.step();
'''
# 原因是不清零梯度会累加,梯度会在前一次的基础上无限下降,而不是对其进行覆盖。
opt.zero_grad() # 为下次训练清空梯度
batch_x = batch_x.cuda() # A.cuda()就说利用GPU运算
batch_y = batch_y.cuda()
batch_y_aux = batch_y_aux.cuda()
main_output, aux_output = model(batch_x) # X_train_t ==》batch_x
# 放入model:SelfBoostedNet 进行训练,得到两个输出。下面计算他们的loss
main_loss = loss(main_output, batch_y)
aux_loss = loss(aux_output, batch_y_aux)
total_loss = main_loss + alpha * aux_loss
total_loss.backward() # 通过反向传播过程来实现可训练参数的更新
opt.step() # 更新权重参数
train_main_loss += main_loss.item() * batch_x.shape[0]
train_aux_loss += aux_loss.item() * batch_x.shape[0]
'''
不使用with torch.no_grad():此时有grad_fn=属性,表示,计算的结果在一计算图当中,可以进行梯度反传等操作。
只是想要网络结果的话就不需要后向传播 ,如果你想通过网络输出的结果去进一步优化网络的话 就需要后向传播了。
'''
# 所以我们的我们不进行后向传播
with torch.no_grad():
val_main_loss, val_aux_loss = 0, 0
# 验证集
for batch_x, batch_y, batch_y_aux in val_loader:
batch_x = batch_x.cuda()
batch_y = batch_y.cuda()
batch_y_aux = batch_y_aux.cuda()
main_output, aux_output = model(batch_x)
main_loss = loss(main_output, batch_y)
aux_loss = loss(aux_output, batch_y_aux)
val_main_loss += main_loss.item() * batch_x.shape[0]
val_aux_loss += aux_loss.item() * batch_x.shape[0]
train_main_loss /= X_train_t.shape[0]
train_aux_loss /= X_train_t.shape[0]
val_main_loss /= X_val_t.shape[0]
val_aux_loss /= X_val_t.shape[0]
'''
他在训练验证集的时候,只是想看一下训练的效果,
并不是想通过验证集来更新网络时,所以使用with torch.no_grad()。
最终,torch.save就保存的训练集的训练模型。
'''
if val_loss > val_main_loss:
val_loss = val_main_loss
torch.save(model.state_dict(), 'self_boost_air_quality.pt')
print("Iter: ", e,
"train main loss: ", train_main_loss,
"train aux loss: ", train_aux_loss,
"val main loss: ", val_main_loss,
"val aux loss: ", val_aux_loss)
model.load_state_dict(torch.load('self_boost_air_quality.pt'))
他在训练验证集的时候,只是想看一下训练的效果,并不是想通过验证集来更新网络时,所以使用with torch.no_grad()。
最终,torch.save就保存的训练集的训练模型。
如果我们是with torch.no_grad()
就说明我们的数据不需要计算梯度也不进行后向传播
在这里插入代码片