从零开始玩转TensorFlow:小明的机器学习故事 5

图像识别的挑战

1 故事引入:小明的“图像识别”大赛

小明从学校里听说了一个有趣的比赛:“美食图像识别”。参赛者需要训练计算机,看一张食物照片(例如披萨、苹果、汉堡等),就能猜出这是什么食物。听起来非常酷,但是怎么让计算机“看懂”图片呢?

小明想:
“传统的神经网络(全连接网络)之前用来做数字分类效果还行,但这些美食图像不但颜色复杂,而且分辨率更高,直接用全连接网络可能会效果一般。听说有个东西叫卷积神经网络(CNN),特别适合图像识别。我就来好好研究一下吧!”


2 为什么CNN更擅长看图?

2.1 普通神经网络:所有像素一锅端

在最简单的全连接网络里,每个神经元都要处理图像里所有像素的信息。想象下:

  • 你有一大张图,每个位置都有信息。
  • “侦探们”都拥挤在一起,每个人想“盯”整个图像。
  • 数据一多就会非常混乱,大家根本不好分工,效率也低。
2.2 卷积神经网络:给侦探们分配“放大镜”

CNN 里有一层又一层的小“滤镜”(卷积核),它们就像给侦探们每人发了一个“放大镜”,让他们专注查看图像上的某一块区域,从而提取“边缘”“角”“颜色块”等重要特征。

  • 卷积层(Convolution Layer):这个层就负责把一张图分成小块挨个扫描,发现局部特征。
  • 池化层(Pooling Layer):把提取到的“局部发现”做简化,让整体数据量更小;同时,对位置的小幅变化也更有耐心。
  • 全连接层(Dense Layer):将各个层提取到的特征进行综合决策,最终输出“这是苹果呢?还是披萨?还是汉堡?”。

正因为这样分工协作,CNN 在图像识别任务上往往能大显身手。


3 小明的热身实验:CIFAR-10

比赛数据通常比较大,小明想先试试 CNN 的“套路”。他找来 CIFAR-10 这个小数据集做热身。CIFAR-10 共有 10 个类别(如飞机、汽车、鸟、猫、船等),每张图都是彩色的,但只有 32×32 像素,大小和图像内容都比较简单,正好适合入门。

3.1 准备数据与环境
import tensorflow as tf
from tensorflow import keras# 下载并加载CIFAR-10数据集
(x_train, y_train), (x_test, y_test) = keras.datasets.cifar10.load_data()# 缩放像素值到[0,1]区间
x_train = x_train.astype('float32') / 255.0
x_test = x_test.astype('float32') / 255.0num_classes = 10  # 一共10个类别
  1. x_train, y_train:训练数据,包含图像及其对应标签。
  2. x_test, y_test:测试数据,用来在训练结束后考核模型。
  3. 归一化:像素值从 0~255 变成 0~1,加快模型收敛。

3.2 CNN 模型结构:小明的“放大镜团队”
model = keras.Sequential([# 第一组:卷积 + 池化keras.layers.Conv2D(32, (3,3), activation='relu', padding='same',input_shape=(32, 32, 3)),keras.layers.MaxPooling2D((2,2)),# 第二组:卷积 + 池化keras.layers.Conv2D(64, (3,3), activation='relu', padding='same'),keras.layers.MaxPooling2D((2,2)),# 将特征图展开,再接全连接层keras.layers.Flatten(),keras.layers.Dense(128, activation='relu'),keras.layers.Dense(num_classes, activation='softmax')
])model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy']
)
model.summary()
  1. Conv2D(32, 3×3):32 个滤镜,每个滤镜关注 3×3 区域;padding='same' 表示卷积后图大小不变。
  2. MaxPooling2D(2×2):对特征图做 2×2 的“精华提取”。
  3. Flatten:把卷积/池化后得到的多维特征图拉平成一维数组。
  4. Dense(128):中间的全连接层,用于更深层次的特征整合。
  5. Dense(num_classes):输出 10 个类别(CIFAR-10 就是 0~9 这 10 类)。

3.3 模型训练:让侦探团队学会识图
history = model.fit(x_train, y_train,epochs=10,batch_size=64,validation_split=0.2
)
  • 训练过程:喂给网络很多训练图片,网络会先猜测是哪一类,然后根据“猜的结果”和“真实标签”之间的差距来更新参数。
  • epochs:训练轮数;batch_size:一次要处理多少张图片。
  • validation_split=0.2:从训练集中划出 20% 的数据做验证,便于实时观察模型的泛化能力。

3.4 训练成果可视化:准确率与损失曲线

在实际操作中,我们通常还会绘制训练和验证的准确率(accuracy)和损失值(loss),看看模型是否正在稳步提高。

  • 如果验证准确率突然下降,说明可能出现 过拟合
  • 如果训练准确率和验证准确率都一起上升,恭喜你,模型健康成长。

以下是一段常见的可视化示例代码,演示如何使用 matplotlib 绘制训练过程中 准确率(accuracy)损失值(loss) 的变化曲线。

import matplotlib.pyplot as plt# 从 history 对象中获取训练过程中的准确率和损失值
acc = history.history['accuracy']              # 训练准确率
val_acc = history.history['val_accuracy']      # 验证准确率
loss = history.history['loss']                 # 训练损失
val_loss = history.history['val_loss']         # 验证损失epochs_range = range(len(acc))  # 横坐标:训练的轮数plt.figure(figsize=(12, 5))# 1. 绘制准确率曲线
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.title('Accuracy Over Epochs')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend(loc='lower right')# 2. 绘制损失值曲线
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.title('Loss Over Epochs')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend(loc='upper right')plt.show()

代码解释

  1. 获取准确率和损失值

    • history.history['accuracy']:训练集上的准确率随 epoch 的变化。
    • history.history['val_accuracy']:验证集上的准确率随 epoch 的变化。
    • history.history['loss']history.history['val_loss']:分别是训练集和验证集的损失值。
  2. 绘制图像

    • plt.subplot(1, 2, 1)plt.subplot(1, 2, 2) 用于将图像一分为二,分别在左、右两边绘制准确率和损失值曲线。
    • plt.plot(epochs_range, ...):将不同 epoch 的值连成线,观察趋势。
    • plt.title()plt.xlabel()plt.ylabel():添加标题和坐标轴标签,便于阅读。
    • plt.legend():显示图例,区分训练曲线和验证曲线。

运行该段代码后,你会看到两个并排的折线图:左边是 准确率 随训练轮数的变化,右边是 损失值 随训练轮数的变化。通过它们,你可以直观判断模型是否持续学习收敛,或是否出现 过拟合(若验证准确率下降或验证损失上升,而训练集表现持续改善,往往说明过拟合)。

示例输出:
在这里插入图片描述

4 最终的“毕业考”:测试集 & 图片可视化

小明已经把 CNN 训练好了,现在是让模型“毕业考”的时候,也就是在测试集 (x_test, y_test) 上检验它的表现。

test_loss, test_acc = model.evaluate(x_test, y_test, verbose=2)
print("Test accuracy:", test_acc)

示例输出:

Test accuracy: 0.7005000114440918

成功得到一个满意的准确率后,小明心中一阵窃喜:
“看来这‘放大镜团队’果然名不虚传!”

4.1 随机挑几张测试图,看看模型预测得如何
import random
import numpy as np
import matplotlib.pyplot as pltindices = random.sample(range(len(x_test)), 5)
for i in indices:img = x_test[i]label = y_test[i][0]pred = model.predict(img[np.newaxis, ...])pred_label = np.argmax(pred, axis=1)[0]plt.imshow(img)plt.title(f"Real: {label}, Pred: {pred_label}")plt.show()
  • random.sample(...):随机挑几个测试样本进行展示。
  • plt.imshow(img):显示这张 32×32 像素的图像。
  • Real: {label}:数据集中给出的真实标签。
  • Pred: {pred_label}:模型预测的标签。

当图像分辨率低时,我们人眼看起来可能会觉得比较模糊。但只要模型学到了“像素间的相关性”,就能“看”得出哪张更像猫、哪张更像船。

示例输出:
在这里插入图片描述
在这里插入图片描述


5 解读示例:当模型识别到一艘船

下图是一个示例输出(当你运行上面代码时,可能得到不同的随机图)。假设标题写着:

Real: 8, Pred: 8

并且画面看上去有一点类似“海面上白色物体”的模糊画面。

  • CIFAR-10 标签 8 通常代表“船”(ship)
  • 虽然图像分辨率低,但海洋深蓝和船体白色的对比能给网络提供重要线索。
  • 模型预测也给出了“8”,说明它成功认定这是“船”。
  • 如果你在比赛里,这是一个 “预测正确” 的案例。

如果实际图像是“狗”,然而模型给了“猫”之类的预测,就可以通过观察图像特征、数据增强或调整网络结构来做进一步优化。这样的人机对照可以帮你快速找到模型的盲点。


6 故事总结:小明的收获

  1. 卷积神经网络为什么行?
    • 通过“局部扫描 + 池化精简”,CNN 能更好地从图像中提取关键特征,且参数量更少,不容易过拟合。
  2. CIFAR-10先热身
    • 小明在 CIFAR-10 上先试手,发现 CNN 能得到不错的效果,足以说明原理可行。
  3. 看结果很重要
    • 训练曲线可以帮助判断模型是否过拟合或仍在上升空间。
    • 最终在测试集上打印几张预测结果,能让人更直观地看到“模型脑子里想的”和“真实情况”一致性如何。
  4. 阶段性成就感
    • 完整走完这套流程,小明对 CNN 有了更深理解,也为他在 “美食图像识别” 大赛上取得好成绩打下坚实基础。

最终寄语

通过这一章节,我们以 小明的故事 为主线,先介绍为什么卷积神经网络(CNN)更适合图像,再到如何用一个小练习数据集(CIFAR-10)搭建模型、训练、测试,并可视化预测结果。

  • 逻辑链路:问题(美食识别)→ 为什么CNN → 如何CNN → 小实验→ 看结果→ 结果分析
  • 核心方法:理解卷积、池化、全连接的作用,知道如何用代码实现并调试。
  • 图像可视化:从中可以直观看到模型预测是否正确,尤其是像CIFAR-10这种低分辨率图像,对人眼来说模糊,但模型却能学到对应特征。如果出现“预测错”,就能帮助我们快速找到改进思路。

现在,小明和你都算踏进了 “计算机视觉” 这个广阔的领域,下一步可以在更大、更真实的数据上继续折腾!别忘了多实践、多观察,最后说不定你也会在比赛中取得令人惊喜的成绩。加油!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/23884.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

01 冲突域和广播域的划分

目录 1、冲突域和广播域的划分 1.1、冲突域 1.2、广播域 1.3、对比总结 1.4、冲突域与广播域个数计算例题 2、交换机和路由器的结构 2.1、交换机的结构 2.2、路由器的结构 1、冲突域和广播域的划分 1.1、冲突域 冲突域是指网络中可能发生数据帧冲突的物理范围。当多…

[C++]使用纯opencv部署yolov12目标检测onnx模型

yolov12官方框架:sunsmarterjie/yolov12 【算法介绍】 在C中使用纯OpenCV部署YOLOv12进行目标检测是一项具有挑战性的任务,因为YOLOv12通常是用PyTorch等深度学习框架实现的,而OpenCV本身并不直接支持加载和运行PyTorch模型。然而&#xff…

神经网络八股(3)

1.什么是梯度消失和梯度爆炸 梯度消失是指梯度在反向传播的过程中逐渐变小,最终趋近于零,这会导致靠前层的神经网络层权重参数更新缓慢,甚至不更新,学习不到有用的特征。 梯度爆炸是指梯度在方向传播过程中逐渐变大,…

zyNo.26

[GXYCTF2019]Ping Ping Ping(Web) 传/?ip1有ping回显,说明后端可能通过php参数接受了ip参数,并且拼接到了最终执行的命令里形成了ping -c 3$ip,这样可能存在一个命令注入漏洞 要判断是否符合 ping -c 3$ip …

轻量级SDK,大能量:EasyRTC重塑嵌入式设备音视频体验

在智能硬件与物联网迅猛发展的今天,嵌入式设备的音视频通讯能力正变得愈加关键。然而,受限于硬件资源,尤其是Flash存储空间的不足,传统的音视频通讯方案往往难以在嵌入式设备上实现高效集成。EasyRTC凭借其轻量级SDK和先进的技术架…

算法日常刷题笔记(2)

为保持刷题的习惯 计划一天刷3-5题 然后一周总计汇总一下 这是第二篇笔记 笔记时间为2月17日到2月23日 第一天 找到初始输入字符串 找到初始输入字符串 Ihttps://leetcode.cn/problems/find-the-original-typed-string-i/ Alice 正在她的电脑上输入一个字符串。但是她打字技…

[实现Rpc] 客户端 | Requestor | RpcCaller的设计实现

目录 Requestor类的实现 框架 完善 onResponse处理回复 完整代码 RpcCaller类的实现 1. 同步调用 call 2. 异步调用 call 3. 回调调用 call Requestor类的实现 (1)主要功能: 客户端发送请求的功能,进行请求描述对服务器…

WPS计算机二级•文档的页面设置与打印

听说这是目录哦 纸张大小页边距和装订线❤️‍🔥打印界面讲解❤️缩印💕打印作文稿纸💞将文档打印成书籍💓限制编辑设置💗给文字文档加密💖文档导出为 PDF格式💘协作编辑模式💝能量站…

hackmyvm-buster

题目地址 信息收集 主机发现 ┌──(root㉿kali)-[/home/kali] └─# arp-scan -I eth1 192.168.56.0/24 Interface: eth1, type: EN10MB, MAC: 00:0c:29:34:da:f5, IPv4: 192.168.56.103 WARNING: Cannot open MAC/Vendor file ieee-oui.txt: Permission denied WARNING: C…

【入门音视频】音视频基础知识

🌈前言🌈 这个系列在我学习过程中,对音视频知识归纳总结的笔记。因为音视频相关讲解非常稀少,所以我希望通过这个音视频系列,跟大家一起学习音视频,希望减少初学者在学习上的压力。同时希望也欢迎指出文章的…

将Ubuntu操作系统的安装源设置为阿里云

在使用Ubuntu操作系统时,默认的软件源通常是国外的仓库,这可能会导致软件安装和更新速度较慢。为了提高下载速度和稳定性,我们可以将Ubuntu的安装源设置为阿里云镜像源。以下是详细步骤: 一、准备工作 在开始之前,请确保您的Ubuntu系统可以正常上网,并且您拥有管理员权…

基于 Python 的项目管理系统开发

基于 Python 的项目管理系统开发 一、引言 在当今快节奏的工作环境中,有效的项目管理对于项目的成功至关重要。借助信息技术手段开发项目管理系统,能够显著提升项目管理的效率和质量。Python 作为一种功能强大、易于学习且具有丰富库支持的编程语言&…

LabVIEW C编译支持工具库CCompileSupp.llb

路径:C:\Program Files (x86)\National Instruments\LabVIEW 2019\vi.lib\Platform\CCompileSupp.llb ​ 1. 工具库概述 定位:LabVIEW内置的C语言编译支持工具库,用于处理LabVIEW与C/C代码的混合编程接口,涵盖编译器配置、代码生成…

JVM之JVM的组成

Java 虚拟机(JVM)是 Java 程序的运行核心,它主要由类加载系统、运行时数据区、执行引擎和本地方法接口这几个关键部分组成。 类加载系统(Class Loading System) 类加载系统负责在程序运行时动态地将 Java 类加载到 J…

pycharm 调试 debug 进入 remote_sources

解决办法1: pycharm函数跳转到remote_sources中的文件中_pycharm修改remotesource包存放地址-CSDN博客 file->settings->project structure将项目文件夹设为"Sources"(此时文件夹会变为蓝色)。 解决方法2 Debug:使用Pychar…

iOS App的启动与优化

App的启动流程 App启动分为冷启动和热启动 冷启动:从0开始启动App热启动:App已经在内存中,但是后台还挂着,再次点击图标启动App。 一般对App启动的优化都是针对冷启动。 App冷启动可分为三个阶段: dyld&#xff1a…

StarRocks FE leader节点CPU使用率周期性的忽高忽低问题分析

背景 本文基于 StarRocks 3.3.5 最近在做一些 StarRocks 相关的指标监控的时候,看到了FE master的CPU使用率相对其他FE节点是比较高的,且 呈现周期性的变化(周期为8分钟), 于此同时FE master节点的GC频率相对于其他节…

Spring高级篇-Spring IOC容器 Aware 接口

一、概述 在Spring框架中,IOC(Inversion of Control)容器负责管理应用程序中的对象(即Bean)的生命周期和依赖关系。Spring提供了一系列的Aware接口,允许Bean在初始化时获取Spring容器中的某些资源或信息。…

数字信任的底层逻辑:密码学核心技术与现实应用

安全和密码学 --The Missing Semester of Your CS Education 目录 熵与密码强度密码散列函数密钥体系 3.1 对称加密 3.2 非对称加密信任模型对比典型应用案例安全实践建议扩展练习杂项 密码学是构建数字信任的基石。 本文浅析密码学在现实工具中的应用,涵盖 1&…

MySQL数据库连接池泄露导致MySQL Server超时关闭连接

前言 最近做项目,发现老项目出现xxx,这个错误其实很简单,出现在MySQL数据库Server端对长时间没有使用的client连接执行清楚处理,因为是druid数据库,且在github也出现这样的issue:The last packet successf…