TensorFlow----fashion_mnist数据集神经网络的搭建

文章目录


前言

深度学习小白,若有错误希望各位大佬多多包涵。


一、数据集加载以及数据集的预处理

数据集可以直接从网上下载,这里把数据集分为了训练集和测试集,但是更多的时候我们会分成训练集,交叉验证集和测试集,这样的训练效果会更好。

(x, y), (x_test, y_test) = datasets.fashion_mnist.load_data()

这里得到的x, y, x_test , y_test都是Numpy类型,要转化为张量类型

def preprocess(x, y):
    # 并做归一化处理
    x = tf.cast(x, dtype=tf.float32) / 255.
    y = tf.cast(y, dtype=tf.int32)
    return x, y

这个函数与map()组合使用,传入preprocess,即可完成映射,类型转换

然后,为了加快计算的速度将整个样本切片为batch大小的小样本
为了方便操作,先生成Dataset类的对象,然后再dataset成员方法batch

db = tf.data.Dataset.from_tensor_slices((x, y))
db = db.map(preprocess).shuffle(10000).batch(batches) 

测试集做相同的处理即可

循环处理每一个batch数据样本

sample = next(iter(db))

二、全连接网络层构建

使用Sequential容器,生成Sequential类的一个实例

model = Sequential([
    # [b,784] @ [784,256]--> [b,256]
    layers.Dense(256, activation=tf.nn.relu),
    # [b,256]--> [b,128]
    layers.Dense(128, activation=tf.nn.relu),
    # [b, 128] --> [b,64]
    layers.Dense(64, activation=tf.nn.relu),
    # [b,64] --> [b,32]
    layers.Dense(32, activation=tf.nn.relu),
    # [b,32] --> [b,10] 输出层
    layers.Dense(10)
])

并用成员函数build, summary完成网络权值,偏置和输入维度的初始化与网络模型参数状况的输出

model.build(input_shape=[None, 28 * 28]) 
model.summary()

构造优化器
优化器主要使用apply_gradients方法传入变量和对应梯度从而来对给定变量进行迭代,或者直接使用minimize方法对目标函数进行迭代优化
TensorFlow----fashion_mnist数据集神经网络的搭建

optimizers = optimizers.Adam(learning_rate=1e-3)

三、计算梯度和代价函数并更新参数

在使用自动求导功能计算梯度,需要将向前计算过程放置在tf.GradientTape()环境中, 利用GradientTape对象的gradient()方法自动求解参数的梯度, 并利用optimizers对象更新参数

 with tf.GradientTape() as tape:
 	logits = model(x)
 	y_onehot = tf.one_hot(y, depth=10)
 	loss_ce = tf.losses.categorical_crossentropy(y_onehot, logits, from_logits=True)
    loss_ce = tf.reduce_mean(loss_ce)

grads = tape.gradient(loss_ce, model.trainable_variables)
optimizers.apply_gradients(zip(grads, model.trainable_variables))

四、完整程序

# -*- codeing = utf-8 -*-
# @Time : 10:02
# @Author:Paranipd
# @File : mnist_test.py
# @Software:PyCharm

import os
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics  # 数据集, 网络层, 分类器, 容器

os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'  # 去掉不必要的报错

# 预处理,参数类型转换 ,加载的数据集是Nunpy类型
def preprocess(x, y):
    # 并做归一化处理
    x = tf.cast(x, dtype=tf.float32) / 255.
    y = tf.cast(y, dtype=tf.int32)
    return x, y

# 加载数据集 = 训练集 + 测试集  x,y : 普通数据类型(Numpy)
# x.sahpe : (60000, 28 , 28) y.shape:(60000,)
# x.min-max:(0,255)   y :[0,9]
(x, y), (x_test, y_test) = datasets.fashion_mnist.load_data()
print(x.shape, x.dtype, y.shape, y.dtype)

# 批处理样本数
batches = 128
# 创建一个数据集,其元素是给定张量的切片
# 通过使用tf.data.Dataset提供的接口from_tensor_slices将(x,y)-->Dataset类的对象
db = tf.data.Dataset.from_tensor_slices((x, y))
# map数据类型的转换
# shuffle 将数据集随机打散
# batch 将多个样本组成一个batch ,加速计算
# 注意不同的顺序,会有不同的结果
db = db.map(preprocess).shuffle(10000).batch(batches)  # 为了使每次取数据样本的数量为batches
# print('db:', db)


db_test = tf.data.Dataset.from_tensor_slices((x_test, y_test))
db_test = db_test.map(preprocess).batch(batches)

# 通过Dataset的对象db进行迭代,获取下一批batch  ==>sample = next(iter(db))
db_iter = iter(db)
sample = next(db_iter)
print('batch:', sample[0].shape, sample[1].shape)

# 通过Sequential容器封装一个网络大类对象
model = Sequential([
    # [b,784] @ [784,256]--> [b,256]
    layers.Dense(256, activation=tf.nn.relu),
    # [b,256]--> [b,128]
    layers.Dense(128, activation=tf.nn.relu),
    # [b, 128] --> [b,64]
    layers.Dense(64, activation=tf.nn.relu),
    # [b,64] --> [b,32]
    layers.Dense(32, activation=tf.nn.relu),
    # [b,32] --> [b,10] 输出层
    layers.Dense(10)
])

# 初始化网络的权值和维度
model.build(input_shape=[None, 28 * 28])    # Sequential类的类方法
# 输出网络模式各层的参数状况,查看网络模型的结构
model.summary()

# w = w - lr * grad
# 学习率的设置,更新参数
optimizers = optimizers.Adam(learning_rate=1e-3)


def main():
    # 将整个数据集迭代30次
    for epoch in range(30):
        # 迭代数据集对象,待step参数 ,完成一次batch的数据训练叫做一个step
        # 批次处理部分数据集,一次处理128个样本
        for step, (x, y) in enumerate(db):
            # x: [b,28,28] ==> [b,784]   一维
            # y: [b]
            x = tf.reshape(x, [-1, 28 * 28])

            # 在使用自动求导功能计算梯度,需要将向前计算过程放置在tf.GradientTape()环境中
            # 利用GradientTape对象的gradient()方法自动求解参数的梯度
            # 并利用optimizers对象更新参数
            with tf.GradientTape() as tape:    # 梯度记录器
                # [b,784] ==> [b,10]
                # model(x) 实际是调用类中__call__方法
                # 输出网络模型(向前计算)结果
                logits = model(x)
                # onehot编码
                y_onehot = tf.one_hot(y, depth=10)

                # 均方差代价函数
                loss_mse = tf.reduce_mean(tf.losses.MSE(y_onehot, logits))
                # 交叉熵损失计算函数
                loss_ce = tf.losses.categorical_crossentropy(y_onehot, logits, from_logits=True)
                loss_ce = tf.reduce_mean(loss_ce)

            # 对所有的可优化变量求导
            grads = tape.gradient(loss_ce, model.trainable_variables)
            # 更新可以优化张量
            # zip将对应元素打包为元组,这些元组组成一个列表
            optimizers.apply_gradients(zip(grads, model.trainable_variables))

            if step % 100 == 0:
                print(epoch, step, 'loss:', float(loss_ce), float(loss_mse))

        # test 计算一个精确度
        total_correct = 0
        total_num = 0
        for x, y in db_test:
            # x: [b,28,28] ==> [b,784]
            # y: [b]
            x = tf.reshape(x, [-1, 28 * 28])
            # [b,10]
            logits = model(x)
            # logits --> prob: [b,10] int64

            # 将输出结果归一化处理,得到和为1的概率
            prob = tf.nn.softmax(logits, axis=1)  # [0,1]
            # 找到对应维度最大值的索引位置
            pred = tf.argmax(prob, axis=1)
            pred = tf.cast(pred, dtype=tf.int32)
            # pred:[b]
            # y: [b]
            # correct: [b], True(1): equal; False(0): not equal
            correct = tf.equal(pred, y)
            correct = tf.reduce_sum(tf.cast(correct, dtype=tf.int32))
            # 预测对的数量
            total_correct += int(correct)
            # 总的数量
            total_num += x.shape[0]
        # 精确度
        acc = total_correct / total_num
        print(epoch, 'text acc:', acc)

if __name__ == "__main__":
    main()

模型结果
TensorFlow----fashion_mnist数据集神经网络的搭建
TensorFlow----fashion_mnist数据集神经网络的搭建
最终的预测精确度有0.87左右,要是再做一些优化处理和误差处理准确度还可以更高。


总结

提示:这里对文章进行总结:

上一篇:flink的内存管理


下一篇:nacos进阶二--使用源码启动项目