国科大DL课四合一实战包:MNIST识别+猫狗分类+古诗生成+微博情感分析
2026/6/9 21:54:13 网站建设 项目流程

本文还有配套的精品资源,点击获取

简介:一套开箱即用的深度学习项目合集,覆盖图像识别、文本生成、自然语言处理三大方向。手写数字识别基于MNIST数据集,用CNN快速实现高准确率;猫狗图像分类提供完整数据预处理、数据增强与二分类训练流程;古诗生成支持RNN和Transformer两种结构,输入关键词即可输出押韵合规的七言/五言诗;微博情感判别针对中文短文本,完成从清洗、分词、向量化到LSTM/BiLSTM分类的全流程。每个项目都含main.py主入口、net/定义网络、utils/封装常用函数、data/组织原始与处理后数据、assets/存放模型权重与可视化结果、实验报告PDF(含loss曲线、参数配置、性能对比与问题复盘),以及详细README.md说明运行步骤。全部基于PyTorch,依赖通过requirements.txt统一管理,无需额外环境配置,适合课程设计、期末作业或自学练手。

1. 这不是课设模板,而是一套“能跑通、能讲清、能改得动”的深度学习实战脚手架

你有没有遇到过这样的情况:老师布置了“用深度学习做点什么”的课程设计,网上搜了一堆GitHub项目,点开一看——README里写着“pip install requirements.txt”,结果运行到第3行就报错“ModuleNotFoundError: No module named ‘torchvision.transforms’”;或者好不容易配好环境,训练跑起来了,但loss曲线像心电图一样上下乱跳,模型在验证集上准确率卡在50%不动,翻遍代码也找不到问题出在哪;更别提那些号称“支持古诗生成”的项目,输入“春风”,输出“春风春风春风春风”,押韵?平仄?格律?不存在的。

这个“国科大DL课四合一实战包”,就是为解决这些真实痛点而生的。它不叫“教学示例”,也不叫“Demo工程”,我更愿意把它称作一套可调试、可溯源、可延展的深度学习最小可行实践单元(MVP Unit)。四个项目——MNIST识别、猫狗分类、古诗生成、微博情感分析——分别对应图像识别、图像二分类、序列生成、短文本分类这四大经典任务类型,覆盖了从数据加载、预处理、模型搭建、训练循环、评估指标到结果可视化的完整闭环。更重要的是,每个项目都不是“黑箱式”的一键训练:net/目录里你能看到CNN每一层的通道数、卷积核尺寸、是否带BatchNorm;utils/里封装了中文分词器调用、图像增强策略组合、古诗韵脚检测逻辑;data/下不仅有原始数据链接,还有预处理脚本(比如把猫狗图片按8:2自动划分train/val,并生成CSV标签文件);assets/里存的不只是最终模型权重,还有每轮训练保存的checkpoint、loss和acc曲线图、甚至古诗生成过程中的attention热力图。实验报告PDF不是应付差事的格式文档,而是真正在记录“为什么选ResNet18而不是VGG16?”、“为什么LSTM隐藏层设为128而非256?”、“数据增强加了RandomRotation但没加Cutout,因为实测后者导致古诗生成韵律崩坏”这类决策背后的思考链。它面向的不是“想看看AI多神奇”的观众,而是“我要交作业、要答辩、要真正搞懂每一行代码在干什么”的本科生。你不需要从零搭环境,但必须能看懂main.pytrainer.train()这一行背后调用了多少个回调函数;你不需要自己写数据加载器,但应该明白DataLoadernum_workers=4pin_memory=True对GPU利用率的实际影响。这套包的价值,不在于它多炫酷,而在于它足够“诚实”——所有中间状态都暴露给你,所有选择理由都写进报告,所有坑都帮你踩过一遍,并且告诉你怎么绕过去。

2. 项目整体设计与思路拆解:为什么是这四个任务?为什么这样组织?

2.1 四个任务的选型逻辑:覆盖能力谱系,拒绝功能堆砌

这四个项目绝非随意拼凑,而是严格遵循“能力递进+领域覆盖”双维度筛选:

  • MNIST识别(HandwrittenNumeralRecognition):这是深度学习的“Hello World”,但本项目刻意规避了“抄个LeNet就完事”的惰性。它采用轻量级CNN架构(3层卷积+2层全连接),参数量控制在20万以内,确保在CPU上也能10分钟内完成一轮完整训练。关键设计在于预处理与归一化策略的显式暴露utils/preprocess.py中明确区分了normalize_to_01()(像素值除以255)和normalize_to_neg1_1()(减均值除标准差),并在实验报告中对比了二者对收敛速度的影响——前者训练初期loss下降快但易震荡,后者收敛更稳但首epoch loss偏高。这不是为了炫技,而是让学生第一时间建立“数据分布直接影响模型行为”的直觉。

  • 猫狗分类(DogCat):作为图像二分类的典型代表,它承担着“承上启下”的作用。上承MNIST的CNN基础,下启更复杂的视觉任务。项目未直接使用ImageNet预训练模型(如ResNet50),而是从零训练一个定制化CNN(DogCatNet),结构为:Conv(3,64)→BN→ReLU→MaxPool → Conv(64,128)→BN→ReLU→MaxPool → Conv(128,256)→BN→ReLU→GlobalAvgPool → Linear(256,2)。选择GlobalAvgPool而非Flatten,是为了强制模型学习空间不变性特征,避免全连接层过度拟合局部纹理。数据增强策略也做了精细化设计:训练时启用RandomHorizontalFlip(p=0.5) + RandomRotation(degrees=15) + ColorJitter(brightness=0.2, contrast=0.2),验证时仅用Resize(256)→CenterCrop(224)。实验报告中特别指出,移除ColorJitter后,模型在光照变化大的测试图上准确率下降3.2%,印证了色彩扰动对泛化性的必要性。

  • 古诗生成(AutoPoetry):这是整个包的技术制高点,也是最容易“翻车”的模块。它同时提供RNN(LSTM)与Transformer两种实现,并非为了堆砌技术名词,而是服务于不同教学目标:RNN版本(models/rnn_poet.py)代码行数少、状态传递逻辑清晰,适合理解“序列建模”的本质;Transformer版本(models/transformer_poet.py)则完整实现了PositionalEncoding、MultiHeadAttention、LayerNorm等核心组件,且针对中文古诗特性做了三处关键改造:① 词嵌入层使用nn.Embedding(vocab_size, d_model, padding_idx=0),显式指定padding索引;② 解码器自注意力掩码(causal mask)采用torch.tril(torch.ones(seq_len, seq_len)),确保预测第i字时只能看到前i-1字;③ 在损失函数计算时,屏蔽掉 和 标记的loss贡献(通过ignore_index参数),防止模型被无效token带偏。这种“同一任务,双路径实现”的设计,让学生能直观对比两种范式的优劣——RNN训练快但长程依赖弱,Transformer生成质量高但需更多数据和算力。

  • 微博情感分析(SentimentAnalysis):作为NLP任务的代表,它直面中文短文本的现实挑战:噪声大(表情符号、网络用语)、长度短(平均15字)、标注稀疏(正负样本不均衡)。项目采用BiLSTM+Attention架构,而非简单LSTM,因为双向结构能同时捕获“太棒了!”和“不咋地…”这类依赖上下文的情感极性。预处理流程极为务实:utils/clean_text.py中,先用正则re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9\s]', '', text)清洗非法字符,再调用jieba.lcut()分词,最后用collections.Counter统计词频,动态构建词表(vocab)并设定min_freq=2,将低频词统一映射为<UNK>。实验报告中坦诚指出:若直接使用预训练词向量(如Word2Vec),在微博新词(如“绝绝子”、“yyds”)上效果反而不如随机初始化,因此本项目采用随机初始化词向量+微调策略,更符合本科生项目的数据规模实际。

这四个任务构成了一条清晰的能力成长线:从静态图像识别(MNIST),到带数据增强的细粒度图像分类(猫狗),再到需要建模长程依赖的序列生成(古诗),最后到噪声环境下的短文本理解(微博)。每一个环节的复杂度提升都是可感知、可掌控的,没有一步登天的跳跃。

2.2 目录结构的工程哲学:资源隔离、职责分明、可追溯

整个包的目录组织,体现了一种克制而务实的工程思维,完全摒弃了“把所有东西塞进一个文件夹”的学生气做法:

. ├── README.md # 全局入口:一句话说明每个项目如何启动,依赖安装命令,常见问题速查 ├── requirements.txt # 统一依赖:只包含核心库(torch>=1.12,<2.0, torchvision, numpy, jieba, matplotlib),无冗余包 ├── data/ # 原始数据“只读区”:存放下载后的原始压缩包(如mnist.zip, dogs-vs-cats.zip),禁止修改 │ ├── MNIST/ │ ├── DogCat/ │ ├── AutoPoetry/ │ └── SentimentAnalysis/ ├── assets/ # 运行时“产出区”:模型权重(.pth)、可视化图表(.png)、生成文本(.txt)、日志(.log) │ ├── HandwrittenNumeralRecognition/ │ ├── DogCat/ │ ├── AutoPoetry/ │ └── SentimentAnalysis/ ├── net/ # 网络定义“契约区”:每个项目一个子目录,只放`__init__.py`和`model.py`,定义网络类(如`MNISTNet`, `DogCatNet`) │ ├── mnist/ │ ├── dogcat/ │ ├── autopoe/ │ └── sentiment/ ├── utils/ # 工具函数“共享池”:`data_loader.py`(统一数据加载逻辑)、`metrics.py`(accuracy, f1_score)、`visualize.py`(绘制loss曲线) │ ├── __init__.py │ ├── data_loader.py │ ├── metrics.py │ └── visualize.py ├── models/ # 模型实现“实验田”:RNN/Transformer古诗模型、BiLSTM情感模型等具体实现,可自由替换 │ ├── rnn_poet.py │ ├── transformer_poet.py │ └── bilstm_sentiment.py ├── main.py (x4) # 项目入口“开关”:每个项目一个独立main.py,内容高度一致(导入、配置、训练、评估),便于横向对比 └── 实验报告.pdf # 决策日志“档案馆”:每个项目单独章节,含模型结构图、超参表格、loss/acc曲线、失败案例复盘

这种结构的核心价值在于可追溯性(Traceability)。当你发现猫狗分类模型效果不佳时,你可以:
1. 查assets/DogCat/train_log.txt看loss是否收敛;
2. 看net/dogcat/model.py确认网络结构是否有误;
3. 检查data/DogCat/processed/下生成的train.csv标签是否正确;
4. 最后对照实验报告.pdf第3.2节,看作者是否提到“在batch_size=32时出现梯度爆炸,故调整为16”。

所有线索都指向明确位置,无需在混乱的文件堆里大海捞针。这正是工业级项目与课程设计的本质区别——后者追求“能跑”,前者追求“可知、可控、可迭代”。

3. 核心细节解析与实操要点:从代码到原理的穿透式解读

3.1 MNIST识别:轻量CNN里的归一化陷阱与梯度裁剪实践

MNIST项目看似简单,却是检验基础功底的试金石。main.py中关键训练循环如下:

# main.py (MNIST) for epoch in range(num_epochs): model.train() for batch_idx, (data, target) in enumerate(train_loader): data, target = data.to(device), target.to(device) optimizer.zero_grad() output = model(data) loss = criterion(output, target) loss.backward() # 关键:梯度裁剪 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) optimizer.step()

这段代码藏着三个极易被忽略的细节:

第一,归一化方式的选择直接影响收敛稳定性。
utils/preprocess.py提供了两种方案:
-normalize_to_01():data = data.float() / 255.0→ 输出范围[0, 1]
-normalize_to_neg1_1():data = transforms.Normalize((0.1307,), (0.3081))(data)→ 输出范围[-1, 1](均值0.1307,标准差0.3081是MNIST全局统计值)

实测对比显示:使用normalize_to_01()时,初始loss约2.3,前5epoch下降迅猛但波动剧烈(±0.15);而normalize_to_neg1_1()初始loss约3.1,但下降曲线平滑,10epoch后稳定在0.02以下。原因在于,Sigmoid/Tanh激活函数在输入接近0时梯度最大,[-1,1]的输入分布让神经元工作在梯度最敏感的区域,而[0,1]则使其偏向饱和区。这提醒我们:归一化不是“让数字变小”的形式主义,而是为激活函数创造最佳工作区间

第二,梯度裁剪(clip_grad_norm_)是防止训练崩溃的保险丝。
虽然MNIST数据干净,但轻量CNN在batch_size=128lr=0.01时,仍可能出现梯度爆炸(loss突增至inf)。max_norm=1.0意味着:计算所有参数梯度的L2范数,若大于1,则按比例缩放所有梯度,使其范数恰好为1。这不是“治标”,而是“保命”——它确保优化器不会因单次异常更新而彻底偏离轨道。我在调试时曾注释掉这行,结果第7epoch时loss从0.05飙升至nan,重启训练耗时15分钟;加上后,全程平稳。

第三,DataLoadernum_workerspin_memory需协同优化。
train_loader = DataLoader(dataset, batch_size=128, shuffle=True, num_workers=4, pin_memory=True)
-num_workers=4:启用4个子进程并行加载数据,避免GPU等待CPU预处理。但若设为0(默认),CPU单线程处理会成为瓶颈。
-pin_memory=True:将数据加载到GPU可直接访问的“锁页内存”(pinned memory),使data.to(device)速度提升3倍以上。实测关闭此选项,单epoch耗时从8s增至22s。

提示:在笔记本等内存受限设备上,若开启num_workers>0导致内存溢出,应优先降低batch_size,而非关闭多进程——因为pin_memory带来的加速收益远大于num_workers的内存开销。

3.2 猫狗分类:数据增强的“度”与验证集泄露的隐形杀手

猫狗分类项目的数据增强策略,在utils/data_augment.py中定义:

train_transform = transforms.Compose([ transforms.Resize(256), transforms.RandomResizedCrop(224, scale=(0.8, 1.0)), # 随机裁剪缩放 transforms.RandomHorizontalFlip(p=0.5), transforms.RandomRotation(degrees=15), transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # ImageNet均值标准差 ])

这里存在一个经典误区:为何不用更激进的增强(如Cutout、Mixup)?
实验报告第4.1节给出了答案:在data/DogCat/raw/中,部分猫狗图片存在明显拍摄角度倾斜或背景杂乱。当引入Cutout(p=0.5, size=32)(随机遮挡32x32区域)后,模型在验证集准确率从92.3%降至88.7%。分析错误样本发现,被遮挡的往往是动物的关键判别区域(猫的胡须、狗的鼻头),导致模型被迫学习背景纹理等虚假相关性。而ColorJitter则不同,它模拟了不同光照条件下的色彩变化,迫使模型关注形状与纹理等本质特征。这印证了一个原则:数据增强的目标不是“让数据更多”,而是“让模型更鲁棒”;任何增强都应服务于任务本质,而非技术炫技。

另一个致命陷阱是验证集泄露(Validation Leakage)。许多学生会这样操作:

# 错误示范:先全局归一化,再划分train/val all_images = load_all_images() all_images = normalize(all_images) # 对全部数据统一归一化! train_data, val_data = train_test_split(all_images, test_size=0.2)

这会导致验证集的统计信息(均值、标准差)污染了训练过程,使模型在验证时获得“作弊”优势。本项目严格采用先划分、后归一化

# 正确流程(见 data/dogcat/preprocess.py) train_paths, val_paths = split_train_val(raw_dir, val_ratio=0.2) # 分别计算train和val的均值标准差 train_mean, train_std = compute_stats(train_paths) val_mean, val_std = compute_stats(val_paths) # 注意:此处val_stats仅用于val transform!

train_transform使用train_mean/stdval_transform使用val_mean/std。虽然计算稍繁琐,但保证了评估的公正性。我在复现时曾忽略此点,导致验证准确率虚高3.5%,直到对比实验报告.pdf中的基线才发现问题。

3.3 古诗生成:RNN与Transformer的“状态”本质差异与韵脚约束实现

古诗生成的models/目录下,rnn_poet.pytransformer_poet.py的对比,是理解序列建模范式差异的最佳教材。

RNN(LSTM)版本的核心在于“隐状态(hidden state)”的传递:

# rnn_poet.py def forward(self, x, hidden): # x: [batch, seq_len], hidden: [num_layers, batch, hidden_size] embed = self.embedding(x) # [batch, seq_len, embed_dim] lstm_out, hidden = self.lstm(embed, hidden) # lstm_out: [batch, seq_len, hidden_size] output = self.classifier(lstm_out) # [batch, seq_len, vocab_size] return output, hidden

每次调用forward,都需要传入上一时刻的hidden,这体现了RNN的状态依赖性——生成第n个字,必须知道前n-1个字的累积状态。这种设计天然适合古诗的“起承转合”逻辑,但缺陷是长程依赖衰减(梯度消失)。

Transformer版本则彻底抛弃“状态”,代之以“注意力(attention)”:

# transformer_poet.py def forward(self, src, tgt): # src: [seq_len, batch], tgt: [seq_len, batch] (shifted right) src_emb = self.src_embedding(src) * math.sqrt(self.d_model) src_emb = self.pos_encoder(src_emb) # 加入位置编码 tgt_emb = self.tgt_embedding(tgt) * math.sqrt(self.d_model) tgt_emb = self.pos_encoder(tgt_emb) output = self.transformer(src_emb, tgt_emb) # 核心:多头自注意力+编码器-解码器注意力 return self.generator(output) # [seq_len, batch, vocab_size]

它不维护任何跨时间步的状态,而是通过src(输入诗句)与tgt(目标诗句,右移一位)之间的全局注意力权重,让模型在生成每个字时,都能“看到”整首诗的所有已生成字。这解决了RNN的长程依赖问题,但代价是计算量大增。

最关键的工程实现是韵脚约束。古诗要求偶数句押韵(如七言绝句的2、4句押韵)。项目在utils/poem_utils.py中实现了:

def is_rhyme(word1, word2): """基于《中华新韵》简表,判断两字是否同韵""" rhyme_dict = { 'a': ['a', 'ia', 'ua'], 'o': ['o', 'uo'], 'e': ['e', 'ie', 'ue'], 'i': ['i', 'in', 'ing'], 'u': ['u', 'un', 'ong'], 'ü': ['ü', 'ün', 'üng'] } # 获取拼音韵母 pinyin1 = lazy_pinyin(word1, style=FINALS)[0] if word1 else '' pinyin2 = lazy_pinyin(word2, style=FINALS)[0] if word2 else '' # 匹配韵部 for key, finals in rhyme_dict.items(): if pinyin1 in finals and pinyin2 in finals: return True return False def enforce_rhyme(generated_poem, target_rhyme_word): """在生成末句时,强制最后一个字与target_rhyme_word押韵""" candidates = get_rhyme_words(target_rhyme_word) # 从词典获取同韵字 # 在模型输出的top-k预测中,只保留candidates中的字 logits = model_output[:, -1, :] # 最后一个位置的logits mask = torch.zeros_like(logits) for idx in candidates_idx: mask[:, idx] = 1 masked_logits = logits.masked_fill(mask == 0, float('-inf')) return torch.softmax(masked_logits, dim=-1)

这种“后处理约束”比在损失函数中加入韵律惩罚更直接有效,确保生成结果符合基本格律要求。

3.4 微博情感分析:中文分词的颗粒度博弈与类别不平衡的采样策略

微博情感分析面临的最大挑战是中文分词的歧义性。例如句子“苹果很好吃”,分词结果可能是:
-['苹果', '很', '好吃'](“苹果”作为水果名词)
-['苹', '果', '很', '好吃'](错误切分)

项目采用jieba.lcut()(精确模式),并在utils/clean_text.py中加入了规则后处理

def post_process_jieba(words): # 合并常见网络词 words = ''.join(words) words = re.sub(r'yyds', '永远的神', words) words = re.sub(r'绝绝子', '绝佳的', words) # 再次分词 return jieba.lcut(words)

这比单纯依赖词典更灵活,能适应网络语言演化。

更严峻的是类别不平衡:微博数据集中,正面样本占比约65%,负面仅35%。若直接训练,模型会倾向于预测“正面”,导致F1-score(负面类)极低。项目在data/sentiment/preprocess.py中实现了分层抽样(Stratified Sampling)

from sklearn.model_selection import train_test_split train_df, val_df = train_test_split( df, test_size=0.2, stratify=df['label'], # 按label列分层,保证train/val中正负比例一致 random_state=42 )

同时,在utils/data_loader.py中,为负面样本设置了更高的采样权重

# 计算每个样本的权重 class_counts = np.bincount(df['label']) weights = 1. / class_counts[df['label']] # 负面样本权重 = 1/0.35 ≈ 2.86 sampler = WeightedRandomSampler(weights, num_samples=len(weights), replacement=True) train_loader = DataLoader(dataset, sampler=sampler, ...)

双重保障下,模型在测试集上的负面类F1-score从0.42提升至0.76,证明了数据层面的工程投入,往往比模型调参更有效

4. 实操过程与核心环节实现:从零开始的完整复现指南

4.1 环境准备与依赖安装:一次配齐,终身受益

整个包的环境管理极度克制,requirements.txt仅包含6个核心依赖:

torch==1.13.1+cu117 torchvision==0.14.1+cu117 numpy==1.23.5 jieba==0.42.1 matplotlib==3.7.1 scikit-learn==1.2.2

关键点解析:
-torch==1.13.1+cu117:明确指定CUDA 11.7版本,避免与显卡驱动冲突。若你使用A100(CUDA 11.8),需手动修改为torch==1.13.1+cu118,并确保nvidia-smi显示的CUDA Version ≥ 11.8。
-jieba==0.42.1:锁定版本,因为新版jieba的lcut()对网络词处理逻辑有变更,可能导致分词结果不一致。
- 无pandasseaborn等“看起来有用”的包:所有数据处理均用numpy和原生Python,减少依赖链断裂风险。

安装命令(推荐conda):

# 创建独立环境(避免污染主环境) conda create -n dl_course python=3.9 conda activate dl_course # 安装PyTorch(根据你的CUDA版本选择,此处以11.7为例) pip3 install torch==1.13.1+cu117 torchvision==0.14.1+cu117 --extra-index-url https://download.pytorch.org/whl/cu117 # 安装其余依赖 pip install -r requirements.txt

注意:若使用M1/M2 Mac(无CUDA),需将torch行改为torch==1.13.1(CPU版),并删除torchvision+cu117后缀。此时训练速度会慢,但保证功能完整。

4.2 数据准备全流程:自动化脚本,拒绝手动搬运

所有数据预处理均由data/*/preprocess.py脚本驱动,以猫狗分类为例:

# 进入猫狗项目目录 cd data/DogCat/ # 下载原始数据(需科学上网,但项目已提供百度网盘备用链接) wget https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_3367a.zip # 解压 unzip kagglecatsanddogs_3367a.zip # 运行预处理脚本(自动完成:重命名、划分train/val、生成CSV、归一化统计) python preprocess.py --raw_dir "PetImages" --output_dir "processed" --val_ratio 0.2

preprocess.py的核心逻辑:
1. 扫描PetImages/Cat/PetImages/Dog/目录,过滤掉损坏图片(用PIL.Image.open().verify());
2. 将图片统一调整为256x256,并按8:2比例随机划分到processed/train/processed/val/
3. 生成train.csvval.csv,格式为:
filename,label cat_001.jpg,0 dog_002.jpg,1
4. 计算processed/train/中所有图片的RGB通道均值与标准差,写入stats.json

此脚本确保了数据准备过程100%可复现。你无需记住“要把图片放到哪个文件夹”,只需执行一条命令,剩下的交给脚本。我在第一次运行时,因原始数据包里混有.db文件导致PIL报错,脚本自动跳过并记录在preprocess.log中,极大降低了排错成本。

4.3 模型训练与监控:从main.py到assets的完整证据链

每个项目的main.py是训练的唯一入口。以古诗生成为例:

# 进入古诗项目根目录 cd AutoPoetry/ # 使用RNN模型训练(默认) python main.py --model rnn --epochs 50 --lr 0.001 # 或使用Transformer模型(需更多GPU显存) python main.py --model transformer --epochs 30 --lr 0.0005

main.py执行后,会在assets/AutoPoetry/下生成:
-checkpoints/:每5个epoch保存一个.pth文件,如rnn_epoch_45.pth
-logs/train_log.txt记录每轮loss、acc,gen_sample.txt保存生成的古诗示例;
-figures/loss_curve.pngacc_curve.pngattention_heatmap.png(Transformer专属);
-models/:最终模型best_model.pth(验证集loss最低者)。

关键监控技巧:
- 实时查看训练日志:tail -f assets/AutoPoetry/logs/train_log.txt
- 若loss长时间不降,立即检查assets/AutoPoetry/logs/gen_sample.txt中的生成结果——若全是重复字(如“山山山山”),大概率是学习率过高或梯度爆炸,需降低--lr或增大--clip_grad值。
-attention_heatmap.png是Transformer的“X光片”:理想情况下,生成第5个字时,注意力权重应集中在前4个字上;若权重均匀分布,则说明模型未学会依赖关系。

4.4 结果评估与报告撰写:如何把实验过程变成答辩亮点

实验报告.pdf不是终点,而是你课程设计的起点。它提供了完整的答辩话术框架

报告章节你可以这样讲(答辩口语化表达)为什么能加分
3.1 模型选择依据“我对比了CNN、ResNet18和VGG16,最终选CNN,因为MNIST是灰度图,深层网络容易过拟合;而且我的GPU显存只有4G,ResNet18加载后只剩1G显存,根本跑不动。”展示了工程权衡能力,而非盲目追新
4.3 失败案例复盘“最初用Cutout增强,准确率掉了3个点。我画了混淆矩阵,发现模型把很多‘狗’错判成‘猫’,因为Cutout把狗的耳朵遮住了——这说明增强不能破坏关键特征。”体现批判性思维和问题定位能力
5.2 参数敏感性分析“我把batch_size从32调到64,训练快了,但验证准确率降了1.2%。因为更大的batch让梯度估计更准,但也减少了参数更新次数,对小数据集不利。”证明你真正理解了超参含义

撰写建议:
- 直接复制实验报告.pdf中对应章节的图表(loss曲线、混淆矩阵),但务必用自己的数据重绘。答辩老师一眼就能看出真假。
- 在“问题分析”部分,至少写一个你真实遇到并解决的问题(如“训练时GPU显存不足,通过减小batch_size和启用gradient checkpointing解决”)。空洞的“未来可改进”毫无价值。
- 所有结论必须有数据支撑:“模型准确率92.3%”比“模型效果很好”有力一万倍。

5. 常见问题与排查技巧实录:那些让你抓狂的报错,我都替你踩过了

5.1 经典报错速查表

报错信息根本原因一行解决命令为什么有效
ModuleNotFoundError: No module named 'torchvision.transforms'torchvision版本与torch不匹配pip uninstall torchvision && pip install torchvision==0.14.1+cu117torch==1.13.1必须配torchvision==0.14.1,版本错位会导致模块缺失
RuntimeError: CUDA out of memoryGPU显存不足(尤其Transformer古诗)python main.py --model transformer --batch_size 8 --num_workers 0减小batch_size直接降低显存占用;num_workers=0避免子进程额外内存开销
ValueError: Expected input batch_size (128) to match target batch_size (64)数据加载器与模型输入尺寸不一致检查data/*/preprocess.pyresize尺寸是否与net/*/model.pynn.AdaptiveAvgPool2d()参数匹配图像尺寸不一致会导致张量广播失败,必须前后端统一
UnicodeDecodeError: 'gbk' codec can't decode byte 0xadWindows系统读取UTF-8文件报错main.py开头添加:import locale; locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')强制Python使用UTF-8编码读取文件,解决中文路径乱码

5.2 独家避坑技巧:来自真实战场的经验

技巧1:Loss曲线“假收敛”的识别与应对
现象:loss_curve.png显示loss持续下降,但验证准确率停滞在50%(随机猜测水平)。
排查步骤:
1. 打开assets/*/logs/train_log.txt,搜索val_acc,确认是否真的卡住;
2. 检查data/*/processed/train.csvval.csv的标签分布——是否val.csv里全是同一类?(数据划分bug);
3.终极验证:在main.py中临时注释掉model.train(),改为model.eval(),用torch.no_grad()跑一遍验证集。若此时准确率飙升,说明是BatchNorm层在训练/评估模式下行为不一致导致的。

技巧2:古诗生成“无意义重复”的急救方案
现象:生成结果为“春风春风春风春风”。
原因:模型陷入局部最优,对起始符<START>过度依赖。
解决方案(三选一):
-短期急救:在models/rnn_poet.pyforward函数中,给初始hidden状态加微小噪声:hidden = hidden + torch.randn_like(hidden) * 0.1
-中期调整:在main.py中启用--teacher_forcing_ratio 0.5(教师强制概率50%),让模型一半时间看真实前序字,一半时间看自己生成的字;
-长期根治:检查utils/poem_utils.py中的get_rhyme_words()函数,确保其返回的候选字足够丰富(≥50个),避免模型因选择太少而重复。

技巧3:微博情感分析F1-score偏低的“作弊”排查法
现象:准确率85%,但负面类F1只有0.3。
不要急着换模型!先做这个检查:

# 在 main.py 评估后添加 from sklearn.metrics import classification_report print(classification_report(y_true, y_pred))

若输出显示:

precision recall f1-score support 0 0.95 0.92 0.93 1200 1 0.30 0.15 0.20 300

说明模型严重偏向正面类。此时立刻检查data/SentimentAnalysis/processed/下的train.csv:用pandas.read_csv().label.value_counts()确认正负样本数。若比例不是1:1,则证明WeightedRandomSampler未生效,需检查sampler是否正确传入DataLoader

我在答辩前2小时发现此问题,紧急重跑预处理脚本,最终F1提升至0.76,成功救回答辩分数。记住:在NLP任务中,数据分布比模型结构重要十倍。

6. 项目延展与个人定制:如何把“四合一”变成你的“五合一”、“六合一”

这套包的价值,不仅在于它能跑通,更在于它为你提供了可生长的骨架。我鼓励你基于它做增量创新,而非止步于复现:

6.1 轻量级扩展:增加一个“第五项目”

想加入新任务?比如“新闻标题分类”或“手写汉字识别”?只需遵循现有范式:
1. 在根目录创建新文件夹NewsClassification/
2. 复制net/mnist/net/news/,修改model.pyNewsClassifier
3. 复制data/sentiment/preprocess.pydata/news/preprocess.py,适配新闻数据格式;
4. 复制main.pymain_news.py,修改导入路径和参数;
5. 更新README.md,添加启动命令。

整个过程不超过1小时,因为你复用的是经过验证的utils/assets/管理逻辑。这比从零开始搭项目快5倍。

6.2 深度定制:替换核心组件,理解技术本质

  • 替换优化器:将main.py中的torch.optim.Adam换成torch.optim.SGD,并添加momentum=0.9。你会发现收敛变慢但最终loss更低——这揭示了Adam的自适应学习率虽快,却可能错过更优解。
  • 替换损失函数:在微博情感分析中,将nn.CrossEntropyLoss()换成nn.BCEWithLogitsLoss()(需修改输出层为单节点+Sigmoid),观察F1-score变化。你会理解多分类与二分类损失函数的设计哲学。
  • 替换评估指标:在猫狗分类中,不只看准确率,用utils/metrics.py中的confusion_matrix计算精确率、召回率、F1-score,并画出ROC曲线。这让你真正理解“模型好坏”不止一个数字。

6.3 答辩高光时刻:一个让老师眼前一亮的小技巧

在演示古诗生成时,不要只输入“春天”,试试输入“春天+悲伤”。然后打开models/transformer_poet.py,找到generate()函数,在torch.argmax()前插入:

# 添加温度系数(temperature scaling) logits = logits / temperature # temperature=0.7 probs = torch.softmax(logits, dim=-1) next_token = torch.multinomial(probs, num_samples=1)

重新训练后,生成结果会从刻板的“春眠不觉晓”变为更有创造力的“春寒料峭花自凋”。在答辩时说:“我加入了温度采样,让模型在确定性和创造性间取得平衡——就像诗人既要守格律,也要有灵光一现。” 这句话,足以让老师记住你。

这套包的终极目的,不是让你交一份作业,而是帮你建立一种深度学习工程师的思维习惯:看到一个任务,能立刻拆解为数据、模型、训练、评估四个模块;遇到一个问题,能沿着assets/net/data/utils/的路径精准定位;做出一个选择,能说出“为什么不是别的”。当你能自然地说出“这个loss曲线的震荡,是因为学习率太大,而验证集准确率平台期,说明模型容量已饱和”,你就已经超越了90%的同学。现在,打开终端,输入python main.py,让代码跑起来——真正的学习,永远始于第一行print("Hello DL!")的输出。

本文还有配套的精品资源,点击获取

简介:一套开箱即用的深度学习项目合集,覆盖图像识别、文本生成、自然语言处理三大方向。手写数字识别基于MNIST数据集,用CNN快速实现高准确率;猫狗图像分类提供完整数据预处理、数据增强与二分类训练流程;古诗生成支持RNN和Transformer两种结构,输入关键词即可输出押韵合规的七言/五言诗;微博情感判别针对中文短文本,完成从清洗、分词、向量化到LSTM/BiLSTM分类的全流程。每个项目都含main.py主入口、net/定义网络、utils/封装常用函数、data/组织原始与处理后数据、assets/存放模型权重与可视化结果、实验报告PDF(含loss曲线、参数配置、性能对比与问题复盘),以及详细README.md说明运行步骤。全部基于PyTorch,依赖通过requirements.txt统一管理,无需额外环境配置,适合课程设计、期末作业或自学练手。


本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询