当前位置: 首页 > article >正文

第T1周:Tensorflow实现mnist手写数字识别

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

目标

具体实现
(一)环境
语言环境:Python 3.10
编 译 器: PyCharm
框架: TensorFlow
**(二)具体步骤:

  1. 安装TensorFlow
    第一次使用这个框架,先安装,打开官网:TensorFlow:
    image.png
# 先把PIP升级到最新版本
$ pip install --upgrade pip  
# 安装稳定版,支持CPU和GPU
$ pip install tensorflow

演示一下官方的代码看看能不能跑(我也看不懂是什么意思,就当是hello world,看看TF正常不):
image.png
image.png
跑成功了(下图),那说明我们安装也成功了。
image.png
下面就通过具体代码来熟悉熟悉TF的使用。
2. 使用TensorFlow实现MNIST手写数字识别
2.1 设置GPU
一上来就整高阶的GPU运算,大家如果没有显卡 ,可以使用CPU(应该默认就是使用CPU),那么本步骤可以直接忽略.

import tensorflow as tf  
print("可用的GPU数量: ", len(tf.config.list_physical_devices('GPU')))

image.png
我的机器明明有显卡,但是显示0,不管了,后面再研究。
选择GPU的代码:

import tensorflow as tf  
print("可用的GPU数量: ", len(tf.config.list_physical_devices('GPU')))  
  
gpus = tf.config.list_physical_devices("GPU")  
  
if gpus:  
    gpu0 = gpus[0]  # 如果有多个GPU,则使用第0个GPU  
    tf.config.experiment.set_memory_growth(gpu0, True)  
    tf.config.set_variable_device([gpu0], "GPU")

2.2 导入MINST数据

from tensorflow.keras import datasets, layers, models
# 导入mnist数据,依次分别为训练集图片、训练集标签、测试集图片、测试集标签  
(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()

2.3 归一化

# 归一化  
train_images, test_images = train_images / 255.0, test_images / 255.0  
#查看数据形状
print('train_images.shape:', train_images.shape)  
print('test_images.shape: ', test_images.shape)  
print('train_labels: ', train_labels.shape)  
print('test_labels: ', test_labels.shape)

image.png
2.4 把数据可视化看看

# 显示数据集前50个图片数据看看  
plt.figure(figsize=(20, 10))  # 将图片显示大小设置为 20宽,10长的大小 ,单位英寸(inch)  
# 遍历MNIST数据集,下标0-49  
for i in range(50):  
    # 将整个figure分成5行10列,绘制第i+1个子图  
    plt.subplot(5, 10, i+1)  
    plt.xticks([])  # 不显示X轴刻度  
    plt.yticks([])  # 不显示Y轴刻度  
    plt.grid(False)     # 不显示网格线  
    plt.imshow(train_images[i], cmap=plt.cm.binary)  # 显示图片  
    plt.xlabel(train_labels[i])  # 显示图片对应的数字(标签)  
  
plt.show()

image.png
2.5 调整图片格式(数据形状)
为啥要调整图片格式呢,导入数据的时候,图片的形状是这样的(60000, 28,28)意思是有6000张28X28像素的图片,现在要调整成(60000, 28, 28, 1)的形状,为啥要调整形状?因为神经网络使用的数量(图像表)它的形状应该是(样本数、宽、高、通道数),对应到(60000, 28, 28)就是样本数60000张图片,宽28,高28都有了,差一个通道数。按我的理解,MNIST数据集图片是单通道图片,因此后面应该通道数是1。可以先学习一下什么叫张量表示(张量简介  |  TensorFlow Core):
image.png
image.png
image.png

再理解一张图片,通常是由RGB三通道构成的,如下:
image.png
image.png

# 调整数据格式,使用reshape来调整  
test_images = test_images.reshape((60000, 28, 28, 1))  
train_images = train_images.reshape((60000, 28, 28, 1))  
  
# 查看数据形状  
print('train_images.shape:', train_images.shape)  
print('test_images.shape: ', test_images.shape)  
print('train_labels: ', train_labels.shape)  
print('test_labels: ', test_labels.shape)

image.png
格式已经调整过来了。有人可能问train_labels和test_labels怎么不调整格式,记住这两个不是图片,是标签值,不用调整。
2.6 构建CNN网络模型(重头戏)
CNN的概念:Convolutional Neural Network,卷积神经网络)是一种前馈神经网络,特别适用于处理具有网格结构的数据,如图像或时间序列数据。CNN最初是为‌图像识别任务而设计的,但后来也被广泛应用于其他领域。
CNN的工作原理:CNN通过一系列方法成功将数据量庞大的图像识别问题不断降维,最终使其能够被训练。其工作原理主要包括以下几个部分:

  1. 卷积层:用于提取输入数据的局部特征。
  2. 池化层:用于降低特征的空间维度,减少计算量。
  3. 全连接层:用于分类或回归任务。
    CNN的特点包括局部连接、权重共享和空间层次结构,这些特点使得CNN在处理图像等数据时非常高效。
    CNN的应用领域:由于CNN在图像识别方面的出色表现,它已经被广泛应用于各种图像处理任务中。此外,CNN也被应用于‌自然语言处理和‌语音识别等领域。近年来,随着‌深度学习的发展,CNN已经成为图像分类的黄金标准。
    CNN的构建:话说把一头大像装冰箱总共需要几步,也是三步:第一步打开冰箱门,第二步放进冰箱(怎么装时冰箱的你别管),第三步关上冰箱门。CNN的构建简单来讲就是三步,第一步准备数据集(输入层),第二步做卷积运算(怎么运算的,目前还是一个黑盒子),第三步是输出结果(输出层,我们期望它输出的内容)。输入和输出大家都已经清楚了,就是这个第二步一直没闹明白,这个黑盒子内部是怎么搞的,就这么神奇的实现了各种分类,归类。今天就是来实现第二步,看看怎么搞出来的。
    CNN的模型:其实第二步的黑盒子就是神经网络模型,而模型有千千万(你自己也可以搞,只是效果怎么样就不知道了),知名的有:
    image.png
    TF框架给了我们搭建模型的方法,我们就找一个模型来试试:
    image.png
    从左到右,一步一步通过TF的方法来实现这个神经网络模型,代码中解释:
  
# 搭建模型  
model = models.Sequential([  
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),  
    layers.MaxPooling2D((2, 2)),  
    layers.Conv2D(64, (3, 3), activation='relu'),  
    layers.MaxPooling2D((2, 2)),  
  
    layers.Flatten(),  
    layers.Dense(64, activation='relu'),  
    layers.Dense(10)  
])  
  
# 打印网络结构  
print(model.summary())

image.png
解释:
Conv2D:二维卷积层,基本都用这个。
activation=‘relu’:激活函数使用ReLu函数。
MaxPooling2D: 池化层
Flatten:连接卷积层和全连接层。把张量展平。
Dense: 全连接层和输出层
image.png
2.6 编译模型

# 编译模型  
model.compile(  
    optimizer="adam",   # 设置优化器为Adam优化器  
    # 设置损失函数为交叉熵损失函数(tf.keras.losses.SparseCategoricalCrossentropy())  
    # from_logits为True时,会将y_pred转化为概率(用softmax),否则不进行转换,通常情况下用True结果更稳定  
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),  
    # 设置性能指标列表,将在模型训练时监控列表中的指标  
    metrics=['accuracy']

2.7 训练模型

# 训练模型  
history = model.fit(  
    # 输入训练集数据  
    train_images,  
    # 输入训练集标签  
    train_labels,  
    # 设置epoch为10,第一个epoch将会把所有数据输入模型完成一次训练  
    epochs=10,  
    # 设置验证集  
    validation_data=(test_images, test_labels)  
)

image.png
2.8 用这个网络模型来进行预测吧
找一张test_images里的照片先预测一下,看实际图片是什么:

plt.imshow(test_images[1])   # 上面的代码中test_images已经归一化了,可能显示不出来,可以使用归一化前的test_images看图片

image.png
拿这张照片预测一下:

pre = model.predict(test_images)  
print(pre[1])

image.png
数值最大的是第3个数,按照对应,第3个数就是2(0,1,2…这个顺序)。所以预测是对的。
改进一下,直观一点:

# 预测  
print(test_images[1].shape)  
plt.imshow(test_images[1].reshape(28, 28))  
pre = model.predict(test_images)  
print(pre[1])  
print("预测结果是:", np.argmax(pre[1]))

image.png


http://www.kler.cn/a/307541.html

相关文章:

  • 软件工程师简历(精选篇)
  • 三、损失函数
  • 三维测量与建模笔记 - 特征提取与匹配 - 4.2 梯度算子、Canny边缘检测、霍夫变换直线检测
  • odoo 17 后端路由接口认证自定义
  • linux c/c++最高效的计时方法
  • Linux如何更优质调节系统性能
  • AI学习指南深度学习篇-RMSprop在深度学习中的应用
  • 【网络】高级IO——select版本TCP服务器
  • 【系统架构设计师-2009年真题】案例分析-答案及详解
  • 【Python 数据分析学习】Matplotlib 的基础和应用
  • C/C++:优选算法(持续更新~~)
  • 【linux】cp命令
  • HTML、CSS实现树状图
  • 【无人机设计与控制】四旋翼无人机俯仰姿态保持模糊PID控制(带说明报告)
  • 基于SpringBoot+Vue+MySQL的教学资源共享平台
  • [C++]类和对象(上)
  • 携手鲲鹏,长亮科技加速银行核心系统升级
  • 7.Jmeter数据驱动(csv数据文件设置)+Jmeter数据库操作
  • 从零搭建 Docker 私有库
  • 【30天玩转python】多线程与多进程编程
  • 怎么把网站设置成HTTPS访问?
  • html+css网页制作 旅游 厦门旅游网3个页面
  • golang中连接达梦数据库使用域名来代替IP时会出现解析问题
  • c++ #include <cmath>介绍
  • TON智能合约stdlib_ext库:扩展功能一览
  • 一,掌心里的智慧:我的 TinyML 学习之旅