ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

CNN图像风格迁移毕设源码:从环境配置到训练推理全流程

CNN图像风格迁移毕设源码:从环境配置到训练推理全流程 简介这份资源是面向计算机、人工智能、通信工程等专业学生与教师的图像风格迁移完整项目包基于CNN卷积神经网络实现可作为毕业设计、课程设计或项目立项演示也适合具备一定Python基础的学习者进阶参考。包内共93个文件涵盖9个py源码、4个pth预训练模型、40张jpg与17张png风格及内容示例图、3段mp4演示视频以及html、css等前端页面文件压缩包约57.03MB目录结构清晰便于按模块查阅。项目已通过运行测试提供图片与视频两种风格迁移功能并附带训练脚本与操作说明读者可据此完成环境配置、模型训练与效果验证也可在现有代码基础上修改以扩展新功能。目前已有1144人学习下载适合需要完整方案与可复用代码的读者参考借鉴。1. 从一份能跑通的毕设源码说起CNN 图像风格迁移到底交付了什么如果你正在找一份能直接跑起来的 CNN 图像风格迁移毕设源码这份资源大概率能省掉你两周的调试时间。它不是那种只丢几个.py文件、缺模型权重、跑起来一堆报错的半成品而是把训练脚本、推理脚本、预训练模型、Web 交互界面、视频处理入口全部打包好了。解压后你会看到train.py、neural_style.py、app.py、test_on_image.py、test_on_video.py这些核心文件checkpoints目录里躺着cuphead_10000.pth、sketch_2000.pth、starry_night_28000_vgg16.pth、mosaic_10000.pth四个已经训练好的风格模型images/styles和images/content里备好了梵高、毕加索、蒙克等风格图和一批内容图。换句话说你拿到手就能做三件事用现成模型做图片风格迁移、用现成模型做视频风格迁移、用自己的数据集重新训练一个新风格模型。适合计算机、人工智能、通信工程等专业的在校生做毕设或课程设计也适合想快速验证风格迁移效果的开发者。下面我按实际拆包和跑通的顺序把环境、训练、推理、Web 端和踩坑点逐个讲清楚。2. 环境配置与依赖安装把 PyTorch、OpenCV、ffmpeg 一次装对2.1 为什么推荐 Anaconda PyCharm 而不是裸装 Python这份源码的依赖列表不算短PyTorch、torchvision、opencv、numpy、av、ffmpeg、skvideo、pillow、tqdm。如果你直接用系统 Python 装很容易出现torch和torchvision版本不匹配、ffmpeg找不到可执行文件、cv2导入报 DLL 缺失这类问题。我一般会建议用 Anaconda 建一个独立环境把 Python 版本锁在 3.8 或 3.9因为源码里__pycache__目录下能看到models.cpython-37.pyc、models.cpython-39.pyc、models.cpython-310.pyc说明作者在 3.7 到 3.10 都跑过但 3.8/3.9 的兼容性最稳。PyCharm Community Edition 2022.3.3 是操作说明里明确提到的版本用它的好处是能直接在 IDE 里配置解释器、看变量、打断点比在 cmd 里盲跑舒服得多。安装命令我习惯分两步走先建环境再装包conda create -n style_transfer python3.9 -y conda activate style_transfer这两行的作用是创建一个名为style_transfer的独立环境Python 版本指定 3.9。-y表示自动确认避免中途卡在交互提示。环境建好后所有后续安装都只影响这个环境不会污染系统 Python。2.2 依赖安装的先后顺序与版本约束PyTorch 的安装要看你的显卡。如果有 NVIDIA 显卡并且装了 CUDA去 PyTorch 官网选对应 CUDA 版本的命令如果没有显卡或者不想折腾直接装 CPU 版也能跑只是训练和视频推理会慢很多。我一般会先装 PyTorch 和 torchvision再装其他pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install opencv-python numpy av scikit-video pillow tqdm ffmpeg-python第一行是装 GPU 版 PyTorchcu118对应 CUDA 11.8你要根据自己的 CUDA 版本改。第二行里opencv-python负责图像读写和 resizeav和scikit-video负责视频帧解码ffmpeg-python是 ffmpeg 的 Python 封装。注意ffmpeg本身是一个独立的可执行程序pip 装的ffmpeg-python只是调用接口你还需要在系统里装 ffmpeg 并把它加到 PATH。Windows 下常见做法是去 ffmpeg 官网下压缩包解压后把bin目录路径加到系统环境变量。装完后在 cmd 里敲ffmpeg -version能输出版本号才算成功。提示如果你在import cv2时报ImportError: DLL load failed九成是opencv-python和 numpy 版本冲突。先pip uninstall opencv-python numpy再pip install opencv-python4.8.1.78 numpy1.24.3这个组合我在多台机器上验证过。2.3 验证环境是否就绪的最小检查脚本装完别急着跑app.py先写个几行的检查脚本确认核心库都能导入import torch import torchvision import cv2 import numpy as np import av from PIL import Image print(torch:, torch.__version__) print(torchvision:, torchvision.__version__) print(cuda available:, torch.cuda.is_available()) print(opencv:, cv2.__version__) print(numpy:, np.__version__)这段代码的作用是逐个导入依赖并打印版本号。重点看cuda available这一行如果是True说明 GPU 可用训练和推理会走显卡如果是False代码会自动回退到 CPU功能不受影响但速度会明显下降。如果某个 import 直接报错就回到上一步单独重装那个库。这一步花两分钟能避免后面跑训练时才发现环境有问题。3. 用自己的数据训练新风格模型train.py 参数逐项拆解3.1 风格迁移的训练逻辑与数据集准备这份源码的训练脚本是train.py它用的是快速风格迁移Fast Neural Style Transfer的思路用一个前馈网络学习从内容图到风格化图的映射训练完成后推理速度很快不像原始 Gatys 方法那样每张图都要迭代优化。训练需要两部分数据内容图数据集和风格图。内容图建议用 COCO 或者你自己收集的图片放在一个目录下风格图就是你想模仿的那幅画比如images/styles/starry_night.jpg。操作说明里给的命令是python train.py --dataset_path data/coco/images/ --style_image images/styles/adriaen-van-ostade_landscape.jpg --epochs 1 --batch_size 4 --image_size 256这条命令里--dataset_path指向内容图目录--style_image指向风格图--epochs是训练轮数--batch_size是批大小--image_size是输入图像尺寸。注意操作说明里写的adriaen-van-ostade_landscape.jpg在images/styles目录下不一定存在你换成实际有的风格图比如starry_night.jpg或cuphead.jpg。3.2 关键参数怎么调epochs、batch_size、image_size 的取舍--epochs 1只是演示能跑通真正要出一个可用的风格模型通常需要几千到几万次迭代。源码里starry_night_28000_vgg16.pth这个文件名暗示了它训练了 28000 次迭代cuphead_10000.pth是 10000 次。所以如果你要自己训一个能看的模型别只跑 1 个 epoch至少准备跑几个小时到十几个小时具体看显卡。--batch_size 4在 8GB 显存的卡上比较稳如果你显存只有 4GB改成 2 或 1显存 12GB 以上可以试 8。--image_size 256是训练时的输入分辨率256 是速度和质量的折中调到 512 会更清晰但显存占用翻倍、速度慢很多。我一般先用 256 跑通流程确认 loss 在下降再考虑加大分辨率。训练过程中你会看到 loss 输出风格迁移的 loss 通常由内容损失和风格损失加权组成。如果内容损失下降但风格损失不降可能是风格权重设得太低反过来风格很浓但内容完全看不清就是风格权重太高。源码里这些权重一般在models.py或neural_style.py里定义你可以搜content_weight和style_weight这两个变量。3.3 训练中断与恢复checkpoints 目录的作用训练脚本一般会定期保存模型到checkpoints目录。如果你训练到一半断电或者想先停下次可以加载上次的权重继续。常见做法是在train.py里加一个--resume参数指向已有的.pth文件或者直接改代码里的加载路径。这份源码里已经有四个训练好的.pth你可以直接拿来做推理也可以作为继续训练的基础。注意.pth文件是 PyTorch 的 state_dict 格式加载时要保证网络结构和保存时一致否则会报 key 不匹配。如果你改了models.py里的网络层旧权重就不能直接用了。4. 图片与视频风格迁移Web 端和脚本两种用法4.1 启动 Flask 应用app.py 的路由与上传逻辑操作说明里写的启动方式是python app.py然后访问http://127.0.0.1:5000。app.py是一个 Flask 应用里面定义了两个主要路由一个处理图片上传和风格迁移一个处理视频上传和风格迁移。启动后你会看到一个网页上面有图片风格迁移和视频风格迁移两个板块。图片板块的操作流程是点击“选择文件”上传本地图片在下拉框里选一个风格模型点“apply style”等页面刷新后就能看到生成的图片。视频板块同理只是上传的是视频文件生成的是风格化后的视频。这里有个细节下拉框里的风格模型对应的是checkpoints目录下的.pth文件。如果你自己训练了新模型把它放进checkpoints目录并在app.py里把模型列表更新一下就能在网页上选到。app.py里通常有一个字典或列表维护模型名称和路径的映射搜checkpoints或.pth就能找到。4.2 不启动 Web 直接用脚本推理test_on_image.py 和 test_on_video.py如果你不想开网页或者想批量处理图片可以直接用test_on_image.py和test_on_video.py。这两个脚本一般接受输入路径、风格模型路径、输出路径三个参数。以图片为例常见用法是python test_on_image.py --content images/content/zurich.jpeg --style_model checkpoints/starry_night_28000_vgg16.pth --output output/zurich_starry.jpg这条命令把zurich.jpeg用梵高星空模型做风格迁移结果保存到output目录。--content是内容图路径--style_model是风格模型权重--output是输出路径。视频脚本类似只是输入输出换成视频文件内部会逐帧处理再合成。视频处理很吃时间一个 10 秒的 30fps 视频有 300 帧每帧都要过一遍网络CPU 上可能要跑十几分钟GPU 上会快很多。4.3 视频风格迁移的帧处理与音轨保留问题视频风格迁移有一个容易被忽略的点音轨。很多逐帧处理的脚本只处理画面合成后的视频没有声音。如果你需要保留原视频的音轨常见做法是用 ffmpeg 先把原视频的音轨提取出来等画面处理完再合并回去ffmpeg -i input.mp4 -vn -acodec copy audio.aac ffmpeg -i stylized_video.mp4 -i audio.aac -c:v copy -c:a aac -shortest output_with_audio.mp4第一行从原视频提取音频流保存为audio.aac第二行把风格化后的视频和音频合并。-vn表示不要视频-acodec copy表示音频直接复制不重编码-shortest表示以较短的流为准结束。这一步不是源码里必须的但如果你要做演示或者交毕设带声音的视频观感会好很多。注意视频推理时如果报av相关的错误先确认av和ffmpeg版本匹配。av是对 ffmpeg 的 Python 绑定ffmpeg 版本太老或太新都可能导致解码失败。我遇到过 ffmpeg 6.x 配旧版 av 报错的情况降级 ffmpeg 到 5.x 就正常了。5. 避坑与常见问题排查从报错到跑通的五条血泪经验5.1 现象运行 app.py 后浏览器打不开 127.0.0.1:5000原因通常是 Flask 没启动成功或者端口被占用。先看 cmd 里有没有Running on http://127.0.0.1:5000这行输出如果没有说明app.py在导入阶段就报错了往上翻看具体的 ImportError 或 SyntaxError。如果有这行输出但浏览器打不开可能是端口被其他程序占了改app.py最后一行app.run(port5001)换个端口。还有一种情况是你在虚拟机或远程服务器上跑127.0.0.1只能本机访问需要改成0.0.0.0并检查防火墙。5.2 现象训练时 loss 变成 nan 或者不下降原因一般是学习率太高或者数据预处理有问题。先检查内容图目录里有没有损坏的图片用PIL打开每张图确认没有报错。然后看学习率如果train.py里默认学习率是 0.001 或更高试着降到 0.0001。还有一种可能是输入图像没有归一化到 [0,1] 或 [-1,1]导致数值爆炸。风格迁移的输入一般会做transforms.ToTensor()和Normalize确认这两步在数据加载里有没有漏掉。5.3 现象生成的图片全黑或者全白这通常是模型权重加载失败或者输出层激活函数不对。先确认.pth文件和当前网络结构匹配如果报Missing key(s)或Unexpected key(s)说明结构对不上。如果权重加载没报错但输出全黑检查输出层有没有加Sigmoid或Tanh把值限制在合理范围以及推理时有没有做反归一化。我遇到过输出全黑是因为推理时忘了把图像从 [-1,1] 转回 [0,255]加一行output (output 1) / 2 * 255就正常了。5.4 现象视频处理到一半报内存不足原因是逐帧处理时把所有帧都读进内存了。一个 1080p 的视频每帧约 6MB1000 帧就是 6GB很容易爆内存。解决办法是改成流式处理读一帧、处理一帧、写一帧不要一次性read()全部帧。av和cv2.VideoCapture都支持逐帧读取用while循环配合cap.read()就行。如果源码里是一次性读入的你可以自己改成流式或者先把视频切成小段分批处理。5.5 现象pip 安装 torch 时下载极慢或超时原因是默认源在国外。换国内镜像源能快很多pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 -i https://pypi.tuna.tsinghua.edu.cn/simple注意 PyTorch 的 CUDA 版本包在清华源里不一定全所以--index-url还是指向 PyTorch 官方-i指向清华源作为补充。如果还是慢可以先只装 CPU 版跑通流程等确认代码没问题再换 GPU 版。CPU 版安装命令把cu118换成cpu即可。6. 进阶技巧用 make_style_new_dataset.py 扩充风格数据集与模型验证源码里有一个make_style_new_dataset.py这个脚本容易被忽略但它其实很有用。它的作用是把一张风格图做数据增强生成一批风格变体用来扩充训练数据或者做模型鲁棒性测试。常见做法是读入一张风格图做随机裁剪、旋转、色彩抖动生成几十张变体保存到新目录。这样你训练时风格损失不会只盯着同一张图模型泛化会好一些。用法一般是python make_style_new_dataset.py --style_image images/styles/starry_night.jpg --output_dir data/styles_aug --num_aug 50--style_image是原始风格图--output_dir是输出目录--num_aug是生成数量。生成完后把--style_image参数改成输出目录训练脚本会从目录里随机采样风格图。注意增强不要太激进旋转角度控制在 ±15 度、色彩抖动幅度小一点否则风格会变得不像原画。另一个进阶用法是模型验证。训练完一个新模型后别只看 loss 曲线拿几张没参与训练的内容图跑一遍肉眼对比风格化效果。我一般会固定三张内容图一张人像、一张风景、一张建筑分别用新模型和已有模型各跑一次放在一起看。如果新模型在人像上把脸糊成一团说明内容损失权重太低如果风格完全没上去说明风格权重太低。这个对比表比任何指标都直观验证维度检查方法合格标准内容保留人像五官是否可辨眼睛、鼻子轮廓清晰风格强度笔触和色彩是否接近风格图一眼能看出风格来源伪影边缘是否有网格或色块无明显规则纹理推理速度单张 256x256 耗时GPU 上低于 0.1 秒最后说一个我自己的习惯每次拿到一份新源码先不急着改代码而是用作者提供的预训练模型跑通推理确认环境没问题再动训练。这样如果后面训练报错你能确定是训练配置的问题而不是环境本身没搭好。从那以后我每次拆新项目都强制走一遍“先推理后训练”的流程省了很多来回排查的时间。希望这份拆解能帮你顺利跑通自己的风格迁移毕设。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进