ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

TensorFlow 2.0/Keras实战入门:从环境搭建到训练第一个神经网络模型

TensorFlow 2.0/Keras实战入门:从环境搭建到训练第一个神经网络模型 写这篇教程的念头其实是被身边好几个朋友问出来的。他们想学Python深度学习一上来就被“TensorFlow还是PyTorch”的选择题卡住接着又卡在环境安装上最后连门都没摸到就放弃了。这篇文章不折腾框架之争直接聚焦一条已经被验证过无数次的路线Python TensorFlow 2.0/ Keras 实战入门。从环境搭建到训练出第一个模型再到解决常见报错把我在实际项目中踩过的坑、绕过的弯都写出来适合编程基础一般、又想快速跨进深度学习大门的人。我不打算讲太多数学先把流程跑通建立体感之后再回头补理论会轻松得多。1. 整体思路与框架选型很多人入门深度学习时最大的误区是一上来就啃神经网络的理论推导结果被反向传播、梯度消失这些概念劝退。我的建议恰恰相反先把工具用起来让代码跑起来看到一个真实的数据集在你的模型下被正确分类再回头看理论你会有一种“原来如此”的顿悟感。这就是为什么我推荐Keras作为入门第一框架——它把复杂的东西包装得极其简洁你可以在半小时内搭出一个可用的神经网络。1.1 为什么选择TensorFlow 2.0/Keras而不是其他组合选TensorFlow 2.0/Keras是基于几个非常实际的考量。第一Keras在TensorFlow 2.0中已经深度融合了tf.keras就是官方推荐的高级API。你不需要像老版本那样分开安装Keras然后担心版本兼容问题。这一点对于刚入门的人来说省去了巨大的环境维护成本。第二学习资料极其丰富。你会搜到“动手深度学习”、“吴恩达深度学习课后题”这些关键词这些经典资源在讲解时很多示例代码用的就是Keras风格的写法。照着资料敲代码和你的环境对得上就不会因为框架版本差异产生莫名其妙的报错。第三Debug的难度相对更低。Keras的函数式API、Sequential模型把网络结构以非常直观的方式组织起来。运行出错时错误信息往往直接指向你代码里的那一层不像底层框架那样输出一长串无关日志。TensorFlow与PyTorch的流行趋势在2024年虽然有一些变化但对于入门者来说先掌握一个容易上手的工具更重要之后需要再学另一个框架迁移成本也不会太高因为深度学习的核心概念是相通的。1.2 先跑通再理解用面向项目的方式学深度学习我管这套学习方法叫“实战驱动式学习”流程如下找一个公开的小型数据集比如后面会用到的手写数字识别。不提前研究太久直接按本文的代码敲一遍跑通训练和预测。一个一个地改参数改隐藏层数量、改激活函数、改学习率观察训练曲线和准确率的变化。遇到报错先自己读错误信息再按第五章的排查表去解决。最后再回去看反向传播、梯度下降等数学原理。这样的顺序大脑是在“有问题要解决”的状态下吸收知识的。我试过带着堂弟用这个方法入门他只有Python基础语法水平三天后就能独立改出一个识别中文手写字体的模型尽管准确率一般。相比之下如果按照传统的“先学一个月数学再动手”的顺序大部分人会在第二周就放弃。我的建议是把这个项目当作一个完整的实际任务来推进。项目标题是“TensorFlow 2.0/Keras实战”那么你的目标就是交付一个能运行的模型而不是“学完这门课”。这两种心态的差异最终的学习效果会差距巨大。2. 环境搭建与工具准备环境安装是劝退新手的第一道坎。网络上那些所谓“手把手教你安装tensorflow”的教程往往没有说明系统差异和版本匹配问题导致很多人照着做却失败。这一章我把安装过程拆细把我踩过的坑都标出来。2.1 Python版本与虚拟环境准备不管你用什么系统第一原则是不要直接往系统Python里乱装包。你以后会同时做好几个项目每个项目的依赖版本可能互相冲突。分离虚拟环境是唯一的正规做法这不是可选项是必选项。Python版本方面TensorFlow 2.5及之后的版本对Python 3.83.10支持得比较好。我推荐安装Python 3.9兼容性和稳定性最均衡。你可能会搜到“python 3.8”、“python下载”、“python安装教程”这些词注意选择从官网python.org下载对应系统的安装包。安装时务必勾选“Add Python to PATH”这个选项默认是不勾选的很多新手后续在命令行里输入python提示找不到命令就是因为这一步。在命令行执行下面的操作创建一个独立的虚拟环境# 创建名为 tf2 的虚拟环境指定 Python 版本 conda create -n tf2 python3.9 # 激活虚拟环境 conda activate tf2如果你用的是原生的venv命令也差不多python -m venv tf2 # Windows: tf2\Scripts\activate # macOS/Linux: source tf2/bin/activate在这个虚拟环境里你可以随意安装、卸载不同版本的包都不影响系统全局。2.2 TensorFlow安装与版本匹配的细节激活了虚拟环境后安装TensorFlow本体pip install tensorflow2.5.0为什么我特意推荐2.5.0这个版本因为它的生态非常成熟网上各种教程、开源项目的兼容性验证都集中在2.5到2.10这个区间。太新的版本往往有些API变动入门期不建议追新。如果你用pip install tensorflow不加版本号可能会装上2.16甚至更高的大版本到时候照着老教程跑代码可能遇到tf.keras.xxx位置变了或者某些函数被移除的情况无缘无故增加麻烦。安装完成后在Python环境里验证一下import tensorflow as tf print(tf.__version__) print(tf.config.list_physical_devices())2.3 CPU与GPU版本的差异没有NVIDIA显卡怎么办一个很多新手搜不到明确答案的问题TensorFlow到底需不需要GPU我直接说结论如果你只是入门用CPU版完全足够。手写数字识别这种数据集在CPU上训练也就几分钟。你可以在没有GPU的情况下完成本文所有实战内容。如果你打算训练稍大一点的模型比如目标检测、Transformer显卡能快几十倍。热词里有“tensorflow 2.5.0 cuda cudnn nvidia 驱动 driver version”说明很多人卡在GPU环境配置上。如果你有NVIDIA独立显卡确实可以配置GPU加速但这一块坑非常多。网上很多教程只告诉你装CUDA但CUDA版本和TensorFlow版本有严格对应关系。TensorFlow 2.5.0官方对应的CUDA版本是11.2cuDNN是8.1。你的显卡驱动版本需要支持对应的CUDA版本。配置GPU环境的步骤如下在命令行输入nvidia-smi查看顶部显示的Driver Version和CUDA Version。我见过有人的驱动是550.144.03上面显示的CUDA版本是12.4这是驱动支持的最高CUDA版本不是说你只能装12.4是向下兼容的。去NVIDIA官网下载CUDA 11.2 toolkit安装。去NVIDIA开发者网站下载cuDNN 8.1解压后把文件复制到CUDA安装目录的对应目录下。在虚拟环境里验证tf.config.list_physical_devices(GPU)能否看到你的显卡。这个过程非常绕而且经常出错后不提示是驱动还是CUDA的问题。我的建议是如果你的目的就是入门先放弃GPU。用CPU跑通所有代码。等你确实需要训练更大的模型再回头配置GPU到时候你排查问题的能力已经比现在强很多成功率会高得多。别在一开始就给自己设太多路障。我见过太多人折腾了三天GPU环境还没跑通一个模型就放弃了。学习深度学习的重点不是环境是模型本身。3. 第一个实战模型手写数字识别这一章我们直接动手做一个经典的图像分类任务手写数字识别MNIST。这个任务被称为“深度学习界的Hello World”。整个项目只需要几行代码就能跑出超过98%的准确率而且训练时间极短非常适合作为第一个实战项目。3.1 理解数据MNIST数据集长相如何MNIST数据集包含60000张训练图片和10000张测试图片每张图片是28×28像素的灰度图内容是手写的09数字。你可以把它想象成一大堆压缩到28×28的小方块每个方块里是一个数字草书。在Keras里加载这个数据集就一句话from tensorflow.keras.datasets import mnist (x_train, y_train), (x_test, y_test) mnist.load_data()下载的数据是numpy数组格式。x_train的形状是(60000, 28, 28)y_train的形状是(60000,)。每个像素值范围是02550是黑255是白。3.2 数据预处理为什么要除以255原始像素值0255的范围直接喂给神经网络效果不太好。深层网络通过多层加权求和数值范围过大的输入会让梯度计算不稳定难以收敛。通用的做法是归一化把像素值压缩到01之间x_train x_train.astype(float32) / 255.0 x_test x_test.astype(float32) / 255.0同时模型的输入需要一个固定的形状。全连接网络期望输入是一维的而每张图片是28×28的二维矩阵。需要把图片“拉平”成一个784维的向量x_train x_train.reshape(-1, 28*28) x_test x_test.reshape(-1, 28*28)到这里你可能想问为什么不直接用二维形状非要拉平这里的原因其实挺实际Dense全连接层的数学本质是做矩阵乘法它天然接收一维向量作为输入。将来你学到卷积神经网络时再改用二维或三维形状那是另一套网络结构的事。3.3 搭建Sequential模型三层网络的逐层拆解神经网络模型五花八门但入门阶段用Sequential顺序模型最直观一层接着一层像叠积木那样堆起来。下面是完整代码from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense model Sequential([ Dense(128, activationrelu, input_shape(784,)), Dense(64, activationrelu), Dense(10, activationsoftmax) ])逐层解释第一层Dense(128, activationrelu, input_shape(784,))有128个神经元接收784维输入向量使用relu激活函数。这层的作用是提取输入中的基本特征。relu激活函数形式是max(0, x)它计算简单而且能有效缓解深层网络的梯度消失问题。第二层Dense(64, activationrelu)有64个神经元继续提取特征。网络为什么要做多层而不是单层因为单层网络只能解决线性可分的问题神经网络之所以强大靠的是多层非线性变换的组合层数越多能表达的函数越复杂。第三层Dense(10, activationsoftmax)输出10个类别09的概率。softmax会把输出压缩成10个介于0到1的数值而且它们之和恰好等于1相当于一个概率分布。最终取概率最大的那个数字作为预测结果。3.4 编译模型损失函数、优化器、评估指标光搭建模型还不够得告诉模型“如何学习”和“怎么衡量好坏”model.compile( optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy] )optimizeradam优化器决定模型如何根据损失值调整权重。Adam是目前最流行的自适应学习率优化器它结合了动量法和RMSProp的优点几乎不需要手动调学习率就能获得不错效果。对于入门来说无脑用adam是性价比最高的选择。losssparse_categorical_crossentropy损失函数衡量预测概率分布与真实标签之间的差距。为什么用sparse版本因为我们的标签y_train是整数形式比如数字7不是独热编码one-hot形式。只要标签是整数就用sparse版本否则就要先做one-hot再使用categorical版本。metrics[accuracy]评估指标这里用准确率训练过程中输出每一轮的准确率便于直观监控。3.5 训练模型与验证epoch和batch_size的选择逻辑核心训练代码history model.fit( x_train, y_train, batch_size64, epochs20, validation_split0.2 )这里的两个参数需要认真理解batch_size64每轮迭代时把60000张训练图分成若干小批每批64张。为什么不一次性把全部数据喂进去两方面的考虑一是显存/内存装不下所以必须分批二是小批量训练本身也引入了随机性这种随机噪声有时候反而能帮模型跳出局部最优效果有时优于全量梯度下降。选择64这个数值是经验值需要看着训练过程微调。epochs20把全部数据完整跑20遍。每一遍模型在训练集上“看”一遍所有图片并更新一次权重。轮数太少模型欠拟合轮数太多又可能过拟合。20轮只是起点后面会根据验证集表现调整。validation_split0.2从训练数据里抽出20%作为验证集不参与训练只用来检验模型在没见过的数据上的表现。这比只看训练集准确率靠谱得多能提前发觉过拟合倾向。训练过程中你会看到类似这样的输出不同机器耗时不同Epoch 1/20 469/469 [] - 2s 4ms/step - loss: 0.2960 - accuracy: 0.9146 - val_loss: 0.1478 - val_accuracy: 0.9567 Epoch 2/20 469/469 [] - 2s 4ms/step - loss: 0.1241 - accuracy: 0.9632 - val_loss: 0.0982 - val_accuracy: 0.9683 ... Epoch 20/20 469/469 [] - 2s 4ms/step - loss: 0.0325 - accuracy: 0.9909 - val_loss: 0.0892 - val_accuracy: 0.9783注意到没有训练集准确率在持续上升但验证集准确率在最后几个epoch增速放缓甚至波动。这个现象后面会细说现在先记住关注val_accuracy而不要太在意accuracy。3.6 评估与预测让模型跑起来检验成色训练完成后在测试集上做最终评估test_loss, test_acc model.evaluate(x_test, y_test) print(f测试准确率: {test_acc:.4f})正常情况下这个值应该在97%以上。如果低于这个数回头看数据预处理有没有漏掉归一化或者网络结构是否有误。再做一次实际预测并可视化结果import numpy as np predictions model.predict(x_test) # 取第一张测试图的预测结果 predicted_class np.argmax(predictions[0]) print(f预测结果: {predicted_class}) print(f真实标签: {y_test[0]})predict返回的是一个形状为(10000, 10)的概率矩阵。np.argmax获取每行最大值对应的索引这个索引就是预测的数字。到这里你已经完成了第一个完整的深度学习实战项目。整个过程不到50行代码但涵盖了一个标准深度学习项目的完整流程数据加载、预处理、模型构建、训练、评估、预测。4. 深入优化从准确率98%到更强的性能用上面的基础模型测试准确率通常能到97%98%。对于一个入门项目来说已经合格了但如果你想让模型更强需要进一步理解深度学习中更精细的技术点。4.1 过拟合到底是什么以及验证集扮演的角色首先要理解一个核心概念过拟合。这是深度学习中最常出现、也最需要警惕的问题。所谓过拟合就是模型把训练数据“背”下来了而不是真正学会了规律。就像学生不是理解了数学原理而是把整本习题册的答案都记住了。你给他一道全新的题他就抓瞎。回到我们的训练过程。如果你仔细观察输出会发现train accuracy一路升高但val_accuracy在某个epoch之后就不再上升甚至下降。这就是过拟合的典型信号。模型开始记住训练集的特定细节甚至记住了噪声而这些细节对于新的数据没有任何帮助。验证集validation set就是为了及时察觉过拟合而存在的。它不参与训练每一轮epoch结束后模型用它来检验自己的泛化能力。所以训练时你要盯紧val_loss和val_accuracy不要被train accuracy的漂亮曲线骗了。4.2 Dropout与BatchNormalization两个经常成对出现的层对抗过拟合最常用的一招是加入Dropout层。它的原理简单粗暴每次训练迭代时随机让一部分神经元不工作输出置为0。比如Dropout(0.5)就是每轮有50%的神经元被随机丢弃。为什么要这么做想象一个团队如果每次开会总有固定的几个主力发言其他人就会偷懒如果每次随机抽掉一批人所有人都必须随时准备好独立干活整个团队的抗风险能力就提升了。Dropout迫使网络不能过度依赖某一个或某几个神经元从而学习到更鲁棒的特征。另一个常见的层是BatchNormalization批归一化它做的事是在每一层激活之前把这一层的输入数据重新标准化为均值为0、方差为1的分布。它的作用一是加速收敛因为数据分布稳定了二是有轻微的正则化效果。在实践中很多模型用BatchNormalization之后可以将学习率调大训练速度会快不少。改造后的模型结构from tensorflow.keras.layers import Dropout, BatchNormalization model Sequential([ Dense(128, activationrelu, input_shape(784,)), BatchNormalization(), Dropout(0.3), Dense(64, activationrelu), BatchNormalization(), Dropout(0.3), Dense(10, activationsoftmax) ])加入这些层之后很可能出现的情况是训练集准确率上升变慢了不再轻松到99%但验证集准确率反而更平滑、更稳健。这个现象非常重要——你牺牲了一点点训练集表现换来了更强的泛化能力。4.3 回调函数训练过程中的智能止损装置在实际项目中我们不会傻傻地设置20个epoch就结束训练。更合理的做法是设一个大一点的epoch数比如50然后让“智能回调”根据验证集表现决定什么时候停止、什么时候保存最优模型。这就像开车装了自动刹车和导航比较省心。下面三个回调是实战中最常用的from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau callbacks [ EarlyStopping(monitorval_loss, patience5, restore_best_weightsTrue), ModelCheckpoint(best_mnist_model.h5, monitorval_accuracy, save_best_onlyTrue), ReduceLROnPlateau(monitorval_loss, factor0.5, patience3, min_lr1e-6) ] model.fit(x_train, y_train, epochs50, batch_size64, validation_split0.2, callbackscallbacks)分别解释他们的用途EarlyStopping监控val_loss如果连续5个epoch都没有改善就停止训练。restore_best_weightsTrue的意思是停止后自动把模型权重恢复到这个最佳epoch的水平。这解决了你手动判断“什么时候该停”的问题。ModelCheckpoint在每次epoch结束后如果当前val_accuracy是历史最佳就把模型保存到磁盘。最终你会得到一个训练过程中表现最好的模型。就算你后面又不小心做了什么操作也能从这个文件中恢复。ReduceLROnPlateau监控val_loss如果连续3个epoch都没有下降就把学习率减半。这是对付“训练后期loss在某个水平震荡不前”的利器。学习率太大导致参数在最低点附近来回跳动缩小学习率往往能突破瓶颈。在实际项目中这三个回调的组合使用率极高几乎是我所有项目的标配。你后续自己写模型时直接把这套回调拿过去改个文件名就行。4.4 数据增强用小技巧让模型见多识广MNIST数据集是已经相对规范的数据但对于真实世界的很多图像任务来说过拟合的主要原因是数据量太少。数据增强是一种在训练时“无中生有”制造更多样本的技巧。它的思路是在原始图片基础上做随机变换——旋转一点、平移一点、缩放一点、添加噪声——然后把变换后的图片也当作训练数据。这样模型就能看到更多样化的输入泛化能力自然更强。但这里要注意数据增强不适合在MNIST这种已经高度标准化的灰度数据集上随便乱用。如果旋转角度过大9会变成看起来像6模型反而会糊涂。在简单的全连接网络上做数据增强效果提升有限更常见的做法是配合卷积神经网络CNN使用。下面给一个适合MNIST的数据增强配置注意幅度要小如旋转5度、平移10%from tensorflow.keras.preprocessing.image import ImageDataGenerator datagen ImageDataGenerator( rotation_range5, width_shift_range0.1, height_shift_range0.1, zoom_range0.1 ) datagen.fit(x_train.reshape(-1, 28, 28, 1))训练时把数据流换成datagen.flow()即可。不过对入门阶段来说理解有这个技术方向就够了暂时不必着急实现。5. 进阶路线卷积网络、迁移学习与项目实战当全连接网络这套流程跑熟以后下一步就可以涉足真正在工业界广泛应用的卷积神经网络CNN。5.1 为什么图像任务必须学CNN全连接网络处理二维图像的方式是把它拉平这相当于把一张照片上所有的像素当成一个没有空间关系的向量来处理。这种做法的最大问题是完全丢失了邻近像素之间的空间关系。比如一个手写的数字7它的“横”和“竖”在空间上是相邻的这种结构信息一旦拉平就看不出来了。换成生活场景来类比全连接网络像是把一本书撕成一个个单字然后摊在桌上找规律CNN则是按章节、按段落去阅读能看到上下文关系。所以对图像任务来说CNN几乎是必须掌握的。CNN的核心组件有三个卷积层Conv2D用一个小窗口如3×3在图像上滑动提取局部特征。最初几层提取的是边缘、颜色块等低级特征越深层的卷积提取的越是复杂的结构特征。池化层MaxPooling2D对特征图下采样缩小尺寸减少计算量同时增加一定的平移不变性。MaxPooling其实就是在一个小窗口内取最大值扔掉冗余信息。全连接层在卷积特征提取完成后再把高维特征映射到分类结果上。一个经典的CNN结构的代码示例from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten model Sequential([ Conv2D(32, (3, 3), activationrelu, input_shape(28, 28, 1)), MaxPooling2D((2, 2)), Conv2D(64, (3, 3), activationrelu), MaxPooling2D((2, 2)), Flatten(), Dense(128, activationrelu), Dropout(0.3), Dense(10, activationsoftmax) ])注意输入形状变成了(28, 28, 1)最后一个1是通道数灰度图只有一个通道彩色RGB图是3。用CNN在MNIST上准确率轻松能到99%以上。5.2 迁移学习站在巨人肩膀上的实战利器如果你面对的不是MNIST这种玩具数据集而是真实世界中几千张图片的分类任务从零训练网络通常效果不佳而且极容易过拟合。这时候就需要迁移学习。迁移学习的思路是借用别人在ImageNet一个包含1400万张图片的数据库等大规模数据集上训练好的模型权重把前面所有“特征提取层”保留下来只替换最后的“分类层”然后在新数据上微调。这就好比你不需要从零开始学医术才能做手术而是直接跟着有几十年经验的名医学习他的诊断思路你直接拿过来用只需要补充学习你自己要面对的特殊病例。在Keras中加载预训练模型只需一行from tensorflow.keras.applications import VGG16 # 加载VGG16去掉最顶层的分类层 base_model VGG16(weightsimagenet, include_topFalse, input_shape(224, 224, 3)) # 冻结base_model的所有层训练时只更新新加的分类层 base_model.trainable False然后在这个base_model的输出上接上你自己的全局池化层和全连接层编译后在自己的数据集上训练几轮。这样做的好处是你只需要非常少的训练数据且训练时间大幅缩短。工业界常见做法是在公司自己的数据上用迁移学习的方式快速构建一个高精度的分类系统。顺便提一下网上热词里出现的“脑机yolov11全栈实战”其实就是迁移学习思路的具体应用案例——先用别人训练好的目标检测模型YOLO系列再结合自己的业务场景做适配和部署。思路一通原理就万变不离其宗。5.3 从MNIST到一个完整项目pandas、Django与前后端分离当你掌握了模型训练的基本功下一步就是把模型部署成真正能用的产品。这时候你会发现深度学习的“深度学习”只是一小部分周边工程才是大头。热词里出现的“前后端分离项目实战”、“django项目实战新手”、“django web应用开发实战电子书下载”、“python连接cmd”其实都是这个方向。一个真实的AI项目最少包含这样几条线数据线数据采集、清洗、入库。这一步通常要用到pandas做数据预处理配合数据库或数据文件管理样本。模型线离线训练模型定期评估和更新。这部分的产出就是我们已经做好的.h5模型文件。服务线把训练好的模型封装成API接口让其他程序可以调用。Django或Flask都常用来做这件事。前端通过HTTP请求把图片传给后端后端调用模型推理把结果返回给前端。前端线用户上传图片的界面、查看识别结果的界面。这就是“前后端分离项目实战”的那些内容。这里先不展开讲但你要有一个认知把模型跑通是第一步非常重要的第一步但“实战”的完整含义还包括部署。后续你可以沿着“Django REST Framework MNIST模型API”的方向去完成一个图像识别服务的搭建。6. 常见问题与排查技巧实录这一章发一个排错清单都是我实际踩过的坑有些坑我甚至踩了两遍才长记性。遇到问题直接对照查表能少走不少弯路。6.1 环境安装与导入相关的报错ModuleNotFoundError: No module named tensorflow大概率是没激活虚拟环境或者装到了另一个环境里。在命令行执行conda list tensorflow确认是否在当前环境不在就重新安装。ImportError: DLL load failed或Could not find cudart64_110.dll这是Windows上GPU安装没配对。先确定你没有短路径或中文字符串的路径问题。TensorFlow的两个版本CPU/GPU对应的CUDA/cuDNN版本要求很严直接用CPU版或者按2.3节的步骤重新安装显卡驱动、CUDA 11.2和cuDNN 8.1。numpy版本不兼容的报错TensorFlow 2.5.0对numpy版本范围有限制。你在装tensorflow之后再装其他包有时pip会顺手把numpy升级或降级导致TF无法导入。遇到这种情况在虚拟环境里重新执行pip install numpy1.20之类固定版本的安装。6.2 训练过程中的常见问题与排查训练过程常见问题如下表所示现象原因解决方案训练loss下降但val_loss一路上升过拟合加入Dropout或正则化或增加数据量训练loss几乎不变学习率设置不当或数据未归一化尝试调小/调大学习率检查输入数据是否除255准确率极低接近随机猜测标签与模型输出维度不匹配检查最后一层的神经元数是否等于类别数训练时显存不足OOMbatch_size过大或模型太复杂减小batch_size或减少Dense层神经元数量训练在某个epoch后loss卡住不动学习率太小或卡在局部最优用ReduceLROnPlateau自动调度学习率6.3 关于数值稳定性与梯度的几个关键检查训练神经网络的过程中遇到loss出现nan是最让人头疼的情况之一。我来分享一下排查顺序先检查学习率是否过大。学习率过大会导致梯度更新幅度过大参数“飞”出有效区间loss算出nan。快速诊断办法把learning_rate缩小10倍看是否恢复。再检查输入数据中是否有nan或无穷大值。用np.isnan(x_train).any()快速排查。如果数据里有缺失值就需要在数据预处理阶段处理掉。最后检查损失函数和输出层激活函数是否匹配。多分类任务中输出层用softmax对应损失函数用categorical_crossentropy二元分类用sigmoid对应binary_crossentropy。算子配错也可能产生数值不稳定。6.4 提高调试效率的几条建议我只分享我亲身实践过、被吸纳为日常工作流的三条经验第一调试阶段把训练数据裁小。如果完整数据有60000张调试时先只用600张也就是在加载后手动切一块比如x_train_small x_train[:600]把epoch数设大一点。快速验证代码逻辑是否正确能通过了再恢复全量数据训练。这能帮你把调试周期从几分钟缩短到几秒。第二记录每次实验的关键参数和结果。我用一个Excel表记录日期、模型结构、epoch数、学习率、测试准确率、备注。当你想复现一个结果时这张表格的价值无可估量。第三对模型结构和参数足够熟悉之前不要盲目套用别人的超参数。看到某人在某个数据集上用了0.001的学习率拿了高分就认为“0.001就是好的”。学习率和batch_size、优化器类型、网络深度都有关系它们在同一个体系内互相配合。理解它们之间的关系比记住一个“标准值”更重要。7. 我的一点个人体会与下一步建议整套流程跑完之后我的感受是深度学习的入门并不比学一门新的编程语言更难最难的永远是“第一次”的抗拒和犹豫。不要把太多时间花在纠结框架、纠结环境、纠结数学基础上先把第一个模型跑通建立“我能做出来”的正反馈之后才谈得上深入学习。关于资源的补充建议网上那些“动手深度学习”、“吴恩达深度学习课后题”都是很好的资源但我的经验是它们最好的使用时机是在你已经跑通一个模型之后。带着实践中的疑问去听课和零基础去听课吸收效率完全是两个级别。还有人说“深度学习鱼书”也就是那本《深度学习入门基于Python的理论与实现》写得非常好但同样适合作为第二本或者参考资料来读。下一步的建议我给出的路径是先去把CIFAR-10一个更复杂的图像分类数据集用CNN跑通精度目标设为85%以上练手CNN和调参能力再学一下TensorFlow的model.save和tf.keras.models.load_model弄清模型的保存与恢复之后尝试用Django搭一个网页把你的模型封装成一个可以在浏览器里上传图片、返回识别结果的小应用。这三步下来你就完成了从“跑通代码”到“做出产品”的跨越。最后再分享一个亲身经历的小技巧训练模型的时候不要干等着。把epoch数调大然后用callbacks里的EarlyStopping和ModelCheckpoint把“止损”和“存档”都交给程序处理你只管在屏幕另一端正经地看几页理论。等它训练完你手里有了最佳模型脑袋里也有了一点新知识效率特别高。这个习惯我沿用至今对它很信赖。
返回列表