学习链接:
https://speech.ee.ntu.edu.tw/~hylee/ml/2021-spring.html
https://www.bilibili.com/video/BV1Wv411h7kN?p=7
例子描述:
Author: Heng-Jui Chang
Slides: https://github.com/ga642381/ML2021-Spring/blob/main/HW01/HW01.pdf
Video: TBA
Objectives:

  • Solve a regression problem with deep neural networks (DNN).
  • Understand basic DNN training tips.
  • Get familiar with PyTorch.

If any questions, please contact the TAs via TA hours, NTU COOL, or email.

Preprocess

We have three kinds of datasets:

  • train: for training
  • dev: for validation
  • test: for testing (w/o target value)

Dataset

The COVID19Dataset below does:

  • read .csv files
  • extract features
  • split covid.train.csv into train/dev sets
  • normalize features

Finishing TODO below might make you pass medium baseline.

图片1.png

0.设置seed

  1. myseed = 42069 # set a random seed for reproducibility
  2. torch.backends.cudnn.deterministic = True
  3. torch.backends.cudnn.benchmark = False
  4. np.random.seed(myseed)
  5. torch.manual_seed(myseed)
  6. if torch.cuda.is_available():
  7. torch.cuda.manual_seed_all(myseed)

1.载入数据

  1. tr_path = 'covid.train.csv' # path to training data
  2. tt_path = 'covid.test.csv' # path to testing data

2.处理数据

输入参数:

init(self,path,mode =’train’,target_only = ‘False’):

处理流程:

  1. read .csv files
  2. extract features
  3. split covid.train.csv into train/dev sets
  4. normalize features
  5. Generates a dataset, then is put into a dataloader.

    要点:

  • 注意数据规范化,减均值除方差即可;
  • 训练时划分训练和测试集;
  • train的时候需要shuffle,测试的时候不需要(保证测试结果可复现);
  • dataloader相当于一个“字典”,包括数据集合一些参数; ```python

    PyTorch

    import torch from torch.utils.data import Dataset, DataLoader

For data preprocess

import numpy as np import csv

class COVID19Dataset(Dataset): ‘’’ read .csv files extract features split covid.train.csv into train/dev sets normalize features ‘’’ ‘’’ Dataset for loading and preprocessing the COVID19 dataset ‘’’ def init(self,path,mode =’train’,target_only = ‘False’): self.mode =mode

  1. with open(path,'r') as fp:
  2. data = list(csv.reader(fp))
  3. data = np.array(data[1:])[:,1:].astype(float)
  4. '''data.shape = 2700*94'''
  5. if not target_only:
  6. feats = list(range(93))
  7. else:
  8. # TODO: Using 40 states & 2 tested_positive features (indices = 57 & 75)
  9. pass
  10. if mode =='test':
  11. # Testing data
  12. # data: 893 x 93 (40 states + day 1 (18) + day 2 (18) + day 3 (17))
  13. data = data[:,feats]
  14. self.data = torch.FloatTensor(data)
  15. else:
  16. # Training data (train/dev sets)
  17. # data: 2700 x 94 (40 states + day 1 (18) + day 2 (18) + day 3 (18))
  18. target = data[:,-1]
  19. data = data[:,feats]
  20. # Splitting training data into train & dev sets
  21. if mode == 'train':
  22. indices = [i for i in range(len(data)) if i % 10 != 0]
  23. elif mode == 'dev':
  24. indices = [i for i in range(len(data)) if i % 10 == 0]
  25. # Convert data into PyTorch tensors
  26. self.data = torch.FloatTensor(data[indices])
  27. self.target = torch.FloatTensor(target[indices])
  28. # Normalize features (you may remove this part to see what will happen)
  29. self.data[:,40:] = \
  30. (self.data[:, 40:] - self.data[:, 40:].mean(dim=0, keepdim=True)) \
  31. / self.data[:, 40:].std(dim=0, keepdim=True)
  32. self.dim = self.data.shape[1]
  33. print('Finished reading the {} set of COVID19 Dataset ({} samples found, each dim = {})'.format(mode, len(self.data), self.dim))
  34. def __getitem__(self, index):
  35. # Returns one sample at a time
  36. if self.mode in ['train', 'dev']:
  37. # For training
  38. return self.data[index], self.target[index]
  39. else:
  40. # For testing (no target)
  41. return self.data[index]
  42. def __len__(self):
  43. # Returns the size of the dataset
  44. return len(self.data)

def prep_dataloader(path, mode, batch_size, n_jobs=0, target_only=False): ‘’’ Generates a dataset, then is put into a dataloader. ‘’’ dataset = COVID19Dataset(path, mode=mode, target_only=target_only) # Construct dataset dataloader = DataLoader( dataset, batch_size, shuffle=(mode == ‘train’), drop_last=False, num_workers=n_jobs, pin_memory=True) # Construct dataloader return dataloader

  1. <a name="OXhl4"></a>
  2. ## 3.建立模型
  3. <a name="T9gb9"></a>
  4. ### 输入参数:
  5. input_dim
  6. <a name="WPeII"></a>
  7. ### 网络层:
  8. 在init中定义网络层;
  9. <a name="LJ8Kb"></a>
  10. ### Loss
  11. 在init中定义loss;
  12. <a name="xhwAn"></a>
  13. ### forward
  14. 矩阵相乘
  15. <a name="hIyy5"></a>
  16. ### 注意事项:
  17. - BatchNorm1d可以省略正则化和dropout
  18. ```python
  19. # PyTorch
  20. import torch.nn as nn
  21. class NeuralNet(nn.Module):
  22. ''' A simple fully-connected deep neural network '''
  23. def __init__(self, input_dim):
  24. super(NeuralNet, self).__init__()
  25. self.net = nn.Sequential(
  26. nn.Linear(input_dim, 128),
  27. nn.BatchNorm1d(128),
  28. nn.ReLU(),
  29. nn.Linear(128, 256),
  30. nn.BatchNorm1d(256),
  31. nn.ReLU(),
  32. nn.Linear(256, 512),
  33. nn.BatchNorm1d(512),
  34. nn.ReLU(),
  35. nn.Linear(512, 256),
  36. nn.BatchNorm1d(256),
  37. nn.ReLU(),
  38. nn.Linear(256, 128),
  39. nn.BatchNorm1d(128),
  40. nn.ReLU(),
  41. nn.Linear(128, 64),
  42. nn.BatchNorm1d(64),
  43. nn.ReLU(),
  44. nn.Linear(64, 1),
  45. )
  46. # Mean squared error loss
  47. self.criterion = nn.MSELoss(reduction='mean')
  48. def forward(self, x):
  49. ''' Given input of size (batch_size x input_dim), compute output of the network '''
  50. # print(np.shape(self.net(x))) #[270*1]
  51. # print(self.net(x))
  52. # print(np.shape(self.net(x).squeeze(1)))
  53. # print(self.net(x).squeeze(1))#[270]
  54. return self.net(x).squeeze(1)
  55. def cal_loss(self, pred, target):
  56. ''' Calculate loss '''
  57. # TODO: you may implement L2 regularization here
  58. return self.criterion(pred, target)

4.训练并保存参数

训练的一些参数,可以用args

  1. config = {
  2. 'n_epochs': 3000, # maximum number of epochs
  3. 'batch_size': 270, # mini-batch size for dataloader
  4. 'optimizer': 'SGD', # optimization algorithm (optimizer in torch.optim)
  5. 'optim_hparas': { # hyper-parameters for the optimizer (depends on which optimizer you are using)
  6. 'lr': 0.001, # learning rate of SGD
  7. 'momentum': 0.9 # momentum for SGD
  8. },
  9. 'early_stop': 200, # early stopping epochs (the number epochs since your model's last improvement)
  10. 'save_path': 'models/model.pth' # your model will be saved here
  11. }

设置优化器
开始训练

  1. def train(tr_set, dv_set, model, config, device):
  2. ''' DNN training '''
  3. n_epochs = config['n_epochs'] # Maximum number of epochs
  4. # Setup optimizer
  5. optimizer = getattr(torch.optim, config['optimizer'])(
  6. model.parameters(), **config['optim_hparas'])
  7. min_mse = 1000.
  8. loss_record = {'train': [], 'dev': []} # for recording training loss
  9. early_stop_cnt = 0
  10. epoch = 0
  11. while epoch < n_epochs:
  12. model.train() # set model to training mode
  13. for x, y in tr_set: # iterate through the dataloader
  14. optimizer.zero_grad() # set gradient to zero
  15. x, y = x.to(device), y.to(device) # move data to device (cpu/cuda)
  16. pred = model(x) # forward pass (compute output)
  17. mse_loss = model.cal_loss(pred, y) # compute loss
  18. mse_loss.backward() # compute gradient (backpropagation)
  19. optimizer.step() # update model with optimizer
  20. loss_record['train'].append(mse_loss.detach().cpu().item())
  21. # After each epoch, test your model on the validation (development) set.
  22. dev_mse = dev(dv_set, model, device)
  23. if dev_mse < min_mse:
  24. # Save model if your model improved
  25. min_mse = dev_mse
  26. print('Saving model (epoch = {:4d}, loss = {:.4f})'
  27. .format(epoch + 1, min_mse))
  28. torch.save(model.state_dict(), config['save_path']) # Save model to specified path
  29. early_stop_cnt = 0
  30. else:
  31. early_stop_cnt += 1
  32. epoch += 1
  33. loss_record['dev'].append(dev_mse)
  34. if early_stop_cnt > config['early_stop']:
  35. # Stop training if your model stops improving for "config['early_stop']" epochs.
  36. break
  37. print('Finished training after {} epochs'.format(epoch))
  38. return min_mse, loss_record

验证并保存模型
covid-19.zip