多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

TensorFlow 2.0+Keras深度学习入门实战:从环境搭建到图像分类

TensorFlow 2.0+Keras深度学习入门实战:从环境搭建到图像分类 1. 为什么我劝你别再纠结“学什么框架”直接上手 TensorFlow 2.0/Keras这两年只要聊到 Python 深度学习入门绕不开的一个话题就是“我到底该学 PyTorch 还是 TensorFlow”尤其是看到不少招聘信息里写着“熟悉 PyTorch 优先”很多新手就懵了总觉得是不是选错了方向。先说结论作为入门TensorFlow 2.0 Keras 依然是目前最稳、最不容易劝退的组合没有之一。理由很直接Keras 在 2.0 之后已经彻底并入 TensorFlow成为它的官方高级 API。你写 Keras 代码本质上就是在写 TensorFlow 代码不存在“学了 Keras 就不会 TensorFlow”的说法。而 Keras 的语法设计是我见过所有深度学习框架里最接近“人类思考方式”的。你想想用 PyTorch 搭一个模型要理解nn.Module、forward()、autograd这一整套机制。而 Keras 只需要model.add()或者model tf.keras.Sequential([...])这样一行一行往里加层。这对一个刚摸到深度学习门槛的 Python 初学者来说心理负担完全是两个级别。这篇文章不是把官方文档搬过来念一遍我尽量从“一个已经踩过坑、跑通项目的人”的角度把环境搭建、模型设计、训练调试、常见报错这条线完整串一遍。你跟着走是能真正跑起来、真正出结果的。目标是让一个会基础 Python 语法的人在半天之内跑通自己的第一个深度学习项目。2. 环境搭建完整实操版本、CUDA、显卡这三样到底怎么配2.1 先把 Python 环境弄干净很多新手一上来就卡在环境安装这一步。我在网上天天能看到类似“python安装教程”“python下载安装教程”这类热搜词说明绝大多数人第一道坎就是装 Python。这里有个忠告千万别去官网下载 Python 之后直接全局安装然后pip install tensorflow。我见过太多人因为全局环境混乱装了一堆库之后互相冲突最后连import tensorflow都报错。正确做法是装虚拟环境。你如果用 Anaconda一条命令就能创建干净环境conda create -n tf2 python3.8 conda activate tf2至于为什么推荐 Python 3.8 而不是最新的版本纯属经验之谈。TensorFlow 对最新 Python 版本的支持总是慢半拍用 3.8 或 3.9 基本不会碰到“装不上”的鬼问题。装完环境之后安装 TensorFlow一条命令搞定pip install tensorflow这里补充一下什么时候该装 CPU 版什么时候该装 GPU 版。如果只是入门跑 MNIST、CIFAR-10 这种小数据集CPU 版完全够用训练时间也就几分钟的事情。但如果你打算后续跑图像分类、目标检测或者 NLP 模型建议先确认自己的显卡是不是 NVIDIA 的。只有 N 卡才支持 CUDA。A 卡用户就别折腾 GPU 了深度学习生态默认只跟 CUDA 走。GPU 版本的安装方式也很固定pip install tensorflow-gpu装完之后怎么确认 GPU 真的被识别了用工具库设备检测函数看输出数量import tensorflow as tf print(Num GPUs Available: , len(tf.config.list_physical_devices(GPU)))如果输出的数字是 1 或者更大说明显卡识别成功。如果是 0那说明 CUDA 环境有问题。这时候别慌请按 3.0 版本的步骤重装 CUDA 工具包。下面是经验之谈不要单独去装最新版 CUDA而是依据 TensorFlow 官方版本对应的 CUDA 版本来装否则会随机报错例如找不到库文件之类的。2.2 安装 Keras 到底是单独装还是随 TensorFlow 一起装这里被问过很多次“keras安装教程”。我直接统一答复在 TensorFlow 2.0 之后Keras 不需要单独安装。它就是tensorflow包的一部分。你只需要写from tensorflow import keras或者import tensorflow as tf from tensorflow.keras import layers, models这就够了。早期版本确实是分开的但从 2.0 开始 Keras 已经成了tf.keras。所以如果你在网上搜到旧教程、需要另装keras这个包来做单独操作的写法自动跳过。很久前有个版本用户手动执行pip install keras之后跟 TensorFlow 自带的 Keras 版本产生冲突导致某些函数重复定义。我劝你别自己给自己找麻烦直接统一用tf.keras就行。2.3 用云端环境跑深度学习的备选方案如果你的电脑配置不行装 CUDA 又装不动或者你是 Mac 用户那你就别折腾本地了。前阵子热搜词里就有个“深度学习云平台”说明很多人已经开始转向云端。就拿 Colab 来说云端环境不需要本地造轮子而且免费送 GPU。在 Colab 上激活 GPU 的方式是菜单栏代码执行程序 - 更改运行时类型 - 硬件加速器 - 选择 T4 GPU。虽然免费额度有使用时间和资源限制但入门学习绰绰有余了。另外有人问“codex跑深度学习”行不行。这种东西本质上就是一个 AI 编程助手它顶多帮你写代码框架该配的环境还得你自己配。我理解大家想的是“能不能让它替我写完整个模型”但是深度学习这件事核心是理解和调参代码只是表达工具。让 AI 帮你生成 Keras 代码省的时间确实多尤其是它的代码生成质量在写Sequential模型时确实很高。不过建议你先自己手敲一遍理解每一层的含义再交给它提速。不然报错了你都不知道怎么改。3. 动手写第一个图像分类模型Keras 实战案例拆解3.1 为什么要用 MNIST 数据集做入门说句实在话MNIST 已经被写烂了但我依然坚持用它入门。理由是数据集足够小。训练集只有 6 万张图片每张是 28x28 像素的灰度图。你不需要大显卡CPU 也能轻松跑完几个 epoch。任务足够标准。手写数字识别10 分类问题准确率高了低了都有大量参考资料方便你判断自己的模型和别人的有什么差距。数据加载方式足够简单。Keras 内置了它一行代码直接下载导入不用自己折腾文件读取。我见过不少新手图新鲜一上来就想去跑 ImageNet、跑 YOLO结果环境配置、数据标注、显存限制这些瓶颈一拥而上心态直接爆炸。所以先跑通 MNIST再谈其他。3.2 建立模型的两种写法都给你展示一下Keras 构建模型最常见的方式有两种。第一种叫Sequential顺序模型适合各层按顺序堆叠的场景这也是入门阶段最推荐的写法import tensorflow as tf from tensorflow.keras import layers, models model models.Sequential([ layers.Flatten(input_shape(28, 28)), layers.Dense(128, activationrelu), layers.Dense(10, activationsoftmax) ])这段代码一共做了三件事Flatten把 28x28 的二维图像拉成一维向量长度为 784。这是全连接网络的固定操作因为Dense层本质上就是矩阵乘法输入必须是二维矩阵。第一个Dense(128, activationrelu)是隐藏层128 表示这一层有 128 个神经元。relu激活函数解决了深度网络的梯度消失问题现在基本上看不太到有人用sigmoid做隐藏层激活。第二个Dense(10, activationsoftmax)是输出层。10 对应 0-9 十个数字的类别softmax把输出转成概率分布所有类别概率之和为 1。第二种写法是函数式 API适合多输入、多输出或者层之间有跳跃连接比如 ResNet 结构的场景inputs tf.keras.Input(shape(28, 28)) x layers.Flatten()(inputs) x layers.Dense(128, activationrelu)(x) outputs layers.Dense(10, activationsoftmax)(x) model models.Model(inputsinputs, outputsoutputs)这两种写法在 MNIST 上的效果完全一样。但你最好把两种都敲一遍尤其是第二种写法你会更直观地理解“数据流”的概念——张量经过每一层都像是流水线上的零件被加工一次。理解了这个后面看别人源码才不会一头雾水。3.3 编译和训练这一步有几个关键参数别搞错模型搭好之后需要调用compile()方法来完成配置。下面这段就是最常见的配置model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy])三个参数分别是什么含义花点时间理清楚optimizeradam是优化器。你可以把它理解成“下山时的下山策略”。adam是目前最常用、几乎不用调参就能表现不错的优化器。它结合了动量法和自适应学习率对新手极其友好。loss是损失函数用于衡量预测值和真实值的差距。这里用sparse_categorical_crossentropy是因为标签是整数比如 7不是 one-hot 编码。如果你的标签是 one-hot 格式就要用categorical_crossentropy。这个细节很多人容易忽略运行时报错才知道错了。metrics是评估指标。这里用的accuracy就是分类准确率在训练过程中实时打印方便你直观观察模型状况。接着训练模型history model.fit(x_train, y_train, epochs5, batch_size32, validation_split0.2)讲讲batch_size和epochs这两个新手最容易懵的参数。epochs表示整个训练集被完整训练多少轮batch_size表示每轮迭代中一次喂给模型多少张图片。每个 epoch 的迭代次数 总样本数 ÷batch_size。MINIST 训练集是 60000 张图用batch_size32那么一个 epoch 就有 1875 次迭代。每迭代一次模型就根据当前批次计算梯度并更新一次权重。validation_split0.2的意思是从训练集里抽 20% 作为验证集不参与训练。每轮结束后模型会在验证集上做一次预测从而观察模型的泛化能力。如果训练准确率一直上涨但验证准确率停滞说明过拟合如果两者都低那大概率是欠拟合或者网络结构不对。4. 模型评估与预测别只盯着训练集要拿测试集检验4.1 评估模型看什么指标准确率是唯一标准吗训练完之后需要评估模型的表现。在训练集上准确率高不算本事因为模型很可能只是记住了训练数据真正要看的是它在从未见过的数据上的表现。所以我们要用测试集来评估。test_loss, test_acc model.evaluate(x_test, y_test, verbose2) print(\nTest accuracy:, test_acc)我见过很多新手只盯着训练集准确率一看 99% 就兴奋得不行结果到测试集上直接被腰斩。这就是典型的过拟合。初学者怎么判断是否过拟合最直观的办法就是比较同一个 epoch 里训练准确率和验证准确率。如果训练准确率在上涨验证准确率反而开始下降并且两者差距越来越大那就是过拟合的信号。MNIST 这个任务比较简单模型容量稍微大一点就容易过拟合。所以入门阶段你反而可以故意把网络加宽加深亲眼看看过拟合是怎么表现出来的。只有亲眼见过过拟合的曲线后面学正则化、Dropout 的时候才能理解它到底在解决什么问题。4.2 用训练好的模型对新图片做推理预测评估完之后用模型去预测新图片这是大家最有成就感的一步。代码如下import numpy as np predictions model.predict(x_test) print(np.argmax(predictions[0]))model.predict()返回的是模型对每张图片在每个类别上的预测概率是一个形状为 (10000, 10) 的数组。np.argmax即是提取概率最大的那个索引也就是最终的数字预测结果。这里有一个新朋友容易忽略的点predictions[0]打印出来是一组十个数它们也是类别的预测概率分布。这意味着模型会结合特征对每个类别给出一个置信度作为对结果可靠程度的量化参考。如果你想把预测结果可视化可以直接用matplotlib打印。比如有人问到“python画图横坐标太密集”怎么处理其实就是在用 matplotlib 做可视化时的常见问题。一行代码就能解决import matplotlib.pyplot as plt plt.xticks(rotation45)rotation参数控制横坐标刻度的旋转角度45 度基本能解决标签拥挤重叠的问题。这个技巧在你后续做训练曲线可视化时同样适用。4.3 保存模型和重新加载训练一次不代表完事训练完的模型要保存下来不然关掉程序就一切归零了。Keras 提供了最简洁的模型持久化接口model.save(mnist_model.h5)重新使用的时候只需要一行代码from tensorflow.keras.models import load_model model load_model(mnist_model.h5)这背后的原理是将模型的结构、权重、优化器状态全部打包到一个文件里是“完整模式保存”而不是“仅权重保存”。加载之后你可以继续训练、可以预测一切都和保存时的状态一致。这里建议新人养成习惯模型文件名的后缀用 .h5 与 .keras 取决于你的 TF 版本但加载方式完全一致报错时注意看提示版本差异。5. 核心概念深度讲解神经网络到底在学什么5.1 神经网络为什么需要非线性激活函数很多人代码跑通了但对内部原理依然是一团浆糊。这里我用一个生活化的类比讲明白神经元的工作方式本质上就是“加权求和 激活函数”。每个神经元接收多个输入每个输入乘以对应的权重再加一个偏置项得到一个加权和。如果只有这种线性变换那神经网络不管叠加多少层本质上都等价于一层。非线性激活函数的作用就是让神经网络具备拟合复杂函数的能力。这就好比做饭线性变换像是只会“原料 盐”加再多层也是同样的重复工序激活函数才让模型真正具备了“能根据口味调料”的能力。relu为什么是最常用的激活函数因为它在正半轴导数恒定为 1求导简单、不会引起梯度消失计算速度比其他激活函数快得多。5.2 反向传播和梯度下降是一种“找路下山”的算法如果正向传播是把图片从输入层一路传到输出层得到预测结果那反向传播则是从输出层开始根据预测值与真实值的误差从后往前逐步调整每一层的权重。梯度下降的过程其实就是在下山。你在山上的位置是当前的模型参数目标是最低点最小损失。梯度就是斜坡的方向和陡峭程度告诉你怎么走下山最快。而learning_rate学习率决定你每一步跨多大。步子太大可能直接跨过最低点导致损失震荡不收敛步子太小又走得太慢半天到不了底。这就是为什么我在入门阶段推荐直接用adam因为它会自动调整学习率。早期用SGD的时候光调学习率就能把你折腾半夜。5.3 过拟合的直观理解和常见解法有一句话值得你记住过拟合就是模型把训练集的噪音当成规律学会了。这就像背书狂魔把习题册的题目答案连错误选项都背下来考试却换了形式和出题思路他整个就懵了。过拟合的常见解决方案总结下来有这样几种增加数据量让模型看到更多样化的样本噪音的权重自然会被稀释。降低模型复杂度减少层数或神经元数量让模型没有能力去记住那些细微噪音。添加正则化比如 L2 正则化它在损失函数中加入对大权重的惩罚逼着模型把权重保持在较小水平。使用 Dropout在训练过程中随机让一部分神经元“失活”迫使模型不依赖某几个特定神经元。理解这些概念不是为了考试是为了你后续调模型时脑子里有方向。否则模型崩了你只能迷茫地调参。6. 实操中的常见报错与排查技巧6.1ImportError: DLL load failed这类环境问题这类报错已经连续遇到很多次了。碰到基本上就是两种情况安装的 TensorFlow 版本与 Python 位数不匹配或者机器缺 Microsoft Visual C Redistributable 运行库。CUDA 相关的 DLL 文件缺失也就是 GPU 版 TensorFlow 找不到对应的 CUDA 库。排查步骤很简单先跑 CPU 版测试。如果 CPU 版正常、换成 GPU 版就报 DLL 错误问题就锁定在 CUDA 环境上。按前面说的方法重新安装跟 TensorFlow 版本匹配的 CUDA 工具包和 cuDNN并确认系统PATH环境变量里包含了 CUDA 的 bin 目录。6.2 训练时损失变成nan怎么办这是一个非常典型的问题。loss: nan频繁出现在训练过程中说明梯度爆炸了。常见的诱因有学习率设置得过大导致梯度更新时权重变化太猛。数据没有做归一化输入特征的数值范围差别过大。自定义损失函数里出现了除以 0 或取值问题的情况。处理方式是把学习率降下来试试例如从 0.001 改成 0.0001检查输入数据是否做了标准化用tf.keras.utils.normalize或直接除以 255 把像素值缩放到 0-1 区间如果用的是relu激活函数输出层前偶尔会出现死亡神经元可以试试换成leaky_relu。6.3 训练慢、CPU 占用高是正在正常计算还是没有优化好有热搜词提到“python上利用rapidocr太吃cpu”这是典型的 CPU 版本推理场景。TensorFlow CPU 版对于大模型确实会占满所有核心这是正常现象。如果觉得慢可以考虑这几个优化方向启用tf.data数据管道做输入预处理不要让数据加载拖累计算。调大batch_size充分利用 CPU/GPU 并行计算能力。如果你是 GPU 训练但在 CPU 上跑可以估算一下显存占用是否偏低从而判断任务是否真的充分利用了并行计算资源。另外要说一下“python连接公司系统实现自动拉表”这个需求这和深度学习关系不大但往往会被混在一起。如果你做的是自动化任务建议把数据拉取和模型训练拆成两个环节数据预处理的 Python 脚本和深度学习脚本分开跑这样逻辑清晰遇到问题也容易排错。7. 从小白到实战Minst 之后还能往哪走跑通 MNIST 之后很多人会陷入一种“我好像会了但又什么都不会”的迷茫状态。其实这很正常MNIST 只是一个台阶重点不是这个数据集本身而是你通过这个过程掌握了完整的工作流。后续值得探索的方向有这么几个图像分类进阶把 CIFAR-10 数据集跑一遍数据从灰度图变成彩色图分类难度上了一个台阶这时候你就要接触卷积神经网络了。卷积神经网络 CNN顺着Conv2D、MaxPooling2D、BatchNormalization这些层去延展理解卷积核是怎么提取特征的以及池化层是如何逐步缩小特征图的。模型调优方向增加 Dropout、BatchNormalization添加数据增强观察这些操作对最终准确率的影响。这里顺便提一下热搜词里的“深度学习parameter应该不是mb吧”这个疑惑。它问的其实是模型参数量单位换算的问题。模型的参数量一般是用 count 统计的比如 5,000,000 参数模型体积才用 MB 来算。这两个概念不要混淆。一个 500 万参数的模型文件大小可能只有 20MB单位完全不同。量化交易也是热门方向之一热搜里有“python量化交易策略代码”。如果你后续想往金融数据方向走深度学习的用处主要在时序预测上。你可以先学会把股票数据整理成时间序列再用 LSTM 或 GRU 这类循环神经网络做预测。但这个方向的坑比图像分类大得多市场数据的信噪比低、波动剧烈要提前有心理准备。8. 再谈一下我自己实操下来的一些体会从零开始跑通一个 Keras 模型真不需要太高深的数学基础。大学里学过导数和矩阵相乘完全够用了。真正让大多数人坚持不下去的是卡在环境配置、未知报错和抽象概念上。这篇文章尽量把能避的坑都指出来了但不可能覆盖到每个角落。毕竟每个人电脑环境、系统版本、显卡型号都不一样你总会遇到一些别人没遇到过的问题。我的建议是不管是搜索引擎还是 AI 工具把报错信息直接复制过去关键词越完整越好。别只贴“报错了”三个字没人能猜出你哪一步错了。把报错原文贴出来、把操作步骤交代清楚基本五分钟之内就能得到解决方案。还有一点要提醒新手“跑通代码”只是起点不是终点。很多人复制别人的代码跑出了不错的结果就觉得自己已经会了。但你随便改一个地方比如换个数据集、换一种网络结构模型可能立刻崩给你看。深度学习的真正学习路径是在大量的“报错-思考-解决”循环里建立的。每一次解决问题你都会对框架和数据流的理解更深一层。这个循环开始得越早越好。
返回列表