目的:熟悉熟悉pytorch
导入数据
!gdown --id '1kLSW_-cW2Huj7bh84YTdimGBOJaODiOS' --output covid.train.csv
!gdown --id '1iiI5qROrAhZn-o4FPqsE97bMzDEFvIdg' --output covid.test.csv
/Users/missbei/miniforge3/envs/NLP_search/lib/python3.8/site-packages/gdown/cli.py:127: FutureWarning: Option `--id` was deprecated in version 4.3.1 and will be removed in 5.0. You don't need to pass it anymore to use a file ID.
warnings.warn(
Downloading...
From: https://drive.google.com/uc?id=1kLSW_-cW2Huj7bh84YTdimGBOJaODiOS
To: /Users/missbei/miniforge3/envs/NLP_search/Bilibili/Hung-Yi Lee/covid.train.csv
100%|██████████████████████████████████████| 2.49M/2.49M [00:00<00:00, 38.8MB/s]
/Users/missbei/miniforge3/envs/NLP_search/lib/python3.8/site-packages/gdown/cli.py:127: FutureWarning: Option `--id` was deprecated in version 4.3.1 and will be removed in 5.0. You don't need to pass it anymore to use a file ID.
warnings.warn(
Downloading...
From: https://drive.google.com/uc?id=1iiI5qROrAhZn-o4FPqsE97bMzDEFvIdg
To: /Users/missbei/miniforge3/envs/NLP_search/Bilibili/Hung-Yi Lee/covid.test.csv
100%|████████████████████████████████████████| 993k/993k [00:00<00:00, 15.1MB/s]
import Package
import math
import numpy as np
import pandas as pd
import os
import csv
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader, random_split
Some prepared code, no need to understand
from tqdm import tqdm
def same_seed(seed):
'''Fixes random number generator seeds for reproducibility.'''
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
np.random.seed(seed)
torch.manual_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed_all(seed)
def train_valid_split(data_set, valid_ratio, seed):
'''Split provided training data into training set and validation set'''
valid_set_size = int(valid_ratio * len(data_set))
train_set_size = len(data_set) - valid_set_size
train_set, valid_set = random_split(data_set, [train_set_size, valid_set_size], generator=torch.Generator().manual_seed(seed))
return np.array(train_set), np.array(valid_set)
def predict(test_loader, model, device):
model.eval() # Set your model to evaluation mode.
preds = []
for x in tqdm(test_loader):
x = x.to(device)
with torch.no_grad():
pred = model(x)
preds.append(pred.detach().cpu())
preds = torch.cat(preds, dim=0).numpy()
return preds
Dataset
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SlVuXp5c-1661580334880)(attachment:%E6%88%AA%E5%B1%8F2022-08-26%20%E4%B8%8B%E5%8D%886.32.46.png)]
- 第0列是id
- 第1-37列是37个州的one-hot编码
- 38-41是COVID-like illness
- 42-49是Behavior Indicators
- 50-52是Mental Health Indicators
- 53是最后检测结果,阳不阳
- 后续是第2天-第5天的结果,都写成列
class COVID19Dataset(Dataset):
'''
if no y, the predict
'''
def __init__(self, x, y = None):
if y is None:
self.y = y
else:
self.y = torch.FloatTensor(y)
self.x = torch.FloatTensor(x)
def __getitem__(self, index):
if self.y is None:
return self.x[index]
else:
return self.x[index], self.y[index]
def __len__(self):
return len(self.x)
Neural Network Model
class NN_Model(nn.Module):
def __init__(self, input_dim):
super().__init__() # 搞定多个继承关系的
self.layers = nn.Sequential(
nn.Linear(input_dim, 16),
nn.ReLU(),
nn.Linear(16, 8),
nn.ReLU(),
nn.Linear(8, 1)
)
def forward(self, x):
x = self.layers(x)
x = x.squeeze(1) # (B, 1) ->(B)
return x
Featurn Selection
def select_feat(train_data, valid_data, test_data, select_all = True):
'''Selects useful features to perform regression'''
y_train, y_valid = train_data[:, -1], valid_data[:, -1]
raw_x_train, raw_x_valid, raw_x_test = train_data[:, :-1], valid_data[:, :-1], test_data
if select_all:
feat_idx = list(range(raw_x_train.shape[1]))
# else: #根据传入参数自行筛选
return raw_x_train[:, feat_idx], raw_x_valid[:, feat_idx], raw_x_test[:, feat_idx], y_train, y_valid
Configurations
device = 'cuda' if torch.cuda.is_available() else 'cpu'
config = {
'seed' : 5201314,
'select_all' : True,
'valid_ratio' : 0.2,
'n_epochs' : 3000,
'batch_size': 256,
'learning_rate' : 1e-5,
'early_stop' : 400, #如果模型连续400个epoch没进步,那就停
'save_path' : './models/model.ckpt' # save in hear 问题1:??没有s吗??
}
Dataloader
# 让种子全部复用
same_seed(config['seed'])
# train_data.shape = (2699, 118) id + 37states + 16feats*5days
# test_data.shape = (1078, 117) without outcome case
train_data, test_data = pd.read_csv('./covid.train.csv').values, pd.read_csv('./covid.test.csv').values
# def train_valid_split(data_set, valid_ratio, seed)
train_data, valid_data = train_valid_split(train_data, config['valid_ratio'], config['seed'])
# 打印一下data size
print(f'''train_data size: {
train_data.shape}
valid_data size: {
valid_data.shape}
test_data size: {
test_data.shape}''')
# select features def select_feat(train_data, valid_data, test_data, select_all = True)
x_train, x_valid, x_test, y_train, y_valid = select_feat(train_data, valid_data, test_data, config['select_all'])
# 打印选择的featurn数量
print(f'''number of features: {
x_train.shape[1]}''')
# 制作数据集
train_dataset = COVID19Dataset(x_train, y_train)
valid_dataset = COVID19Dataset(x_valid, y_valid)
test_dataset = COVID19Dataset(x_test)
# 使用dataloader
train_loader = DataLoader(train_dataset, batch_size = config['batch_size'], shuffle = True) # 问题2: pin——memory是什么?
valid_loader = DataLoader(valid_dataset, batch_size = config['batch_size'], shuffle = True)
test_loader = DataLoader(test_dataset, batch_size = config['batch_size'], shuffle = True)
train_data size: (2160, 118)
valid_data size: (539, 118)
test_data size: (1078, 117)
number of features: 117
DataLoader??
Training Loop
def trainer(train_loader, valid_loader, model, config, device):
# Define your optimization algorithm.
# TODO: Please check https://pytorch.org/docs/stable/optim.html to get more available algorithms.
# TODO: L2 regularization (optimizer(weight decay...) or implement by your self).
criterion = nn.MSELoss(reduction = 'mean') # 损失函数
optimizer = torch.optim.SGD(model.parameters(), lr = config['learning_rate'], momentum = 0.9)
# 创建存放模型的目录,如果不存在的话
if not os.path.isdir('./models'):
os.mkdir('./models')
n_epochs, best_loss, step, early_stop_count =