上饶市网站建设_网站建设公司_在线客服_seo优化
2026/1/3 4:02:37 网站建设 项目流程
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

前言

  • 实验环境
python 3.9.2 tensorflow 2.10.0 Jupyter Notebook: 7.4.5

代码实现

设置gpu以及打印时间戳

# 打印当前时间importdatetimeprint(datetime.datetime.now())# 配置gpuimporttensorflowastf gpus=tf.config.list_physical_devices("GPU")ifgpus:gpu0=gpus[0]tf.config.experimental.set_memory_growth(gpu0,True)# 设置gpu现存用量按需使用tf.config.set_visible_devices([gpu0],"GPU")print(gpus)

导入数据

# 数据导入importtensorflowastffromtensorflow.kerasimportdatasets,layers,modelsimportmatplotlib.pyplotasplt# 导入mnist数据,依次分别为训练集图片、训练集标签、测试集图片、测试集标签(train_images,train_labels),(test_images,test_labels)=datasets.mnist.load_data()

数据归一化

# 将像素的值标准化至0到1的区间内。(对于灰度图片来说,每个像素最大值是255,每个像素最小值是0,也就是直接除以255就可以完成归一化。) 这样做可以加速模型的收敛速度,因为大部分神经网络激活函数(如ReLU)在输入值较小时表现更好。train_images,test_images=train_images/255.0,test_images/255.0# 查看数据维数信息train_images.shape,test_images.shape,train_labels.shape,test_labels.shape

可视化图片

# 将数据集前20个图片数据可视化显示# 进行图像大小为20宽、10长的绘图(单位为英寸inch)plt.figure(figsize=(20,10))# 遍历MNIST数据集下标数值0~19foriinrange(20):# 将整个figure分成2行10列,绘制第i+1个子图。plt.subplot(2,10,i+1)# 设置不显示x轴刻度plt.xticks([])# 设置不显示y轴刻度plt.yticks([])# 设置不显示子图网格线plt.grid(False)# 图像展示,cmap为颜色图谱,"plt.cm.binary"为matplotlib.cm中的色表plt.imshow(train_images[i],cmap=plt.cm.binary)# 设置x轴标签显示为图片对应的数字plt.xlabel(train_labels[i])# 显示图片plt.show()

调整图片格式

#调整数据到我们需要的格式,分别对应样本数、高度、宽度、颜色通道数train_images=train_images.reshape((60000,28,28,1))test_images=test_images.reshape((10000,28,28,1))train_images.shape,test_images.shape,train_labels.shape,test_labels.shape

构建模型


  • 各层的作用:
    • 输入层:
      • 作用: 这是模型接收原始数据的入口。在代码中,它体现在layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1))input_shape参数。它定义了模型期望接收的数据格式,这里是(28, 28, 1),代表高度28像素、宽度28像素、1个颜色通道(灰度图)的图像。它本身不进行任何计算,只是规定了数据进入模型的“接口”形状。
    • 卷积层:
      • 作用: 这是卷积神经网络(CNN)的核心。它使用一组可学习的滤波器(也叫卷积核或特征探测器)在输入图像上滑动。
      • 特征提取: 每个卷积核会扫描图像的局部区域,计算卷积运算(加权求和),从而检测特定的局部特征,例如边缘、线条、角点、特定方向的纹理等。在代码中,第一个卷积层使用了32个3x3的卷积核,意味着它会学习提取32种不同的低级特征。第二个卷积层使用了64个3x3的卷积核,它会在第一个卷积层提取的特征基础上,进一步组合和学习更复杂、更抽象的特征。
      • 参数32/64: 表示该层包含的卷积核(滤波器)的数量。数量越多,模型能学习到的特征模式就越多。
      • 参数(3, 3): 表示卷积核的尺寸,这里是3x3的窗口。
      • 参数activation='relu': 应用ReLU激活函数,引入非线性,使得网络能够学习更复杂的模式。ReLU函数(f(x) = max(0, x))还能缓解梯度消失问题,加速训练。
    • 池化层:
      • 作用: 主要进行下采样,即减少数据的空间尺寸(宽度和高度)。
      • 减少参数和计算量: 通过降低特征图的维度,减少了后续层的参数数量和计算量,从而加快训练速度并降低过拟合风险。
      • 特征不变性: 在小区域内进行聚合(如最大池化取最大值),能在一定程度上保持对微小平移、旋转等变换的鲁棒性。
      • 增大感受野: 使得后续的卷积层能看到更大范围的原始输入信息。
      • 参数(2, 2): 表示池化窗口的大小是2x2。这个窗口会滑过输入特征图,每次移动2个像素(步长通常等于窗口大小),并应用聚合操作(这里是最大值)。
    • Flatten层:
      • 作用: 这是一个非常重要的“格式转换器”。
      • 维度重塑: 它将前面卷积层和池化层输出的多维特征图(例如,经过池化后可能是(batch_size, height, width, channels)形状)压平成一维向量(形状变为(batch_size, height * width * channels))。
      • 连接卷积与全连接: 这是卷积部分和全连接部分之间的桥梁。因为全连接层期望接收一维的输入向量,而卷积层输出的是多维张量。
    • 全连接层:
      • 作用: 在代码中,layers.Dense(64, activation='relu')起到了“特征提取器”和“分类器”的双重作用。在靠近输出的部分,它更像是一个分类器。
      • 特征整合: 它接收来自Flatten层的一维向量(即前面所有卷积层提取的综合特征),并将其与该层的所有神经元进行全连接。
      • 学习高维表示: 通过学习权重和偏置,它能够将前面提取的局部特征组合成更高层次、更抽象的表示,用于最终的分类决策。
      • 参数64: 表示该层神经元的数量。这决定了该层输出特征向量的维度。
      • 参数activation='relu': 再次应用ReLU激活函数,引入非线性。
    • 输出层 (Output Layer):
      • 作用: 这是模型的最后一层,负责输出最终的预测结果。
      • 分类决策: 在多分类任务(如在本次MNIST的10个数字分类任务)中,它的神经元数量等于类别数(这次是10)。它接收上一层(全连接层)的特征表示,并将其转换为对每个类别的预测分数(logits)。
      • 参数10: 表示输出空间的维度,对应MNIST数据集的10个数字类别(0-9)。模型会为输入图像计算出一个10维的输出向量,通常这个向量中数值最大的那个索引就代表模型预测的类别。
# 构建模型model=models.Sequential([# 设置二维卷积层1,设置32个3*3卷积核,activation参数将激活函数设置为ReLu函数,input_shape参数将图层的输入形状设置为(28, 28, 1)# ReLu函数作为激活励函数可以增强判定函数和整个神经网络的非线性特性,而本身并不会改变卷积层# 相比其它函数来说,ReLU函数更受青睐,这是因为它可以将神经网络的训练速度提升数倍,而并不会对模型的泛化准确度造成显著影响。layers.Conv2D(32,(3,3),activation='relu',input_shape=(28,28,1)),#池化层1,2*2采样layers.MaxPooling2D((2,2)),# 设置二维卷积层2,设置64个3*3卷积核,activation参数将激活函数设置为ReLu函数layers.Conv2D(64,(3,3),activation='relu'),#池化层2,2*2采样layers.MaxPooling2D((2,2)),layers.Flatten(),#Flatten层,连接卷积层与全连接层layers.Dense(64,activation='relu'),#全连接层,特征进一步提取,64为输出空间的维数,activation参数将激活函数设置为ReLu函数layers.Dense(10)#输出层,输出预期结果,10为输出空间的维数])# 打印网络结构model.summary()

编译模型

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

训练模型

""" 这里设置输入训练数据集(图片及标签)、验证数据集(图片及标签)以及迭代次数epochs 关于model.fit()函数的具体介绍可参考我的博客: https://blog.csdn.net/qq_38251616/article/details/122321757 """history=model.fit(# 输入训练集图片train_images,# 输入训练集标签train_labels,# 设置10个epoch,每一个epoch都将会把所有的数据输入模型完成一次训练。epochs=10,# 设置验证集validation_data=(test_images,test_labels))

模型预测

plt.imshow(test_images[1])

pre=model.predict(test_images)# 对所有测试图片进行预测pre[1]# 输出第一张图片的预测结果

学习总结

  • 深度学习是什么?
    • 我认为深度学习是通过多层非线性变换,从原始数据(如图像、文本、声音)中学习层次化的特征表示。较低层学习基础特征(如边缘、角点),较高层则组合这些基础特征形成更抽象、更有意义的表示(如形状、物体部件),最终用于分类、识别、生成等任务。
  • 本次任务通过构建和训练一个卷积神经网络(CNN)识别MNIST手写数字,让我对TensorFlow框架有了初步的认识。TensorFlow提供了一套清晰、模块化的API,使得从数据加载(datasets.mnist.load_data)、数据预处理(归一化、reshape)、模型构建(Sequential模型和layers模块)、模型编译(model.compile)到模型训练(model.fit)和预测(model.predict)的整个深度学习流程都变得结构化和易于实现。特别是集成的Kerastf.keras)API,极大地简化了模型搭建的复杂度,相比于PyTorch框架,在快速模型构建方面变得更方便了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询