深度学习(4)手写数字识别实战

Step0. 数据及模型准备

1. X and Y(数据准备)

在这里插入图片描述
(1) (xs, ys)容量为60k,即共有6万张图片;
(2) xs.shape: [60k, 28, 28]; ys.shape: [60k];
(3) xs = tf.convert_to_tensor: mnist.load_data格式为numpy,而要使用GPU需要将其转化为tensor格式;
(4) db = tf.data.Dataset.from_tensor_slices((xs, ys)): 将数据转化为Dataset类型,这样可以利用batch一批送入多个数据,默认情况下一批送入一个数据; 如果后边加上.batch(64)那么一批就可以送入64个数据;
(5) for step, (x, y) in enmuerate(db):print(step, x.shape,y, y.shape): 循环迭代db,并输出每条数据的shape,如下图所示:
注: 如果设置.batch(64)的话,x.shape: [64, 28, 28];y.shape: [64];
运行结果如下图所示:
在这里插入图片描述

2. o u t = r e l u { r e l u { r e l u [ X @ W 1 + b 1 ] @ W 2 + b 2 } @ W 3 + b 3 } out=relu\{relu\{relu[X@W_1+b_1]@W_2+b_2\}@W_3+b_3\} out=relu{relu{relu[X@W1+b1]@W2+b2}@W3+b3}(模型准备)

在这里插入图片描述

(1) 降维过程: 784 → \to 512 → \to 256 → \to 10;
(2) Dense函数: 每层需要调用Dense函数,这是全连接(线性层)中的函数,用来组成每层的结构;
layers.Dense(512, activation=‘relu’),表示图片由784降维成512,并且非线性因子(即激活函数)为relu;
layers.Dense(256, activation=‘relu’),表示图片由512降维成256,并且非线性因子(即激活函数)为relu;
layers.Dense(10, activation=‘relu’),表示图片由256降维成10;
(3) 每个参数的更新规则为: w ′ = w − l r ∗ ∂ l ∂ w w'=w-lr*\frac{∂l}{∂w} w=wlrwl;
(4) optimizer的作用就是需要哪些参数,optimizer就会自动按照规则进行更新,只需要设置其步长(即学习率 l r lr lr)即可;

Step1&2. Cmpute o u t out out& l o s s loss loss(计算 h 1 h_1 h1 h 2 h_2 h2 h 3 h_3 h3

在这里插入图片描述

(1) x = tf.rehsape(x, (-1, 28*28)): 将数据进行“打平”操作,即由28*28变为784维向量;
(2) 这部分不需要考虑 h 1 h_1 h1 h 2 h_2 h2,只需要考虑 o u t out out,最终的 o u t : [ 1 , 10 ] out: [1, 10] out:[1,10];
(3) loss = tf.reduce_sum(tf.squre(out - y)) / x.shape[0]: y y y o u t out out之间的欧式距离就是 l o s s loss loss,即: l o s s = 1 n ∑ ( y − o u t ) 2 loss=\frac{1}{n}\sum(y-out)^2 loss=n1(yout)2 ;

Step3. Compute gradient and optimize(更新)

在这里插入图片描述

(1) tape.gradient(loss, model.trainable_variables): 自动求导工具,因为网络层数增加,每层都计算导数会非常麻烦,所以我们需要这个工具; tape.gradient(y, x)就是 ∂ y ∂ x \frac{∂y}{∂x} xy; 对于手写数字识别问题来说, l o s s loss loss就是 y y y,而model.trainable_variables(即 [ W 1 , W 2 , W 3 , b 1 , b 2 , b 3 ] [W_1,W_2,W_3,b_1,b_2,b_3] [W1,W2,W3,b1,b2,b3])就是 x x x;
(2) 得到grads后,利用规则: w ′ = w − l r ∗ ∂ l ∂ w w'=w-lr*\frac{∂l}{∂w} w=wlrwl 和自动更新工具optimizer对所有参数进行更新;

Step4. Loop(循环迭代)

在这里插入图片描述

(1) train_dataset里共有60k个样本,假设一次取60张图片,那么一共需要循环1000次训练,把对60k个样本进行一次训练叫做一个epoch; 把对60张图片(即一个batch)进行一次训练叫做一个step; 一个epoch通常包含多个step;
(2) train_epoch(epoch): 对整个数据集迭代一次; 多次调用即可完成对数据集的多次迭代和多次更新;
(3) 将batch设置为200,也就是一共训练30次。
运行结果如下:
注: 如果出现以下报错:

None -- [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)

则为证书验证问题,需要添加:

import ssl

ssl._create_default_https_context = ssl._create_unverified_context

即可。

完整代码

import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics
import ssl

ssl._create_default_https_context = ssl._create_unverified_context

# 设置GPU使用方式
# 获取GPU列表
gpus = tf.config.experimental.list_physical_devices('GPU')
if gpus:
  try:
    # 设置GPU为增长式占用
    for gpu in gpus:
      tf.config.experimental.set_memory_growth(gpu, True)
  except RuntimeError as e:
    # 打印异常
    print(e)

(x, y), (x_val, y_val) = datasets.mnist.load_data()
x = tf.convert_to_tensor(x, dtype=tf.float32) / 255.
y = tf.convert_to_tensor(y, dtype=tf.int32)
y = tf.one_hot(y, depth=10)
print('datasets:', x.shape, y.shape)
train_dataset = tf.data.Dataset.from_tensor_slices((x, y))
train_dataset = train_dataset.batch(200)


model = keras.Sequential([
    layers.Dense(512, activation='relu'),
    layers.Dense(256, activation='relu'),
    layers.Dense(10)])

optimizer = optimizers.SGD(lr=0.01)


def train_epoch(epoch):
    # Step4. loop
    for step, (x, y) in enumerate(train_dataset):
        with tf.GradientTape() as tape:
            # 打平操作,[b, 28, 28] => [b, 784]
            x = tf.reshape(x, (-1, 28 * 28))
            # Step1. 得到模型输出output [b, 784] => [b, 10]
            out = model(x)
            # Step2. Compute loss
            loss = tf.reduce_sum(tf.square(out - y)) / x.shape[0]

            # Step3. optimizer and update w1, w2, w3, b1, b2, b3
        grads = tape.gradient(loss, model.trainable_variables)
        # w' = w - lr * grad
        optimizer.apply_gradients(zip(grads, model.trainable_variables))

        if step % 100 == 0:
            print(epoch, step, loss.numpy())

def train():

    for epoch in range(30):

        train_epoch(epoch)


if __name__ == '__main__':
    train()

运行结果

在这里插入图片描述
. . . ... ...
在这里插入图片描述

参考文献:
[1] 龙良曲:《深度学习与TensorFlow2入门实战》
[2] https://blog.csdn.net/qq_43653405/article/details/108449661

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值