国科大深度学习课程作业(2023)
这个文档是下面四个实验报告的预置内容,主要介绍了一下实验项目文件结构和实验流程。
整体代码可以到仓库查看:https://github.com/Noitolar/CourseDL.git
- checkpoints:保存的模型权重
- mnist.conv.pt
- dogs_vs_cats.resnet18.pt
- poem(640).lstm.pt
- movie.conv.pt
- datasets:数据集
- mnist
- dogs_vs_cats
- poem(640)
- movie
- logs:实验日志
- mnist.conv.log
- dogs_vs_cats.resnet18.log
- poem(640).lstm.log
- movie.conv.log
- utils:工具类和工具函数
- __init__.py
- cv:前两个实验用到的
- __init__.py
- config.py:实验配置
- dataset.py:数据集处理
- handler.py:模型操作
- nnmodels.py:神经网络模型
- recorder.py:实验记录
- trainer.py:模型训练和评估
- nlp:后两个实验用到的
- __init__.py
- config.py
- dataset.py
- handler.py
- nnmodels.py
- recorder.py
- trainer.py
- task_01.py:实验一
- task_02.py:实验二
- task_03.py:实验三
- task_04.py:实验四
由于面对对象式的编程风格,四个实验的实验流程基本一致,包括但不限于:
-
初始化实验配置:
- 神经网络模型类名
- 神经网络模型参数
- 设备
- 损失函数类名
- 损失函数参数
- 日志文件路径
- 数据集名称
- 随机种子
- 训练集预处理(CV)
- 验证集预处理(CV)
- 批大小
- 迭代轮数
- 优化器类名
- 优化器参数
- 学习率调整策略类名
- 学习率调整策略参数
- 权重文件路径
-
基于配置初始化模型Handler
-
将配置内容记录在日志
-
基于配置初始化数据集和加载器
-
基于配置初始化训练器
-
进行对应轮次的训练和验证/生成,并将结果记录在日志中
下面以task_01.py为例:
import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data as tdata
import torchvision.transforms as trans
import utils.cv as ucv
if __name__ == "__main__":
# 实验配置
config = ucv.config.ConfigObject()
config.model_class = ucv.nnmodels.SimpleConvClassifier
config.model_params = {"num_classes": 10, "num_channels": 1}
config.device = "cuda:0"
config.criterion_class = nn.CrossEntropyLoss
config.criterion_params = {}
config.log_path = "./logs/mnist.conv.log"
config.dataset = "mnist"
config.seed = 0
config.trn_preprocess = trans.Compose([trans.ToTensor(), trans.Normalize(mean=[0.485], std=[0.229])])
config.val_preprocess = config.trn_preprocess
config.batch_size = 32
config.num_epochs = 8
config.optimizer_class = optim.SGD
config.optimizer_params = {"lr": 0.001, "momentum": 0.9, "nesterov": True}
config.scheduler_class = optim.lr_scheduler.MultiStepLR
config.scheduler_params = {"milestones": [4, 6], "gamma": 0.1}
config.checkpoint_path = "./checkpoints/mnist.conv.pt"
# 初始化模型Handler
handler = ucv.handler.ModelHandlerCv(config)
# 将配置录入日志
handler.log_config()
# 初始化数据集和加载器
trn_set, val_set = ucv.dataset.get_dataset(config)
trn_loader = tdata.DataLoader(trn_set, batch_size=config.batch_size, shuffle=True)
val_loader = tdata.DataLoader(val_set, batch_size=config.batch_size * 8)
# 初始化训练器
trainer = ucv.trainer.Trainer(handler)
# 训练并记录结果
best_val_accuracy = 0.0
for epoch in range(config.num_epochs):
handler.log(" " + "=" * 40)
trn_report = trainer.train(trn_loader)
handler.log(f" [{epoch + 1:03d}] trn-loss: {trn_report['loss']:.4f} --- trn-acc: {trn_report['accuracy']:.2%}")
val_report = trainer.validate(val_loader)
handler.log(f" [{epoch + 1:03d}] val-loss: {val_report['loss']:.4f} --- val-acc: {val_report['accuracy']:.2%}")
if val_report["accuracy"] > best_val_accuracy:
best_val_accuracy = val_report["accuracy"]
if config.checkpoint_path is not None:
torch.save(handler.model.state_dict, config.checkpoint_path)
handler.log(f"[=] best-val-acc: {best_val_accuracy:.2%}")