ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-01-26 20:03:53  阅读:218  来源: 互联网

标签:loss fashion 28 db ---- test tf TensorFlow model


文章目录


前言

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


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

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

(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方法对目标函数进行迭代优化
在这里插入图片描述

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()

模型结果
在这里插入图片描述
在这里插入图片描述
最终的预测精确度有0.87左右,要是再做一些优化处理和误差处理准确度还可以更高。


总结

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

标签:loss,fashion,28,db,----,test,tf,TensorFlow,model
来源: https://blog.csdn.net/qq_53144843/article/details/122707220

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有