ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Python深度学习实战:TensorFlow与Keras环境搭建及图像分类入门

Python深度学习实战:TensorFlow与Keras环境搭建及图像分类入门 开头就直接进入正题。这篇文章就是给你准备的实战手册——不讲虚理论只讲怎么把Python深度学习这一条线走通。我用的框架是TensorFlow 2.0里面集成的Keras是主力建模工具。先说清楚这篇文章不是让你从零学Python语法也不是让你啃透所有深度学习数学公式而是假设你已经会写基本Python代码想快速入门深度学习和TensorFlow。我会从环境配置开始一路讲到完整的图像分类项目实战最后分享我踩过的坑和排查经验。读完你能跑通第一个模型并且知道下一步该往哪走。1. 开工前先搞定环境Python、虚拟环境和TensorFlow安装1.1 为什么劝你别在全局环境里直接装TensorFlow我刚接触深度学习那会儿图省事直接在系统Python里敲了pip install tensorflow当时是能跑。但后来项目多了问题就来了——这个项目要TensorFlow 2.4那个项目要2.10还有的项目要用PyTorch三个框架的依赖在同一个全局环境里互相打架。我记得最惨的一次为了装一个图像库把NumPy从1.19升级到了1.21结果另一个项目直接崩了一查是TensorFlow底层依赖不兼容。从那天起我就老老实实每个项目开一个虚拟环境。Python的虚拟环境原理其实很简单你可以把它理解成给每个项目单独开一个工具箱。不同项目用自己的工具箱里面装的库版本互不影响。这样你怎么折腾都不会波及别的项目。具体到操作我推荐用Anaconda原因有两条第一它自带的conda命令能直接装科学计算相关的二进制包省去了Windows上编译的噩梦第二创建环境后切换环境只需要一条命令。# 创建名为tf2的虚拟环境指定Python 3.9 conda create -n tf2 python3.9 -y # 激活环境 conda activate tf21.2 Python版本和TensorFlow版本的匹配关系很多人没注意TensorFlow跟Python版本有严格的对应关系装错了直接报错。根据我长期实测以及TensoFlow官方发布记录整理一份对应关系供参考TensorFlow版本推荐Python版本备注2.4 ~ 2.93.7 ~ 3.9老项目常见兼容性处理好2.10 ~ 2.123.8 ~ 3.10目前最稳定的区间2.13以上3.9 ~ 3.11新特性多但部分第三方库跟进慢我自己现在习惯固定用Python 3.9 TensorFlow 2.10这个组合踩坑最少网上资料也最多。你要是从零开始直接照这个来。别追最新版本深度学习的库更新快新版本往往意味着新的不兼容。1.3 TensorFlow安装和第一个验证命令创建好环境后安装TensorFlow很简单就一行命令pip install tensorflow这句装的是CPU版还是GPU版这要看你的操作系统。在Linux上TensorFlow 2.1之后的pip包会自动包含GPU支持有NVIDIA显卡就会自动调用。在Windows上默认pip装的是CPU版本GPU版本需要额外配CUDA和cuDNN。再说个掏心窝的建议入门阶段别碰GPU配置。CUDA和cuDNN的版本匹配问题能把人折磨到怀疑人生而且入门跑小模型CPU完全够用。我在第4章会专门讲GPU配置的坑但那是你跑通流程以后的事。装完验证一下在命令行输入python -c import tensorflow as tf; print(tf.__version__)看到输出2.10.0之类的版本号环境就通了。这一步很重要很多人后面代码写了一大堆结果才发现环境没配好。1.4 VS Code配置Python环境编辑器推荐VS Code免费、插件丰富、对Python支持好。配置步骤就三步安装Python插件微软官方出的那个。CtrlShiftP输入Python: Select Interpreter选中刚刚创建的tf2虚拟环境。在项目根目录新建.vscode/settings.json可以指定默认解释器一劳永逸。有个小技巧VS Code右下角会显示当前解释器路径你看到路径里带envs\tf2就说明环境选对了。很多人代码没问题却一直报ModuleNotFoundError八成就是解释器还指在全局Python上。2. 看懂TensorFlow 2.0和Keras为什么这套组合适合入门2.1 TensorFlow 1.x到2.0的巨变没用过TensorFlow 1.x的人可能不知道2.0以前写代码有多反人类。在1.x时代你得先构建一张静态计算图然后放进Session里去跑。调试起来极其痛苦——你没法在中间打印变量看一眼因为整个图是“画”好了再执行你想看的中间结果根本不存在。我当时学的时候经常为了查一个bug得在代码里写一堆tf.Print那体验跟盲人摸象差不多。TensorFlow 2.0最核心的改变是引入了默认的Eager Execution动态图机制。直白点说代码写到哪就执行到哪一行一行看得见摸得着你随时可以打印中间变量的值。这个改动让TensorFlow从“先用图定义计算再执行”变成了“边定义边执行”调试体验直接对标Python原生的感觉。这也是为什么我强烈建议新手从2.0开始学——不用理解计算图那一套抽象概念写起来跟写普通Python代码一样自然。2.2 Keras到底是啥和TensorFlow什么关系Keras最初是一个独立的高层神经网络API库后来被Google收编整合进了TensorFlow的tf.keras模块。现在你import tensorflow as tf之后直接写tf.keras就是官方推荐的建模方式。Keras的价值在于把模型搭建的代码量压缩到一个极其夸张的程度。你用底层API写一个卷积神经网络可能要上百行代码用Keras只需要十几行。我经常跟朋友开玩笑Keras像是深度学习框架里的“傻瓜相机”按键少、出片快但拍出的照片质量一点都不差。Keras在TensorFlow里提供了三种建模方式API类型适用场景代码风格Sequential顺序模型简单线性堆叠网络清晰入门首选Functional函数式模型多输入、多输出、共享层、残差结构灵活真实项目主力Subclassing子类化模型完全自定义训练逻辑最自由也最复杂入门阶段先把Sequential玩熟它就像拼积木——一层接一层。之后做复杂项目再过渡到Functional它像是搭电路板可以从任意位置分叉、合并。2.3 为什么入门选TensorFlow而不是PyTorch这是个好问题也是社区吵了很多年的话题。我的观点一直很明确入门选TensorFlow/Keras进阶再看PyTorch。原因有三第一Keras的API设计真的为新手考虑过。model.add()、model.compile()、model.fit()这三个方法读起来就是自然语言哪怕你不懂原理也能把模型跑起来。PyTorch更灵活但灵活的代名词就是“需要你自己做更多决定”。第二TensorFlow生态里的配套工具完整。TensorFlow Serving做部署、TensorBoard做可视化、TensorFlow Lite做移动端——从训练到上线是一条龙闭环。你学完一个框架后面部署时不用再换技术栈。第三中文资料海量。搜索一切TensorFlow报错基本都能找到前人踩坑记录。这点实际用起来极其重要。但说句公道话如果你是搞科研或者想做学术论文复现PyTorch确实更方便。这两者不是死对头入门用Keras建立直觉后期工作需要再补PyTorch时间成本完全可控。3. 第一个实战项目CIFAR-10图像分类3.1 项目目标与数据准备纸上谈兵终觉浅我带你做一个非常经典的入门项目CIFAR-10图像分类。这也是跑通深度学习流程的必修课理解了它后面的项目都是同一套逻辑换皮。CIFAR-10数据集包含6万张32x32的彩色图片分为10个类别飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船、卡车。TensorFlow里直接内置了数据集不用去网上下载一行代码的事import tensorflow as tf from tensorflow.keras import datasets, layers, models (train_images, train_labels), (test_images, test_labels) datasets.cifar10.load_data()打印一下数据shape你会看到print(train_images.shape) # (50000, 32, 32, 3) 五万张32x32的三通道彩色图 print(train_labels.shape) # (50000, 1) 标签是整数选择CIFAR-10的原因很现实① 图片尺寸小CPU也能快速迭代② 类别丰富模型能学到真正的图像特征③ 是行业内标准benchmark网上相关经验多报错了能查到答案。3.2 数据预处理归一化不能省正式建模前通常要做一步归一化把像素值从0~255压缩到0~1之间。train_images, test_images train_images / 255.0, test_images / 255.0为什么必须做这一步因为神经网络对输入数据的尺度非常敏感。你想啊像素值范围0~255如果网络某层的权重初始值在0附近输入直接乘以255梯度很可能爆炸或消失。类比到生活里你给一个人布置任务单位是“元”还是“万元”他对“100”这个数字的感知是完全不同的。归一化就是把所有数据都放到同一个“感知尺度”上让模型更容易学习。这里还有一个细节CIFAR-10的标签是整数不是one-hot编码。后面选损失函数时必须用SparseCategoricalCrossentropy如果用了CategoricalCrossentropy就会报维度不匹配的错。这个问题我见过太多人踩了。3.3 用Keras搭建卷积神经网络CNN这是项目的核心模块。我用Keras Sequential API搭建了一个经典的卷积网络结构model models.Sequential([ # 第一层卷积32个3x3卷积核提取图像局部特征 layers.Conv2D(32, (3, 3), activationrelu, input_shape(32, 32, 3)), # 池化层压缩特征图尺寸减少计算量防止过拟合 layers.MaxPooling2D((2, 2)), # 第二层卷积64个卷积核学习更高级的特征 layers.Conv2D(64, (3, 3), activationrelu), layers.MaxPooling2D((2, 2)), # 第三层卷积继续加深特征提取 layers.Conv2D(64, (3, 3), activationrelu), # 把二维特征图拉平接全连接层 layers.Flatten(), # 全连接层做特征整合 layers.Dense(64, activationrelu), # 输出层10个神经元对应10个类别不带softmax layers.Dense(10) ])用生活化类比解释这些层Conv2D卷积层像人眼聚焦看图先识别边缘、纹理等小局部特征。32和64是“眼睛”的数量越多看得越细但计算量也越大。MaxPooling2D池化层像图片压缩软件把2x2的区域取最大值尺寸缩小一半。既减少计算量又保留主要特征还能防止模型对位置过度敏感。Flatten展平层把多维特征图拉成一维向量因为后面的全连接层只接受一维输入。Dense全连接层把前面提取的特征进行综合打分每个神经元学到一个类别的“投票权”。input_shape(32, 32, 3)只在第一层指定后面层会自动推导输入维度。激活函数选了relu它是目前图像识别领域最常用的激活函数计算简单、能有效缓解梯度消失。输出层故意不激活因为后面损失函数里带了from_logitsTrue参数它会在内部自行处理softmax这个写法数值稳定性更好。3.4 编译模型优化器、损失函数、评估指标模型结构定义好了还要“编译”才能训练。编译是配置学习过程的三个关键参数model.compile(optimizeradam, losstf.keras.losses.SparseCategoricalCrossentropy(from_logitsTrue), metrics[accuracy])optimizer优化器adam是目前最流行的自适应学习率优化器。简单说它负责回答“怎么调整权重让损失变小”。选adam的原因在于它几乎不需要调参默认学习率就能在大多数问题上表现良好对新手极其友好。loss损失函数评估模型预测和真实标签的差距是模型优化的目标。因为我们的标签是整数索引不是one-hot向量所以选SparseCategoricalCrossentropy。metrics评估指标在训练过程中我们观察什么指标。分类任务一般看accuracy就是准确率。我一直强调初学者不用纠结优化器的数学原理先把adam当成默认选项跑通流程后有兴趣再去深入研究。就像开车新手先学会踩油门刹车发动机原理可以以后慢慢学。3.5 训练模型fit函数和回调机制编译完成后一行代码就能启动训练history model.fit(train_images, train_labels, epochs15, batch_size64, validation_data(test_images, test_labels))参数解释epochs15模型要把整个训练集看15遍。每看完一遍权重更新一次理论上看得越多学得越好但太多会过拟合。batch_size64每次取64张图片计算一次梯度。如果电脑内存不够调小这个值可以缓解内存压力比如32或16。validation_data每训练完一个epoch在测试集上验证一次。通过验证集准确率判断模型是“真学会了”还是“把训练集背下来了”。我在实际训练时通常会加两个回调函数来控制过程from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint callbacks [ EarlyStopping(monitorval_loss, patience3, restore_best_weightsTrue), ModelCheckpoint(best_model.h5, monitorval_loss, save_best_onlyTrue) ] history model.fit(train_images, train_labels, epochs15, batch_size64, validation_data(test_images, test_labels), callbackscallbacks)EarlyStopping的作用是当验证集损失连续3个epoch不再下降就自动停止训练防止过拟合也节省时间。ModelCheckpoint会在每轮结束后保存验证集表现最好的模型权重这样即使后面训练跑偏了我们还能回滚到最优版本。训练开始后你会看到类似这样的输出Epoch 1/15 782/782 [] - 8s 10ms/step - loss: 1.4103 - accuracy: 0.4856 - val_loss: 1.2632 - val_accuracy: 0.5427前几个epoch准确率上升很快这是正常的。随着训练进行你会看到训练准确率和验证准确率的差距逐渐拉大——如果差距过大说明开始过拟合了这时候就该用EarlyStopping的耐心参数来控制。训练结束后用测试集评估一下最终效果test_loss, test_acc model.evaluate(test_images, test_labels, verbose2) print(test_acc)在CPU上训练15个epoch大概需要几分钟到十几分钟第一次跑通看到80%以上的准确率恭喜你深度学习第一只脚已经踏进去了。顺便说一句能用自己写的代码在图像分类上达到这个水平说明你已经掌握了数据加载、模型搭建、训练评估这套核心闭环。3.6 模型保存与加载不能只活在内存里训练出来的模型如果只在当前会话里能用那价值大打折扣。保存和加载模型是项目落地的最后一环两种常见方式# 方式一保存整个模型包括结构和权重 model.save(my_cifar10_model) # 方式二只保存权重需要配合代码重新构建模型结构 model.save_weights(my_cifar10_weights.h5)加载整个模型from tensorflow.keras.models import load_model restored_model load_model(my_cifar10_model) predictions restored_model.predict(test_images[:10])完整的模型文件除了权重还包含结构定义、编译配置和优化器状态。注意整个模型保存是TensorFlow 2.x推荐的默认方式只保存权重适合你想改模型结构再加载旧权重的场景。model.save保存出来的是一个文件夹里面包含assets、variables和saved_model.pb等文件。这种格式叫SavedModel是TensorFlow官方推荐的模型交换格式后续部署到服务端或移动端都用它。4. 常见问题与排查技巧实录4.1 环境配置与安装类问题问题描述大概率原因解决方案ImportError: DLL load failedPython版本不兼容或依赖库冲突重建虚拟环境严格按版本表安装ModuleNotFoundError: No module named tensorflow安装到了别的环境检查which python确认当前解释器pip安装速度极慢默认下载源在国外使用国内镜像源pip install -i https://pypi.tuna.tsinghua.edu.cn/simple tensorflow安装TensorFlow后NumPy版本冲突TensorFlow对NumPy有版本范围要求在虚拟环境里执行pip install numpy1.23.5Pip明明是装了TensorFlow但import报错这种问题我在带新人时见得太多了。十次有八次是环境没对——你以为是tf2环境里装的实际pip指向的是全局Python。排查方法很简单在终端里先执行conda activate tf2再输入which python确认路径是在~/anaconda3/envs/tf2/bin/python。一切检查完再装包能省去一半的玄学问题。4.2 训练过程中的经典报错问题1Loss变成了NaN训练刚开始还正常跑着跑着loss变成NaN准确率跟着变没。这种情况大概率是学习率太大导致梯度爆炸。解决思路# 用更小的学习率重新编译 model.compile(optimizertf.keras.optimizers.Adam(learning_rate0.0001), losstf.keras.losses.SparseCategoricalCrossentropy(from_logitsTrue), metrics[accuracy])还有可能是数据问题如果输入数据里有NaN值也会传导到loss。检查一下数据预处理环节有没有除以0或未处理的缺失值。问题2训练集准确率98%测试集只有75%这是典型的过拟合。模型把训练集“背”下来了没学会泛化。我的处理手段按优先级排序加Dropout层随机丢弃部分神经元逼迫模型不依赖特定路径。早停EarlyStopping在第3.5节已经演示过。数据增强比如随机翻转、裁剪图片增加训练样本多样性。数据增强是图像任务里对抗过拟合的神器from tensorflow.keras.preprocessing.image import ImageDataGenerator datagen ImageDataGenerator( rotation_range15, width_shift_range0.1, height_shift_range0.1, horizontal_flipTrue ) datagen.fit(train_images) model.fit(datagen.flow(train_images, train_labels, batch_size64), epochs15, validation_data(test_images, test_labels))问题3训练速度慢且CPU占用低如果你用的是CPU训练发现CPU占用率不到50%甚至10%大概率是数据加载成了瓶颈——模型在等数据GPU或CPU在摸鱼。解决方案是使用tf.data管道并启用预取train_ds tf.data.Dataset.from_tensor_slices((train_images, train_labels)) train_ds train_ds.shuffle(1000).batch(64).prefetch(tf.data.AUTOTUNE)prefetch会把数据提前加载到内存里让计算和数据加载流水线并行工作。加了这一句训练速度能提升很多。问题4GPU安装了但是TensorFlow用不上这个坑我当年跳得最深。nvidia-smi能看到显卡tf.config.list_physical_devices(GPU)却是空列表。原因基本就是CUDA和cuDNN版本跟TensorFlow的构建要求不匹配。TensorFlow 2.10对应的CUDA版本是11.8cuDNN是8.6。装的时候按官方那套来顺序是先装NVIDIA驱动再装CUDA Toolkit最后放cuDNN文件。注意核对CUDA启动环境变量。再说一次我的建议入门别配这玩意等模型规模真的需要GPU加速了再按官方文档从上到下过一遍成功率会高很多。4.3 一个隐藏的“杀手”Keras版本和TensorFlow版本不匹配有些老教程还在教你from keras import ...如果你装了TensorFlow之后还单独装过keras包很可能代码走的是独立Keras而不是TensorFlow内置的Keras。这两个库的API存在版本差异轻则警告重则模型跑不起来。判断方法import keras print(keras.__version__)如果你用的是TensorFlow集成的Keras应该这样做from tensorflow import keras print(keras.__version__)从第一行代码就养成from tensorflow.keras import ...的习惯能避免一大类问题。5. 学完这个项目后往哪走5.1 把项目换汤不换药地扩展CIFAR-10图像分类跑通后你已经掌握了深度学习的标准流程。接下来从这个项目出发可以做的扩展非常多。搜热词里看到的几个方向其实都是同一套流程的变体基于深度学习的口腔疾病图像识别系统本质是医学图像分类把CIFAR-10里的猫狗换成各种口腔病变成像一般会加更严格的数据增强处理类别不均衡问题。难点在数据标注和质量模型结构跟我们的CNN一致主流会换ResNet这类更深的骨架网络。CNN识别恶意软件把恶意软件的二进制数据转换成图像再用CNN判断是良性还是恶意。小区分在输入处理阶段但核心思路仍然是“图像分类”。利用Transformer进行回归的案例图像分类学的是模型输出类别回归任务是模型输出连续数值。比如用时间序列预测股价、销量。Transformer结构跟CNN完全不同但如果理解了Keras的建模流程你会发现在compile时把损失函数换成MSE就好网络结构单独再学。我从这些热词里挑选过研究选题发现最有价值的不是搜到教程而是意识到搜索引擎里高热度的问题往往都是大众卡壳最严重的地方把这些痛点解决了你在这个领域的技术敏感度就上来了。5.2 接下来按什么顺序学我给新手建议的学习路径是这样的巩固数据预处理和tf.data管道真实项目的数据是脏的对这部分能节省大量时间。学Functional API做残差网络、多模态输入输出时要频繁用它。掌握TensorBoard可视化用浏览器看训练曲线理解模型训练过程。尝试迁移学习用预训练的ResNet50、MobileNet直接在自定义数据集上微调。这是目前工业界最常用也最有效的方法。深入一个方向文本处理选Transformer图像分割选U-Net时间序列选LSTM或Transformer。我说得直白一点入门之后区分普通人和高手的分水岭一个是能不能处理好自己的数据另一个是会不会用迁移学习快速解决问题。5.3 资源推荐现在资料多得泛滥反而不知道该看哪些。我推荐的标准是“少而精配代码”《动手学深度学习》李沐等人免费在线阅读有PyTorch和TensorFlow两个版本代码理论代码结合做得很好。TensorFlow官网教程入门教程质量很高而且会随着版本更新持续维护。Keras官方示例库结构清晰覆盖从图像到文本几乎所有任务。直接把代码拿下来改一改就是你的项目。那些所谓的“深度学习课本pdf”我劝你别花时间去搜了。教材的重点是理论推导你现阶段最需要的是“跑起来的感觉”是那种“我终于把模型训练成功”的正反馈。等代码跑顺了再回头补理论理解会深刻得多。照例说点实际体会。每次带人入门我都有一种感觉让新手放弃的往往不是算法难度而是环境的挫败感和“不知道怎么回事就跑通了”的虚无感。这篇文章从环境一步步走到实战就是想帮你把这两座大山都搬走。你照着敲一遍遇到报错别慌先看错误信息里有没有ModuleNotFoundError、ValueError这些关键词再对照第4章的表格查。跑通模型的那一刻你会发现深度学习没那么玄乎——它就是你用Python按照一套固定的流程让机器从数据里找出规律而已。这套流程跑熟了后面所有模型对你来说都只是一个新结构、新数据的组合游戏。
返回列表