classCOVID19Dataset(Dataset): ''' Dataset for loading and preprocessing the COVID19 dataset ''' def__init__(self, path, mode='train', target_only=False): self.mode = mode
# Read data into numpy arrays # Select features # Splitting training data into train & dev sets # Convert data into PyTorch tensors # Normalize features def__getitem__(self, index): # Returns one sample at a time return self.data[index]
def__len__(self): # Returns the size of the dataset returnlen(self.data)
classNeuralNet(nn.Module): ''' A simple fully-connected deep neural network ''' def__init__(self, input_dim): super(NeuralNet, self).__init__()
# Define your neural network here # TODO: How to modify this model to achieve better performance? self.net = nn.Sequential( nn.Linear(input_dim, 32), nn.ReLU(), nn.Linear(32, 1) )
# Mean squared error loss self.criterion = nn.MSELoss(reduction='mean')
defforward(self, x): ''' Given input of size (batch_size x input_dim), compute output of the network ''' return self.net(x).squeeze(1)
defcal_loss(self, pred, target): ''' Calculate loss ''' # TODO: you may implement L1/L2 regularization here return self.criterion(pred, target)
deftrain(tr_set, dv_set, model, config, device): ''' DNN training '''
#Setup Maximum number of epochs
# Setup optimizer min_mse = 1000. loss_record = {'train': [], 'dev': []} # for recording training loss early_stop_cnt = 0 epoch = 0 while epoch < n_epochs: model.train() # set model to training mode for x, y in tr_set: # iterate through the dataloader # forward pass (compute output) # compute loss # backpropagation # update model with optimizer # record loss
# After each epoch, test your model on the validation (development) set. dev_mse = dev(dv_set, model, device) if dev_mse < min_mse: # Save model if your model improved min_mse = dev_mse print('Saving model (epoch = {:4d}, loss = {:.4f})' .format(epoch + 1, min_mse)) torch.save(model.state_dict(), config['save_path']) # Save model to specified path early_stop_cnt = 0 else: early_stop_cnt += 1
epoch += 1 loss_record['dev'].append(dev_mse) if early_stop_cnt > config['early_stop']: # Stop training if your model stops improving for "config['early_stop']" epochs. break
print('Finished training after {} epochs'.format(epoch)) return min_mse, loss_record
def dev(dv_set, model, device): model.eval() # set model to evalutation mode total_loss = 0 for x, y in dv_set: # iterate through the dataloader x, y = x.to(device), y.to(device) # move data to device (cpu/cuda) with torch.no_grad(): # disable gradient calculation pred = model(x) # forward pass (compute output) mse_loss = model.cal_loss(pred, y) # compute loss total_loss += mse_loss.detach().cpu().item() * len(x) # accumulate loss total_loss = total_loss / len(dv_set.dataset) # compute averaged loss
deftest(tt_set, model, device): model.eval() # set model to evalutation mode preds = [] for x in tt_set: # iterate through the dataloader x = x.to(device) # move data to device (cpu/cuda) with torch.no_grad(): # disable gradient calculation pred = model(x) # forward pass (compute output) preds.append(pred.detach().cpu()) # collect prediction preds = torch.cat(preds, dim=0).numpy() # concatenate all predictions and convert to a numpy array return preds
Test模块的流程更为简洁,与Validation基本一致,区别在于没有计算loss。
Setup Hyper-parameters
hyper-parameters
1 2 3 4 5 6 7 8 9 10 11 12 13
config = { 'n_epochs': 3000, # maximum number of epochs 'batch_size': 128, # mini-batch size for dataloader # 使用SGD会出现loss无法减小的问题 'optimizer': 'Adam', # optimization algorithm (optimizer in torch.optim) 'optim_hparas': { # hyper-parameters for the optimizer (depends on which optimizer you are using) 'lr': 0.001, # learning rate of SGD # 'momentum': 0.9, # momentum for SGD 'weight_decay':1e-3# L2 regularization }, 'early_stop': 200, # early stopping epochs (the number epochs since your model's last improvement) 'save_path': 'models/model.pth'# your model will be saved here }