import matplotlib.pyplot as plt
import torch
import numpy as np
import csv
import pandas as pd
from torch.utils.data import DataLoader,Dataset
import torch.nn as nn
from torch import optim
import time
class CovidDataset(Dataset):
def __init__(self,file_path,mode="train"):
with open(file_path,"r") as f:
ori_data = list(csv.reader(f))
csv_data = np.array(ori_data[1:])[:,1:].astype(float)
if mode == "train": #逢五取一
indices = [i for i in range(len(csv_data)) if i%5 != 0]
self.y = torch.tensor(csv_data[indices,-1])
elif mode == "val":
indices = [i for i in range(len(csv_data)) if i % 5 == 0]
self.y = torch.tensor(csv_data[indices, -1])
else:
indices = [i for i in range(len(csv_data))]
data = torch.tensor(csv_data[indices,:-1])
#横向对比无意义,要规划
self.data= (data-data.mean(dim = 0,keepdim=True))/data.std(dim = 0,keepdim=True)
self.mode = mode
def __getitem__(self, idx):
if self.mode != "test":
return self.data[idx].float(), self.y[idx].float() #改成32维
else:
return self.data[idx].float()
def __len__(self):
return len(self.data)
#模型
class MyModel(nn.Module):
def __init__(self,inDim):
super(MyModel, self).__init__()
self.fcl = nn.Linear(inDim,64)
self.relu1 = nn.ReLU() #激活函数
self.fc2 = nn.Linear(64,1)
def forward(self,x): #模型向前过程
x = self.fcl(x)
x = self.relu1(x)
x = self.fc2(x)
if len(x.size()) > 1:
return x.squeeze(1) #去掉一维
return x
def train_val(model,train_loader,val_loader,device,epochs,optimizer,loss,save_path):
model = model.to(device)
plt_train_loss = [] #记录所有轮次的loss
plt_val_loss = []
min_val_loss = 999999999999
for epoch in range(epochs):
train_loss = 0.0
val_loss = 0.0
start_time = time.time()
model.train() #模型调整为训练模式
for batch_x,batch_y in train_loader:
x,target = batch_x.to(device), batch_y.to(device)
pred = model(x)
train_bat_loss = loss(pred,target)
train_bat_loss.backward()
optimizer.step() #更新模型的作用
optimizer.zero_grad()
train_loss += train_bat_loss.cpu().item()#张量无法加放在cpu上加取数值
plt_train_loss.append(train_loss / train_loader.__len__())
model.eval()
with torch.no_grad():
for batch_x,batch_y in val_loader:
x, target = batch_x.to(device), batch_y.to(device)
pred = model(x)
val_bat_loss = loss(pred, target)
val_loss += val_bat_loss.cpu().item()
plt_val_loss.append(val_loss/val_loader.__len__())
if val_loss < min_val_loss:
torch.save(model,save_path)
min_val_loss = val_loss
print("[%03d/%03d] %2.2f sec(s) Trainloss: %.6f |Valloss: %.6f"% \
(epoch,epochs,time.time()-start_time,plt_train_loss[-1],plt_val_loss[-1]))
plt.plot(plt_train_loss)
plt.plot(plt_val_loss)
plt.title("loss图")
plt.legend(["train", "val"])
plt.show()
def evaluate(sava_path,test_loader,device,rel_path):
model = torch.load(sava_path).to(device)
rel = []
with torch.no_grad():
for x in test_loader:
pred = model(x.to(device))
rel.append(pred)
print(rel)
train_file = "covid.train.csv"
test_file = "covid.test.csv"
train_datatest = CovidDataset(train_file,"train")
val_datatest = CovidDataset(train_file,"val")
test_datatest = CovidDataset(test_file,"test")
batch_size = 16
train_loader = DataLoader(train_datatest,batch_size=batch_size,shuffle=True)
val_loader = DataLoader(val_datatest,batch_size=batch_size,shuffle=True)
test_loader = DataLoader(test_datatest,batch_size=1,shuffle=False)
for batch_x,batch_y in train_loader:
print(batch_x,batch_y)
device = "cuda" if torch.cuda.is_available() else "cpu"
print(device)
config = {
"lr":0.001,
"epochs":20,
"momentum":0.9,
"save_path":"model_save/best_model.pth",
"rel_path" : "pred.csv"
}
model = MyModel(inDim=93).to(device) #模型放到gpu上
loss = nn.MSELoss()
optimizer = optim.SGD(model.parameters(),lr =config["lr"],momentum=config["momentum"])
train_val(model,train_loader,val_loader,device,config["epochs"],optimizer,loss,config["save_path"])
会出现_pickle.PicklingError: Can‘t pickle <class ‘main.MyModel‘>: attribute lookup MyModel on __main__的错误
但是调试一步一步能画出图来