当前位置: 首页 > news >正文

HW1 code analysis (Machine Learning by Hung-yi Lee)

Download data 

!gdown --id '1kLSW_-cW2Huj7bh84YTdimGBOJaODiOS' --output covid.train.csv
!gdown --id '1iiI5qROrAhZn-o4FPqsE97bMzDEFvIdg' --output covid.test.csv

这段代码是使用 gdown 命令行工具从 Google Drive 下载文件的命令,适用场景:Google Colab、Jupyter Notebook 或其他支持 ! 执行终端命令的 Python 环境。

Import packages

# 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
  • numpy 是 Python 中用于科学计算的核心库,特别适合处理数组和矩阵运算。NumPy 的名字来源于“Numerical Python”

  • 它提供了高效的数值计算工具,支持多维数组和矩阵操作。

  • pandas 是 Python 中用于数据处理和分析的核心库,特别适合处理结构化数据(如表格数据)。

  • 它提供了高效的数据结构(如 DataFrame 和 Series)和丰富的功能,用于数据读取、清洗、分析和可视化。

  • os 模块提供了与操作系统交互的功能,例如文件路径操作、目录管理、环境变量访问等。os是operating system的缩写

  • csv模块提供了读取和写入 CSV 文件的功能。

  • CSV(Comma-Separated Values,逗号分隔值)是一种常见的文件格式,用于存储表格数据,如电子表格或数据库中的数据。CSV 文件以纯文本形式存储数据,每行是一个数据记录,字段之间通过逗号分隔。它具有简单、通用性强的特点,广泛应用于数据交换和存储。

  • tqdm 是一个用于显示进度条的 Python 库,名字来源于阿拉伯语单词 "taqaddum"(تقدّم),意思是“进展”或“进度”。

  • 它可以在循环或长时间运行的任务中显示一个动态的进度条,帮助用户直观地了解任务的完成情况。

  • torch 是 PyTorch 的核心模块,提供了张量(Tensor)操作、自动求导、数学函数等功能。

  • torch.nn 提供了构建神经网络层和模型的工具。

  • 它包含各种层(如全连接层、卷积层、循环神经网络层等)和损失函数。

  • Dataset:用于定义自定义数据集。

  • DataLoader:用于批量加载数据,支持多线程数据加载和数据打乱。

  • random_split:用于将数据集随机划分为训练集和验证集。

  • SummaryWriter 是 PyTorch 提供的用于将数据写入 TensorBoard 日志的类。

  • 通过它,你可以将训练过程中的标量(如损失、准确率)、图像、直方图等数据记录到日志文件中,然后在 TensorBoard 中查看。

 Some Utility Functions

def same_seed(seed): '''Fixes random number generator seeds for reproducibility.'''torch.backends.cudnn.deterministic = Truetorch.backends.cudnn.benchmark = Falsenp.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_sizetrain_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
  • train_valid_split将提供的数据集划分为训练集和验证集。

  • 使用 random_split 函数进行随机划分,并通过设置随机种子确保结果可重复。

  • predit函数代码逐行解释

  • def predict(test_loader, model, device):

    • 这是一个函数定义,函数名为predict,接受三个参数:

      • test_loader: 数据加载器,通常是一个DataLoader对象,用于批量加载测试数据。

      • model: 训练好的机器学习模型,通常是一个torch.nn.Module的子类。

      • device: 指定模型和数据所在的设备,通常是'cpu''cuda'(GPU)。

  • model.eval()

    • 将模型设置为评估模式。在PyTorch中,模型有两种模式:训练模式(model.train())和评估模式(model.eval())。在评估模式下,模型会关闭一些训练时特有的行为,比如Dropout和Batch Normalization的随机性,以确保推理结果的一致性。

  • preds = []

    • 初始化一个空列表preds,用于存储每个批次的预测结果。

  • for x in tqdm(test_loader):

    • 使用tqdm库对test_loader进行迭代,tqdm是一个进度条库,可以在循环中显示进度条,方便观察数据处理进度。

    • x是当前批次的数据,通常是一个张量(Tensor),包含了输入特征。

  • x = x.to(device)

    • 将当前批次的数据x转移到指定的设备(CPU或GPU)上。这一步是为了确保数据和模型在同一个设备上,以便进行后续的计算。

  • with torch.no_grad():

    • with语句用于创建一个上下文管理器,torch.no_grad()是PyTorch提供的一个上下文管理器,用于禁用梯度计算。

    • 在推理阶段,我们不需要计算梯度,因为不会进行反向传播和参数更新。禁用梯度计算可以减少内存消耗并加速计算。

  • pred = model(x)

    • 将输入数据x传递给模型model,得到模型的输出pred,即模型的预测结果。

  • preds.append(pred.detach().cpu())

    • pred.detach():将预测结果从计算图中分离,避免梯度计算。

    • .cpu():将预测结果从GPU转移到CPU(如果之前是在GPU上计算的)。

    • preds.append(...):将处理后的预测结果添加到preds列表中。

  • preds = torch.cat(preds, dim=0).numpy()

    • torch.cat(preds, dim=0):将列表preds中的所有预测结果沿着第0维度(通常是批次维度)拼接成一个大的张量。

    • .numpy():将PyTorch张量转换为NumPy数组,方便后续处理或保存。

  • return preds

    • 返回最终的预测结果,通常是一个NumPy数组。

Dataset

class COVID19Dataset(Dataset):'''x: Features.y: Targets, if none, do prediction.'''def __init__(self, x, y=None):if y is None:self.y = yelse: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)

Neural Network Model

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

Feature 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_dataif 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
  • 返回筛选后的特征(x_train, x_valid, x_test)和目标值(y_train, y_valid

Training Loop

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.9) 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, 0for 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 += 1loss_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_losstorch.save(model.state_dict(), config['save_path']) # Save your best modelprint('Saving model with loss {:.3f}...'.format(best_loss))early_stop_count = 0else: early_stop_count += 1if early_stop_count >= config['early_stop']:print('\nModel is not improving, so we halt the training session.')return

1. 初始化设置

  • 损失函数:使用 MSELoss(均方误差),适用于回归任务。

  • 优化器:选择 SGD(随机梯度下降)并设置动量 (momentum=0.9),但缺少 weight_decay(L2正则化)。

  • 可视化工具:通过 SummaryWriter() 记录训练过程(TensorBoard支持)。

  • 模型保存目录:检查并创建 ./models 文件夹

 

2. 训练循环

  • 训练模式model.train() 启用Dropout/BatchNorm等训练专用层。

  • 进度条tqdm 实时显示训练进度和当前损失。

  • 梯度管理

    • optimizer.zero_grad() 清空梯度。

    • loss.backward() 反向传播计算梯度。

    • optimizer.step() 更新参数。

  • 设备转移:数据 (x, y) 显式移动到指定设备(如GPU)。

关键细节

  • loss.detach().item() 确保损失值从计算图中分离并转为Python标量。

  • 每个batch的损失记录到 loss_record,最后计算平均训练损失。


3. 验证阶段

  • 评估模式model.eval() 关闭Dropout/BatchNorm的随机性。

  • 无梯度计算with torch.no_grad() 块内禁用自动求导,节省内存/计算资源。

  • 验证损失:同训练损失计算方式,但仅作评估,不反向传播。

注意事项

  • 验证集应参与模型选择和早停,但不参与参数更新。


4. 模型保存与早停

  • 最佳模型保存:当验证损失 (mean_valid_loss) 低于历史最佳时,保存模型到 config['save_path']

  • 早停机制:若验证损失连续 early_stop 次未改善,终止训练。

5. 日志与输出

  • 控制台输出:打印每轮的训练/验证损失。

  • TensorBoard记录:通过 writer.add_scalar 保存损失变化,便于可视化分析。

 

 Configurations

config contains hyper-parameters for training and the path to save your model.

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': 3000,     # Number of epochs.            'batch_size': 256, 'learning_rate': 1e-5,              'early_stop': 400,    # If model has not improved for this many consecutive epochs, stop training.     'save_path': './models/model.ckpt'  # Your model will be saved here.
}

Dataloader

Read data from files and set up training, validation, and testing sets. You do not need to modify this part. 

# Set seed for reproducibility
same_seed(config['seed'])# train_data size: 2699 x 118 (id + 37 states + 16 features x 5 days) 
# test_data size: 1078 x 117 (without last day's positive rate)
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)

Start training!

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)

 

上述内容来自李宏毅教授Machine Learning课程与deepseek

http://www.xdnf.cn/news/249085.html

相关文章:

  • gephi绘图
  • 自动剪辑批量混剪视频过原创软件工具视频帧级处理技术实践批量截图解析
  • Python实例题:Python实现Python解释器
  • C++的基础知识(引用、类、封装、继承、多态、函数重载)
  • 驱动读写实验
  • GRPO:利用组内平均奖励来计算优势
  • 蓝桥杯Python案例
  • 计算机组成原理实验(5) 堆栈寄存器实验
  • 2025五一杯数学建模ABC题赛题已出
  • ctfshow web入门 web44
  • Python学习笔记(第一部分)
  • 基于深度学习的人脸属性识别算法研究
  • 随机森林实战:从原理到垃圾邮件分类
  • 超稳定性理论
  • 第十四章:生产之路:LLM 应用部署、运维与优化
  • MOOS-ivp使用(一)——水下机器人系统的入门与使用
  • 【2025最新面经】暑期实习常问知识点
  • 前端面经 4
  • 【C++学习笔记】深入理解虚函数和多态
  • 简单句练习--语法基础
  • 50、【OS】【Nuttx】【OSTest】参数解析:函数定义
  • 当算力遇上堵车:AI如何让城市血管不再“血栓”?
  • OpenStack Yoga版安装笔记(25)Nova Cell理解
  • 黑马Java基础笔记-6
  • 伽利略如何测量光速?一场跨越山头的失败实验
  • VBA数据结构深度解析:基础类型、自定义类型与数组操作指南
  • Dagster资产工厂实战:从Python到YAML配置的高效ETL流程
  • 408真题笔记
  • 第十三章:LLM 应用质量保证:评估体系、工具与实战
  • 深入解析三大查找算法:线性查找、二分查找与哈希查找的原理与应用