【深度学习21天学习挑战赛】1、我的手写被模型成功识别——CNN实现mnist手写数字识别模型学习笔记

活动地址:CSDN21天学习挑战赛

早上刚刚搭建好学习实验环境,然后就迫不及待的开始第一课的学习深度学习100例-卷积神经网络(CNN)实现mnist手写数字识别 | 第1天

分享一下今天学习过程,总结一下,也请大家指正,大体分三步:

  • 模仿:认真读老师教程,照着敲一篇代码
  • 思考:思考文中的一些知识点,该读文档读文档(比如一些官方文档)、该补基础补基础(比如一些算法理论)好好啃啃西瓜书
  • 实践:训练完模型,自己写了数字,进行预处理,验证模型。思考应用场景

针对新学到的知识,总结如下:(源码我就不重复了,请看老师文章


1、归一化部分

  • 我理解的是,原图(灰度图),它的每一个像素点的取值,都是0-255,灰度也可以认为是亮度,简单说就是色彩的深浅程度。

  • 因为取值范围是0-255,所以,老师在教程里进行train_images / 255.0, test_images / 255.0操作,我理解的就是把每个像素的值等比缩放成0-1区间

  • 为什么要归一化呢,相信很多同学和我一样并未完全搞清楚,我记得一本教材上说的是,归一化后加快了梯度下降求最优解的速度

2、模型定义、配置部分

  • 卷积层,之前学opencv的时候,学了卷积算法,感觉有类似的地方。构建卷积层,用于从输入的高维数组中提取特征。卷积层的每个卷积核就是一个特征映射,用于提取某一个特征,卷积核的数量决定了卷积层输出特征个数老师源码中第一个卷积层,卷积核数量32,卷积核尺寸3*3
    在这里插入图片描述

    所以,我理解的,第一层卷积层的输是input_shape=(28, 28, 1),输出:32

  • 池化层,可以这样理解,池化层作用就是对某个卷积核抽取到若干特征值,只取得其中最大的那个Pool层作为保留值,其他特征值全部抛弃,值最大代表只保留这些特征中最强的,抛弃其他弱特征,可以起到减少神经网络的数据量,简化数据,加快数据处理的作用。

  • Flatten层:用于将上一输入层的数据压成一维的数据,可以理解为把数据拉直一般用于卷积层全连接层之间,因为全连接层只能接收一维数据(向量),而卷积层可以处理二维数据(矩阵)。
    在这里插入图片描述

  • 激活函数relu:relu是用到的比较多的激活函数,它把所有的负值都变为0,而正值不变,这种操作被成为单侧抑制。
    在这里插入图片描述
    相比sigmod函数与tanh函数有以下几个优点
    a、克服梯度消失的问题
    b、快训练速度
    缺点
    a、输入负数,则完全不激活,relu函数死掉
    b、relu函数输出要么是0,要么是正数,也就是relu函数不是以0为中心的函数

深度学习中最大的问题是梯度消失问题,使用tanh、sigmod等饱和激活函数情况下特别严重,而relu函数凭借其线性、非饱和的形式,训练速度则快很多。

  • 优化器adam:Adam 这个名字来源于自适应矩估计(Adaptive Moment Estimation),也是梯度下降算法的一种变形,但是每次迭代参数的学习率都有一定的范围,不会因为梯度很大而导致学习率(步长)也变得很大,参数的值相对比较稳定。

损失函数:如果目标是数字编码 ,比如二分类0,1,损失函数用 SparseCategoricalCrossentropy,from_logits参数,官方文档是这样描述的:
在这里插入图片描述

3、模型训练情况

在这里插入图片描述
可以看到,训练到第四轮的时候,准确率就达到了99.22%

4、测试识别我的手写数字

写下数字
在这里插入图片描述
使用ps切图28*28
在这里插入图片描述
在这里插入图片描述

预处理读取图片、调整图片大小,转换成灰度

模型测试
在这里插入图片描述

5、课程完整源码

import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt

(train_images, train_labels), (test_images, test_labels) = datasets.mnist.load_data()
# 将像素的值标准化至0到1的区间内。
train_images, test_images = train_images / 255.0, test_images / 255.0

train_images.shape,test_images.shape,train_labels.shape,test_labels.shape
plt.figure(figsize=(20,10))
for i in range(20):
    plt.subplot(5,10,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(train_labels[i])
plt.show()
#调整数据到我们需要的格式
train_images = train_images.reshape((60000, 28, 28, 1))#1=通道数
test_images = test_images.reshape((10000, 28, 28, 1))

train_images.shape,test_images.shape,train_labels.shape,test_labels.shape
 
model = models.Sequential([
    layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),#卷积层1,卷积核3*3
    layers.MaxPooling2D((2, 2)),                   #池化层1,2*2采样
    layers.Conv2D(64, (3, 3), activation='relu'),  #卷积层2,卷积核3*3
    layers.MaxPooling2D((2, 2)),                   #池化层2,2*2采样
    
    layers.Flatten(),                              #Flatten层,连接卷积层与全连接层
    layers.Dense(64, activation='relu'),		   #全连接层,特征进一步提取
    layers.Dense(10)                               #输出层,输出预期结果
])
# 打印网络结构
model.summary()
 
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
 
history = model.fit(train_images, train_labels, epochs=10, 
                    validation_data=(test_images, test_labels))
plt.imshow(test_images[1])
pre = model.predict(test_images) # 对所有测试图片进行预测
pre[1] # 输出第一张图片的预测结果

学习日记

1,学习知识点

1、认识和使用卷积层、池化层的使用
2、实践CNN模型的基本搭建、训练、测试流程
3、学习了mnist数据集基本结构和使用方法

2,学习遇到的问题

还需要恶补一些神经网基础部分

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

藏蓝色攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值