目录
[1、显示NVIDIA GPU的状态信息](#1、显示NVIDIA GPU的状态信息)
[9、超参数字典 config](#9、超参数字典 config)
[12、加载并启动 TensorBoard](#12、加载并启动 TensorBoard)
1、显示NVIDIA GPU的状态信息
python
# check gpu type
!nvidia-smi
!nvidia-smi
是在Jupyter Notebook或Google Colab等环境中运行的Shell命令,用于显示NVIDIA GPU的状态信息。在colab中,若要运行Shell命令,则可在前面加:!
**2、**数据集的两种不同的下载方式
python
# google drive link
!gdown --id '1BjXalPZxq9mybPKNjF3h5L3NcF7XKTS-' --output covid_train.csv
!gdown --id '1B55t74Jg2E5FCsKCsUEkPKIuqaY7UIi1' --output covid_test.csv
# dropbox link
# !wget -O covid_train.csv https://www.dropbox.com/s/lmy1riadzoy0ahw/covid.train.csv?dl=0
# !wget -O covid_test.csv https://www.dropbox.com/s/zalbw42lu4nmhr2/covid.test.csv?dl=0
这段代码使用了数据集的两种不同的下载方式(gdown和wget)
-
使用gdown下载(激活状态):
-
gdown
是一个命令行工具,专门用于从Google Drive下载文件 -
--id '1BjXalPZxq9mybPKNjF3h5L3NcF7XKTS-'
指定了Google Drive上文件的ID -
--output covid_train.csv
指定了下载后的文件名为covid_train.csv -
同样的方法下载测试集,保存为covid_test.csv
-
-
使用wget下载(已注释):
-
这部分代码被注释掉了,但提供了另一种从Dropbox下载同样文件的方法
-
wget -O
命令用于从指定URL下载文件并保存为指定名称 -
dl=0
参数改为dl=1
会直接下载Dropbox文件而不是预览页面
-
Dropbox 介绍:
Dropbox 是一个云存储服务,允许用户存储、同步和共享文件。它提供跨设备访问,用户可以将文件上传到云端,并在多个设备间同步。Dropbox 支持文件共享,用户可以生成共享链接与他人共享文件,并控制文件访问权限。它还支持版本控制,允许用户查看和恢复文件的历史版本。
Dropbox 提供免费和付费版本。免费版提供 2 GB 存储空间,适合个人使用;付费版提供更多存储空间和团队协作功能,如 Dropbox Plus(2 TB 存储)和 Dropbox Business(企业级功能)。通过安装客户端,用户可以在不同设备上访问文件,确保文件始终保持同步。
此外,Dropbox 允许用户与团队共同工作,支持多人同时编辑文件,并与其他应用(如 Google Docs、Microsoft Office)集成。它适用于文件备份、团队协作以及跨设备的文件访问和共享。
总结来说,Dropbox 是一个简单且功能强大的工具,方便个人和团队存储、管理和共享文件。
3、导入相关库
python
# Numerical Operations
import math
import numpy as np
# Reading/Writing Data
import pandas as pd
import os
import csv
# For Progress Bar为循环提供进度条,在训练深度学习模型时非常有用
from tqdm import tqdm
# Pytorch
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader, random_split
# For plotting learning curve
from torch.utils.tensorboard import SummaryWriter
数值计算库
-
import math
- 提供基本数学函数 -
import numpy as np
- 提供高效的数值计算功能,尤其是处理数组和矩阵
数据处理库
-
import pandas as pd
- 用于数据分析和操作结构化数据 -
import os
- 提供与操作系统交互的功能,如文件路径操作 -
import csv
- 用于读写CSV文件
进度显示
from tqdm import tqdm
- 为循环提供进度条,在训练深度学习模型时非常有用
PyTorch相关
-
import torch
- PyTorch的核心库 -
import torch.nn as nn
- 包含神经网络层的定义和各种损失函数 -
from torch.utils.data import Dataset, DataLoader, random_split
- 数据加载和处理工具-
Dataset
- 用于自定义数据集 -
DataLoader
- 用于批量加载数据 -
random_split
- 用于将数据集随机分割成训练集和验证集
-
可视化工具
from torch.utils.tensorboard import SummaryWriter
- 用于记录训练过程中的指标并可视化
这是一个典型的深度学习项目的导入部分,表明您可能在准备构建一个PyTorch模型来处理之前下载的COVID相关数据集。这些导入涵盖了数据处理、模型构建、训练过程跟踪和可视化等完整的深度学习工作流程所需的工具。
4、三个工具函数
python
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
第一个函数
用于确保实验的可重复性,通过固定各种随机数生成器的种子:
具体来说,它做了以下几件事:
-
torch.backends.cudnn.deterministic = True
:- 设置CUDNN(NVIDIA的深度学习库)为确定性模式,这意味着每次运行时都会得到相同的结果。通常,CUDNN会尝试优化计算速度,这可能导致不稳定的随机性,设置为
True
可以保证可复现性。
- 设置CUDNN(NVIDIA的深度学习库)为确定性模式,这意味着每次运行时都会得到相同的结果。通常,CUDNN会尝试优化计算速度,这可能导致不稳定的随机性,设置为
-
torch.backends.cudnn.benchmark = False
:- 禁用CUDNN的自动调优功能。当网络的输入大小不变时,禁用这个选项可以保证每次运行时的计算方式保持一致,进一步增加可复现性。
-
np.random.seed(seed)
:- 设置NumPy的随机数种子。很多深度学习代码会用到NumPy来生成随机数,设置种子可以确保生成的随机数序列一致。
-
torch.manual_seed(seed)
:- 设置PyTorch的CPU随机数生成种子,确保CPU上的所有随机操作(如初始化权重等)具有可复现性。
-
torch.cuda.manual_seed_all(seed)
:- 如果GPU可用,这行代码设置所有GPU设备上的随机数生成种子,确保GPU上的所有随机操作也有一致的输出。
总结: 这段代码确保了在每次运行时,所有涉及随机性的操作(如权重初始化、数据加载等)都能生成相同的结果,从而实现了实验的可复现性。
第二个函数
用于将数据集分割为训练集和验证集。
第三个函数
用于使用训练好的模型对测试数据进行预测。
5、定义自己的数据集类
python
class COVID19Dataset(Dataset):
'''
x: Features.
y: Targets, if none, do prediction.
'''
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, idx):
if self.y is None:
return self.x[idx]
else:
return self.x[idx], self.y[idx]
def __len__(self):
return len(self.x)
这段代码定义了一个自定义的 PyTorch 数据集类 COVID19Dataset
,继承自 torch.utils.data.Dataset
。这个类的目的是将输入的特征(x
)和目标(y
)封装成一个可以用于 PyTorch 数据加载器的对象,方便在训练和预测时进行批量处理。
6、定义神经网络模型
python
class My_Model(nn.Module):
def __init__(self, input_dim):
super(My_Model, self).__init__()
# TODO: modify model's structure, be aware of dimensions.
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
这段代码定义了一个简单的神经网络模型 My_Model
,继承自 torch.nn.Module
。该模型用于执行回归任务(因为最后一层输出的是一个标量),并通过 nn.Sequential
来定义一个包含多层的网络结构。
7、定义选择特征的函数
python
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:
feat_idx = [0,1,2,3,4] # TODO: Select suitable feature columns.
return raw_x_train[:,feat_idx], raw_x_valid[:,feat_idx], raw_x_test[:,feat_idx], y_train, y_valid
这段代码定义了一个用于选择特征的函数 select_feat
,它从训练数据、验证数据和测试数据中选择合适的特征进行回归分析。根据参数 select_all
,该函数可以选择所有特征或指定的部分特征。
8、训练过程
python
def trainer(train_loader, valid_loader, model, config, device):
criterion = nn.MSELoss(reduction='mean') # Define your loss function, do not modify this.
# 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).
optimizer = torch.optim.SGD(model.parameters(), lr=config['learning_rate'], momentum=0.7)
writer = SummaryWriter() # Writer of tensoboard.
if not os.path.isdir('./models'):
os.mkdir('./models') # Create directory of saving models.
n_epochs, best_loss, step, early_stop_count = config['n_epochs'], math.inf, 0, 0
for epoch in range(n_epochs):
model.train() # Set your model to train mode.
loss_record = []
# tqdm is a package to visualize your training progress.
train_pbar = tqdm(train_loader, position=0, leave=True)
for x, y in train_pbar:
optimizer.zero_grad() # Set gradient to zero.
x, y = x.to(device), y.to(device) # Move your data to device.
pred = model(x)
loss = criterion(pred, y)
loss.backward() # Compute gradient(backpropagation).
optimizer.step() # Update parameters.
step += 1
loss_record.append(loss.detach().item())
# Display current epoch number and loss on tqdm progress bar.
train_pbar.set_description(f'Epoch [{epoch+1}/{n_epochs}]')
train_pbar.set_postfix({'loss': loss.detach().item()})
mean_train_loss = sum(loss_record)/len(loss_record)
writer.add_scalar('Loss/train', mean_train_loss, step)
model.eval() # Set your model to evaluation mode.
loss_record = []
for x, y in valid_loader:
x, y = x.to(device), y.to(device)
with torch.no_grad():
pred = model(x)
loss = criterion(pred, y)
loss_record.append(loss.item())
mean_valid_loss = sum(loss_record)/len(loss_record)
print(f'Epoch [{epoch+1}/{n_epochs}]: Train loss: {mean_train_loss:.4f}, Valid loss: {mean_valid_loss:.4f}')
# writer.add_scalar('Loss/valid', mean_valid_loss, step)
if mean_valid_loss < best_loss:
best_loss = mean_valid_loss
torch.save(model.state_dict(), config['save_path']) # Save your best model
print('Saving model with loss {:.3f}...'.format(best_loss))
early_stop_count = 0
else:
early_stop_count += 1
if early_stop_count >= config['early_stop']:
print('\nModel is not improving, so we halt the training session.')
return
这段代码实现了一个训练过程,包括模型训练、验证、损失记录、模型保存、早停等功能。它利用 PyTorch 进行训练,并使用 TensorBoard 来记录训练过程的损失值。
逐部分解释:
- 定义损失函数和优化器:
python
criterion = nn.MSELoss(reduction='mean') # Define your loss function
optimizer = torch.optim.SGD(model.parameters(), lr=config['learning_rate'], momentum=0.7)
-
criterion
:使用均方误差(MSE)作为损失函数。reduction='mean'
表示取损失的平均值。 -
optimizer
:使用随机梯度下降(SGD)作为优化器,并设置学习率和动量。优化器会更新模型的参数。
- TensorBoard 写入器:
python
writer = SummaryWriter() # Writer of TensorBoard
- 创建一个
SummaryWriter
对象,用于记录损失值到 TensorBoard 以便可视化训练过程。
- 创建模型保存目录:
python
if not os.path.isdir('./models'):
os.mkdir('./models') # Create directory of saving models
- 如果
models
目录不存在,则创建一个,用于保存训练过程中表现最好的模型。
- 初始化训练参数:
python
n_epochs, best_loss, step, early_stop_count = config['n_epochs'], math.inf, 0, 0
-
n_epochs
:训练的总轮数。 -
best_loss
:记录最好的验证损失,初始设置为正无穷。 -
step
:记录训练步数,通常用于 TensorBoard。 -
early_stop_count
:用于早停策略的计数器,初始值为 0。
- 训练和验证过程:
python
for epoch in range(n_epochs):
model.train() # Set your model to train mode
loss_record = []
train_pbar = tqdm(train_loader, position=0, leave=True) # tqdm progress bar
for x, y in train_pbar:
optimizer.zero_grad() # Reset gradients to zero
x, y = x.to(device), y.to(device) # Move data to device (CPU/GPU)
pred = model(x) # Forward pass
loss = criterion(pred, y) # Compute loss
loss.backward() # Backpropagation
optimizer.step() # Update parameters
step += 1
loss_record.append(loss.detach().item())
train_pbar.set_description(f'Epoch [{epoch+1}/{n_epochs}]') # Update progress bar
train_pbar.set_postfix({'loss': loss.detach().item()})
mean_train_loss = sum(loss_record) / len(loss_record) # Calculate average training loss
writer.add_scalar('Loss/train', mean_train_loss, step)
model.eval() # Set model to evaluation mode
loss_record = []
for x, y in valid_loader:
x, y = x.to(device), y.to(device)
with torch.no_grad(): # No gradient calculation during validation
pred = model(x)
loss = criterion(pred, y)
loss_record.append(loss.item())
mean_valid_loss = sum(loss_record) / len(loss_record) # Calculate average validation loss
print(f'Epoch [{epoch+1}/{n_epochs}]: Train loss: {mean_train_loss:.4f}, Valid loss: {mean_valid_loss:.4f}')
-
训练模式 :调用
model.train()
使模型进入训练模式,启用如 Dropout、BatchNorm 等层的训练状态。 -
训练进度条 :使用
tqdm
来显示训练进度条,实时显示每个批次的损失。 -
前向传播和反向传播:在每个批次中,首先将数据移到设备上(CPU 或 GPU),然后进行前向传播,计算损失,进行反向传播并更新模型参数。
-
验证过程 :使用
model.eval()
将模型设置为评估模式,禁用 Dropout 等操作。在验证时,使用torch.no_grad()
禁用梯度计算,以节省内存和计算资源。
- 模型保存和早停策略:
python
if mean_valid_loss < best_loss:
best_loss = mean_valid_loss
torch.save(model.state_dict(), config['save_path']) # Save your best model
print('Saving model with loss {:.3f}...'.format(best_loss))
early_stop_count = 0
else:
early_stop_count += 1
if early_stop_count >= config['early_stop']:
print('\nModel is not improving, so we halt the training session.')
return
-
保存最好的模型:如果当前验证损失比之前的最好损失更小,保存当前模型的参数,并重置早停计数器。
-
早停机制 :如果验证损失连续多次没有改善(由
early_stop_count
控制),则停止训练,避免过拟合。
9、超参数字典 config
python
device = 'cuda' if torch.cuda.is_available() else 'cpu'
config = {
'seed': 5201314, # Your seed number, you can pick your lucky number. :)
'select_all': True, # Whether to use all features.
'valid_ratio': 0.2, # validation_size = train_size * valid_ratio
'n_epochs': 5000, # Number of epochs.
'batch_size': 256,
'learning_rate': 1e-5,
'early_stop': 600, # If model has not improved for this many consecutive epochs, stop training.
'save_path': './models/model.ckpt' # Your model will be saved here.
}
这段代码设置了一个字典 config
,其中包含了一些重要的配置参数,这些参数将在模型训练过程中使用。这些配置定义了训练的基本设置、超参数、早停策略以及文件保存路径等内容。
10、准备和加载数据
python
same_seed(config['seed'])
train_data, test_data = pd.read_csv('./covid_train.csv').values, pd.read_csv('./covid_test.csv').values
train_data, valid_data = train_valid_split(train_data, config['valid_ratio'], config['seed'])
# Print out the data size.
print(f"""train_data size: {train_data.shape}
valid_data size: {valid_data.shape}
test_data size: {test_data.shape}""")
# Select features
x_train, x_valid, x_test, y_train, y_valid = select_feat(train_data, valid_data, test_data, config['select_all'])
# Print out the number of features.
print(f'number of features: {x_train.shape[1]}')
train_dataset, valid_dataset, test_dataset = COVID19Dataset(x_train, y_train), \
COVID19Dataset(x_valid, y_valid), \
COVID19Dataset(x_test)
# Pytorch data loader loads pytorch dataset into batches.
train_loader = DataLoader(train_dataset, batch_size=config['batch_size'], shuffle=True, pin_memory=True)
valid_loader = DataLoader(valid_dataset, batch_size=config['batch_size'], shuffle=True, pin_memory=True)
test_loader = DataLoader(test_dataset, batch_size=config['batch_size'], shuffle=False, pin_memory=True)
这段代码主要用于准备和加载训练数据、验证数据和测试数据,为后续的训练和推理过程做准备。
11、创建并训练模型
python
model = My_Model(input_dim=x_train.shape[1]).to(device) # put your model and data on the same computation device.
trainer(train_loader, valid_loader, model, config, device)
这段代码的作用是创建并训练一个深度学习模型,确保模型和数据都被加载到同一个计算设备(GPU 或 CPU),并且开始训练。
12、加载并启动 TensorBoard
python
%reload_ext tensorboard
%tensorboard --logdir=./runs/
这两行代码是在 Jupyter Notebook 中用于加载并启动 TensorBoard 的。
13、使用训练好的模型进行预测
python
def save_pred(preds, file):
''' Save predictions to specified file '''
with open(file, 'w') as fp:
writer = csv.writer(fp)
writer.writerow(['id', 'tested_positive'])
for i, p in enumerate(preds):
writer.writerow([i, p])
model = My_Model(input_dim=x_train.shape[1]).to(device)
model.load_state_dict(torch.load(config['save_path']))
preds = predict(test_loader, model, device)
save_pred(preds, 'pred.csv')
这段代码的目的是使用训练好的模型进行预测,并将预测结果保存到指定的文件中。它分为三个主要步骤:加载模型、进行预测、保存预测结果。
14、下载文件到本地
python
from google.colab import files
files.download('pred.csv')
这段代码是用于在 Google Colab 环境中下载文件。具体来说,它通过 files.download()
方法将本地文件(pred.csv
)下载到你的本地计算机。