【深度学习 走进tensorflow2.0】建立一个递归神经网络(LSTM)对MNIST数字集进行分类

无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。人工智能教程

使用CNN进行图像分类是很稀疏平常的,其实使用RNN也是可以的.
大家都知道卷积神经网络可以用来做图片分类,那么循环神经网络可不可以同样用来做图片分类呢,答案是可以滴,下面我们使用TensorFlow 2.0构建循环神经网络LSTM,一起从minist 学习下吧。

数据集特点:
该数据集包含60,000个用于训练的示例和10,000个用于测试的示例。这些数字已经过尺寸标准化并位于图像中心,图像是固定大小(28x28像素),值为0到255。为简单起见,每个图像都被展平并转换为包含784个特征(28*28)的一维numpy数组。

主要注意点:
MNIST的图像形状为28 * 28px,因此我们将为每个样本处理28个时间步长的28个序列。

实战项目–递归神经网络(LSTM)对MNIST数字集进行分类:

from __future__ import absolute_import, division, print_function

# 导入TensorFlow v2.
import tensorflow as tf
from tensorflow.keras import Model, layers
import numpy as np
# MNIST 数据集参数
num_classes = 10   #所有类别(数字 0-9)
num_features = 784 # 数据特征 (图像形状: 28*28)

# 训练参数
learning_rate = 0.001
training_steps = 2000
batch_size = 32
display_step = 100

# 网络参数
# MNIST的图像形状为28 * 28px,因此我们将为每个样本处理28个时间步长的28个序列。
num_input = 28 # 序列数
timesteps = 28 # 时间步长
num_units = 64  # LSTM层神经元数目


# 准备MNIST数据
from tensorflow.keras.datasets import mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
# 转化为float32
x_train, x_test = np.array(x_train, np.float32), np.array(x_test, np.float32)
# 将图像展平为784个特征的一维向量(28*28)。
x_train, x_test = x_train.reshape([-1, 28, 28]), x_test.reshape([-1, num_features])
# 将图像值从[0,255]归一化到[0,1]
x_train, x_test = x_train / 255., x_test / 255.
# 使用tf.data API对数据进行随机排序和批处理
train_data = tf.data.Dataset.from_tensor_slices((x_train, y_train))
train_data = train_data.repeat().shuffle(5000).batch(batch_size).prefetch(1)


# 创建LSTM模型
class LSTM(Model):
    # 创建TF模型
    def __init__(self):
        super(LSTM, self).__init__()
        # RNN (LSTM) 隐含层
        self.lstm_layer = layers.LSTM(units=num_units)
        self.out = layers.Dense(num_classes)

    # 前向传播
    def call(self, x, is_training=False):
        # LSTM层
        x = self.lstm_layer(x)
        # 输出层 (num_classes).
        x = self.out(x)
        if not is_training:
            # tf 交叉熵接收没有经过softmax的概率输出,所以只有不是训练时才应用softmax
            x = tf.nn.softmax(x)
        return x

# 创建LSTM模型
lstm_net = LSTM()
# 交叉熵损失
# 注意,这将对概率输出应用'softmax'
def cross_entropy_loss(x, y):
    # 将标签转换为int 64 作为tf交叉熵函数的输入
    y = tf.cast(y, tf.int64)
    # 对概率输出应用softmax并计算交叉熵
    loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y, logits=x)
     # 批中的平均损失
    return tf.reduce_mean(loss)

# 准确率评估
def accuracy(y_pred, y_true):
    # 预测类是预测向量(即argmax)分数最高的分量下标
    correct_prediction = tf.equal(tf.argmax(y_pred, 1), tf.cast(y_true, tf.int64))
    return tf.reduce_mean(tf.cast(correct_prediction, tf.float32), axis=-1)

# Adam 优化器
optimizer = tf.optimizers.Adam(learning_rate)
# 优化过程
def run_optimization(x, y):
     # 将计算封装在GradientTape中以实现自动微分
    with tf.GradientTape() as g:
        # 前向传播
        pred = lstm_net(x, is_training=True)
        # 计算损失
        loss = cross_entropy_loss(pred, y)

    # 要更新的变量,即可训练变量
    trainable_variables = lstm_net.trainable_variables

    # 计算梯度
    gradients = g.gradient(loss, trainable_variables)

    # 按gradients更新 W 和 b
    optimizer.apply_gradients(zip(gradients, trainable_variables))


# 针对给定步骤数进行训练
for step, (batch_x, batch_y) in enumerate(train_data.take(training_steps), 1):
     # 运行优化过程以更新W和b值
    run_optimization(batch_x, batch_y)

    if step % display_step == 0:
        pred = lstm_net(batch_x, is_training=True)
        loss = cross_entropy_loss(pred, batch_y)
        acc = accuracy(pred, batch_y)
        print("step: %i, loss: %f, accuracy: %f" % (step, loss, acc))

训练结果:

step: 100, loss: 1.346812, accuracy: 0.500000
step: 200, loss: 0.803729, accuracy: 0.718750
step: 300, loss: 0.522755, accuracy: 0.843750
step: 400, loss: 0.394801, accuracy: 0.875000
step: 500, loss: 0.465856, accuracy: 0.875000
step: 600, loss: 0.205619, accuracy: 0.937500
step: 700, loss: 0.323130, accuracy: 0.937500
step: 800, loss: 0.406646, accuracy: 0.906250
step: 900, loss: 0.097341, accuracy: 0.968750
step: 1000, loss: 0.141899, accuracy: 0.937500
step: 1100, loss: 0.140804, accuracy: 0.937500
step: 1200, loss: 0.196056, accuracy: 0.906250
step: 1300, loss: 0.072516, accuracy: 1.000000
step: 1400, loss: 0.228695, accuracy: 0.968750
step: 1500, loss: 0.071493, accuracy: 1.000000
step: 1600, loss: 0.268323, accuracy: 0.937500
step: 1700, loss: 0.042088, accuracy: 1.000000
step: 1800, loss: 0.075105, accuracy: 1.000000
step: 1900, loss: 0.195024, accuracy: 0.968750
step: 2000, loss: 0.021159, accuracy: 1.000000

最后模型训练准确率 达到100% ,真厉害啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

东华果汁哥

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

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

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

打赏作者

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

抵扣说明:

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

余额充值