声明本文为「365 天深度学习训练营」内部学习记录。本文参考 K 同学啊课程内容完成仅用于个人学习与交流。MNIST 为公开数据集请勿将本文用于商业传播。本篇为个人在 T1 关卡上的实践记录。第 T1 周实现 MNIST 手写数字识别这是TensorFlow 的第一篇教案也是深度学习的入门案例。本周不追求一次吃透所有原理先把程序当黑盒跑通再逐步建立直觉。 本周任务跑通程序了解「深度学习」是什么先有感性认识即可 建议学习步骤第 1 遍整体把握每一部分代码在做什么数据 → 模型 → 训练 → 预测。第 2 遍把握每一行语句的含义知道实现的是什么功能即可不求甚解。第 3 遍动手跟着教案敲一遍代码把程序跑通。 备注如果你之前没有接触过深度学习第一篇学起来可能比较蒙不要着急。等到第 3、4 篇教案时你会逐步理解不要尝试一下就弄明白。现阶段任务是把程序当黑盒先学会使用再理解原理。 我的环境语言环境Python 3.9.13编译器Jupyter Lab深度学习环境TensorFlow 2.10.0一、前期工作设置 GPU若使用 CPU可跳过本步。importtensorflowastf gpustf.config.list_physical_devices(GPU)ifgpus:gpu0gpus[0]# 如果有多个 GPU仅使用第 0 个 GPUtf.config.experimental.set_memory_growth(gpu0,True)# 显存按需增长tf.config.set_visible_devices([gpu0],GPU)print(gpus)二、导入数据importtensorflowastffromtensorflow.kerasimportdatasets,layers,modelsimportmatplotlib.pyplotaspltimportnumpyasnp# 导入 MNIST训练集图片/标签、测试集图片/标签(train_images,train_labels),(test_images,test_labels)datasets.mnist.load_data()说明首次运行会自动下载数据默认缓存目录一般为~/.keras/datasets/。本地data.zip为课程备用包本教案使用load_data()即可无需手动解压到data/文件夹。三、归一化数据归一化的作用使不同量纲的特征处于同一数值量级减少方差大的特征的影响使模型更准确。加快学习算法的收敛速度。# 灰度图像素范围 0~255除以 255 归一化到 [0, 1]train_images,test_imagestrain_images/255.0,test_images/255.0train_images.shape,test_images.shape,train_labels.shape,test_labels.shape四、数据可视化plt.figure(figsize(20,10))foriinrange(20):plt.subplot(2,10,i1)plt.xticks([])plt.yticks([])plt.grid(False)plt.imshow(train_images[i],cmapplt.cm.binary)plt.xlabel(train_labels[i])plt.show()五、调整数据格式卷积层需要输入形状为(高, 宽, 通道)因此把(60000, 28, 28)调整为(60000, 28, 28, 1)。train_imagestrain_images.reshape((60000,28,28,1))test_imagestest_images.reshape((10000,28,28,1))train_images.shape,test_images.shape,train_labels.shape,test_labels.shape期望输出类似((60000, 28, 28, 1), (10000, 28, 28, 1), (60000,), (10000,))六、创建卷积神经网络本文使用的是最简单的 CNN 结构类似LeNet-5思路卷积层通过卷积操作对输入图像进行降维和特征抽取。池化层非线性下采样压缩数据与参数数量减轻过拟合提高鲁棒性。全连接层在若干卷积与池化之后完成高级推理。modelmodels.Sequential([layers.Conv2D(32,(3,3),activationrelu,input_shape(28,28,1)),layers.MaxPooling2D((2,2)),layers.Conv2D(64,(3,3),activationrelu),layers.MaxPooling2D((2,2)),layers.Flatten(),layers.Dense(64,activationrelu),layers.Dense(10),])model.summary()ReLU作为激活函数可增强非线性且通常能让训练更快而对泛化影响相对温和。七、编译与训练model.compile()用于配置训练时的优化器、损失函数和评测指标。model.compile(optimizeradam,losstf.keras.losses.SparseCategoricalCrossentropy(from_logitsTrue),metrics[accuracy],)historymodel.fit(train_images,train_labels,epochs10,validation_data(test_images,test_labels),)关于model.fit()的更多参数说明可参考Keras model.fit 详解。训练曲线fromdatetimeimportdatetime current_timedatetime.now()acchistory.history[accuracy]val_acchistory.history[val_accuracy]losshistory.history[loss]val_losshistory.history[val_loss]epochs_rangerange(1,len(acc)1)plt.figure(figsize(12,4))plt.subplot(1,2,1)plt.plot(epochs_range,acc,labelTrain Accuracy)plt.plot(epochs_range,val_acc,labelTest Accuracy)plt.legend(loclower right)plt.title(Training and Validation Accuracy)plt.xlabel(current_time)plt.subplot(1,2,2)plt.plot(epochs_range,loss,labelTrain Loss)plt.plot(epochs_range,val_loss,labelTest Loss)plt.legend(locupper right)plt.title(Training and Validation Loss)plt.show()八、模型预测可以简单理解为输入一张图片模型输出 10 个数分别对应数字 0~9 的「得分」logits并非概率。数值越大模型越倾向于该类别。# 部分 matplotlib 版本会报 Invalid shape (28, 28, 1)可改为 reshape(28, 28)plt.imshow(test_images[1].reshape(28,28),cmapplt.cm.binary)plt.axis(off)plt.show()premodel.predict(test_images)# 对所有测试图片预测pre[1]# 第一张测试图的 10 维输出np.argmax(pre[1])# 预测类别0~9 中得分最大的索引可与真实标签对比print(预测数字:,np.argmax(pre[1]))print(真实标签:,test_labels[1])九、知识点详解若是第一次接触深度学习建议顺序先跑通 → 再对照结构理解。MNIST 手写数字数据集MNIST 来源于美国国家标准与技术研究所NIST是经典公开数据集之一。数据由 250 名不同职业者手写绘制官方页面http://yann.lecun.com/exdb/mnist/。共70000张 28×28 灰度图训练集 60000、测试集 10000。每张图可拉平为长度784的向量像素值归一化后约在 0~1。若把训练集看成张量形状可理解为[60000, 784]第一维是图片索引第二维是像素。各层的作用层级作用输入层将数据送入网络卷积层用卷积核提取局部特征池化层下采样用更高层抽象表示图像Flatten 层将多维特征展平连接卷积与全连接全连接层进一步组合特征输出层输出 10 类 logits十、常见问题汇总1.data文件夹放在哪里本教案使用datasets.mnist.load_data()不需要手动把 MNIST 放到项目data/目录。首次运行会自动下载到用户目录下的 Keras 缓存路径常见为~/.keras/datasets/mnist.npz。若课程提供了data.zip那是备用数据包与load_data()二选一即可不要混用导致路径困惑。2.plt.imshow报Invalid shape (28, 28, 1)将显示代码改为plt.imshow(test_images[1].reshape(28,28),cmapplt.cm.binary)3. 没有 GPU 能跑吗可以。跳过 GPU 设置单元TensorFlow 会自动使用 CPUMNIST 规模较小CPU 也能在可接受时间内完成训练。4.from_logitsTrue是什么意思最后一层未接 Softmax 时损失函数内部会做数值稳定的处理训练时通常更稳定。预测时用np.argmax取最大 logit 即可得到类别。—十一、本周总结本周完成了 TensorFlow 入门链路加载 MNIST → 归一化与可视化 → 搭建 CNN → 编译训练 → 单张/批量预测。核心收获建立了「数据预处理 → 模型定义 →compile/fit→predict」的完整流程理解了归一化、通道维度reshape、卷积/池化/全连接的分工知道现阶段以跑通黑盒为主原理可在后续周次逐步加深。后续可尝试减少epochs做快速实验、对比 CPU/GPU 速度、或改用 PyTorch 版本如训练营 P1对照两种框架的写法差异。