pytorch实现数值型数据简单预测

import torch
import pandas as pd
import numpy as np
import torch.utils.data as Data
import os

df = pd.read_csv(r'res.csv',
                 names=['sex', 'age', 'Hb', 'ALB', 'BUN', 'SCr_not', 'Hydronephrosis', 'diabetes', 'HighBlood',
                        'Scr_yes', 'BSA', 'mgfr'])  # 读取数据并赋予列名
label = df.pop('mgfr')[1:]
label = np.array(label).astype(np.float32)
data = np.array(df)[1:, :].astype(np.float32)
data = torch.from_numpy(data)
label = torch.from_numpy(label)

# 将输入和输出封装进Data.TensorDataset()类对象
torch_dataset = Data.TensorDataset(data, label)#dataset封装
train_dataset, valid_dataset, test_dataset = torch.utils.data.random_split(torch_dataset, [480, 50, 81])#随机划分训练集,验证集,测试集

# 把 dataset 放入 DataLoader
def getloader(torch_dataset):
    loader = Data.DataLoader(#Dataloader,这里调整batch_size
        dataset=torch_dataset,  # 数据,封装进Data.TensorDataset()类的数据
        batch_size=10,  # 每块的大小
        shuffle=True,  # 要不要打乱数据 (打乱比较好)
        num_workers=0,  # 多进程(multiprocess)来读数据,单cpu时建议就0,数值型数据算力要求不大
    )
    return loader

train_loader = getloader(train_dataset)
valid_loader = getloader(valid_dataset)
test_loader = getloader(test_dataset)

class Model(torch.nn.Module):  # 括号里面表示继承类
    def __init__(self):  # 构造函数
        super(Model, self).__init__()  # 调用父类的构造
        self.Conv = torch.nn.Sequential(# 简单网络,可自行调整
            torch.nn.Linear(11, 8),
            torch.nn.ReLU(),
            torch.nn.Linear(8, 5),
            torch.nn.ReLU(),
            torch.nn.Linear(5, 3),
            torch.nn.ReLU(),
            torch.nn.Linear(3, 1)
        )
    def forward(self, x):
        y_pred = self.Conv(x)
        y_pred = y_pred.squeeze(-1)
        return y_pred


model = Model()  # 用模型的时候这样调用,也可以传入参数x,x就送入forward函数,计算出y_pred
# criterion = torch.nn.MSELoss(reduction='sum')  # 构造损失函数
# criterion = torch.nn.CrossEntropyLoss()
criterion = torch.nn.L1Loss(reduction='mean')  # 计算 output 和 target 之差的绝对值
# criterion = torch.nn.BCEWithLogitsLoss() #计算 output 和 target 之差的绝对值

optimizer = torch.optim.Adam(model.parameters(), lr=0.08)
# optimizer = torch.optim.SGD(model.parameters(), lr=0.01)  # 构造优化器
# 训练过程

def valid(a):  # 存储验证集效果最好的模型
    model.eval()  # 需要说明是否模型测试
    eval_loss = 0
    a_loss = 0
    for data in valid_loader:
        x_data, y_label = data
        y_pred = model(x_data)  # 先在前馈里面算出y_pred
        loss = criterion(y_pred, y_label)  # 计算loss
        eval_loss += loss.item()
        a_loss += torch.sum(torch.abs(y_pred - y_label))

    if a > a_loss:
        a = a_loss
        torch.save(model.state_dict(), "loss_min.pth")
    print("a:",a)
    return a


loss_all = 100000
for epoch in range(50):
    for i, data in enumerate(train_loader, 1):
        x_data, y_label = data
        y_pred = model(x_data)  # 先在前馈里面算出y_pred
        loss = criterion(y_pred, y_label)  # 算损失

        optimizer.zero_grad()  # 进行训练的时候梯度归零
        loss.backward()  # 反向传播
        optimizer.step()  # 更新,step函数用于更新,会根据所有参数里面所包含的梯度以及预先设置的学习率进行更新
    loss_all = valid(loss_all)

model_test = Model()
model_test.load_state_dict(torch.load("loss_min.pth"))
model_test.eval()  # 需要说明是否模型测试
eval_loss = 0

a=0
for data in test_loader:
    x_data, y_label = data
    y_pred = model_test(x_data)  # 先在前馈里面算出y_pred
    print("y_pred", y_pred)
    print("y_label", y_label)
    loss = criterion(y_pred, y_label)  # 计算loss
    eval_loss += loss.item()
    a += torch.sum(torch.abs(y_pred - y_label))#计算差值绝对值
print("min_loss:", a*1.0/81)

有个小坑
由于数据来源是一个csv,不注意里面有空值,导致pred预测值一直为NAN,进而loss为NAN
在pytorch训练过程中出现loss=nan的情况
1.学习率太高。
2.loss函数
3.对于回归问题,可能出现了除0 的计算,加一个很小的余项可能可以解决
4.数据本身,是否存在Nan,可以用numpy.any(numpy.isnan(x))检查一下input和target
5.target本身应该是能够被loss函数计算的,比如sigmoid激活函数的target应该大于0,同样的需要检查数据集

第四点要注意!

你可能感兴趣的:(深度学习与神经网络,python,深度学习)