Pytorch NN 回归模型不学习

时间:2021-06-14 22:01:41

标签: python pytorch

我对 pytorch 非常陌生,并且对模型收敛非常执着。在我看来它没有学习,因为 loss/r2 没有改善。

根据我在此处找到的建议,我检查/尝试过的内容。

  1. 从头开始更改/编写损失函数
  2. 设置“loss.requires_grad = True”
  3. 尝试在没有数据加载器的情况下提供数据/只是直接手动批处理
  4. 使用二维数据/平均合并数据!!!我在随机森林和 SVM 回归器中获得了均值池数据的不错结果,但在 NN 中却没有,这让我很困惑,让我认为数据还可以,而网络不行!
  5. 使用学习率、批量大小

关于数据:bert embeddings from letter-sequence,每个数据点为1024个特征43行(对于Conv1d我转置为1024*43) 训练中总共 >40K 个数据点,batch size=64

import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F ## relu, tahn
import torch.utils.data as DataLoader # helps create batches to train on
from scipy.stats import pearsonr
import numpy as np
import torch.utils.data as data_utils
torch.set_printoptions(precision=10)


#Hyperparameters
learning_rate=0.001
batch_size = 64
num_epochs=100


data_train1 = torch.Tensor(data_train)
targets_train1=torch.Tensor(targets_train)

dataset_train = data_utils.TensorDataset(data_train1, targets_train1)
train_loader = DataLoader.DataLoader(dataset=dataset_train, batch_size=batch_size, shuffle=True)


class NN (nn.Module):
    def __init__(self):#input_size=43x1024
        super(NN,self).__init__()
        self.layers = nn.Sequential(
            nn.Conv1d(1024, 512, kernel_size=4), #I tried different in and out here
            nn.ELU(),
            nn.BatchNorm1d(512),
            nn.Flatten(),
            nn.Linear(512*40, 512),
            nn.ReLU(),
            nn.Linear(512, 1)
        )
        
    def forward(self, x):
        return self.layers(x)

torch.manual_seed(100)

#Initialize network
model=NN().to(device)

#Loss and optimizer
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate) #to check 


#Training the model
metric_name='r2'

for epoch in range(num_epochs):
    score=[]
    loss_all=[]
    print(f"Epoch: {epoch+1}/{num_epochs}")

    model.train()

    for batch_idx, (data, targets) in enumerate(train_loader):
        data=data.to(device=device)
        targets=targets.to(device=device)

        optimizer.zero_grad()
        
        #forward
        predictions=model(data)
        
        loss=criterion(predictions,targets).to(device)

        loss.requires_grad = True

        #backward
        loss_all.append(loss.item())
        loss.backward()
    
        #gradient descent or adam step
        optimizer.step()
        
        #computing r squared
        output=predictions.detach().cpu().numpy()
        target=targets.detach().cpu().numpy()
        output=np.squeeze(output)
        target=np.squeeze(target)
    
        score.append(pearsonr(target, output)[0]**2)

    total_score = sum(score)/len(score)
    print(f'training {metric_name}: {total_score}, mean loss: {sum(loss_all)/len(loss_all)}')

第 (10) 个 Epoch 的输出:
Epoch:1/100 训练 r2:0.0026224905802415955,平均损失:0.5084380856556941
Epoch:2/100 训练 r2:0.0026334153423518466,平均损失:0.5082988155293148
Epoch:3/100 训练 r2:0.002577073836564485,平均损失:0.5085703951569392
Epoch:4/100 训练 r2:0.00263483899689855,平均损失:0.5081870414129565
Epoch:5/100 训练 r2:0.0025642136678393776,平均损失:0.5083346445680192
Epoch:6/100 训练 r2:0.0026261540869286933,平均损失:0.5084220717277274
Epoch:7/100 训练 r2:0.002614604670602339,平均损失:0.5082813335398275
Epoch:8/100 训练 r2:0.0024826257263258784,平均损失:0.5086268588042153
Epoch:9/100 训练 r2:0.00261018096876641,平均损失:0.5082496945227619
Epoch:10/100 训练 r2:0.002542892071836945,平均损失:0.5088265852086478

响应为 (-2,2) 范围内的 float64。

希望能帮到你!提前感谢您的时间!

更新 1. 响应缩放到 [-1,1] 范围内的 float64 并且 tanh 仍未收敛。我觉得缺少一些通用的东西。顺便说一句,当我对批次进行非混洗批次和直接数据(第一批次指数为 0-63,第二批次为 64-127 等)时,我在每个时期得到相同的分数结果!

更新 2. 尝试添加 (2) 个更多具有 Conv1d、BatchNorm1d、ELU(1024->512、512->256、256->128,内核大小为 4)的序列,结果更糟:(不是完全学习!

0 个答案:

没有答案