tensorflow2.0 使用mnist数据集训练模型并测试手写图片识别率

话不多说,下面是源码,参考了网上找的资料.模型结构:输入->h1->h2->h3->输出,尽管在mnist测试准确率达到95%,但实际使用画图程序手写10个数字进行识别, 最多只能识别出7个,跟你笔画粗细,数字是否居中,数字大小都有关系

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets

# 加载mnist数据集
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()

# 对数据进行预处理
def preprocess(x, y):
    # 将x映射到[0,1]范围内
    x = tf.cast(x, dtype=tf.float32) / 255.
    y = tf.cast(y, dtype=tf.int32)
    return (x, y)

# 构建dataset对象,对数据进行打乱,批处理等操作
train_data = tf.data.Dataset.from_tensor_slices(
    (x_train, y_train)).shuffle(10000).batch(512)
train_data = train_data.map(preprocess)
test_data = tf.data.Dataset.from_tensor_slices(
    (x_test, y_test)).shuffle(1000).batch(512)
test_data = test_data.map(preprocess)

# 建立权重和偏置,学习效率等训练中用到的变量
w1 = tf.Variable(tf.random.truncated_normal([28*28, 256], stddev=0.1))
b1 = tf.Variable(tf.zeros(256))
w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1))
b2 = tf.Variable(tf.zeros(128))
w3 = tf.Variable(tf.random.truncated_normal([128, 64], stddev=0.1))
b3 = tf.Variable(tf.zeros(64))
w4 = tf.Variable(tf.random.truncated_normal([64, 10], stddev=0.1))
b4 = tf.Variable(tf.zeros(10))
lr = 0.1

# 循环迭代训练
for epoch in range(100):
    for step, (x, y) in enumerate(train_data):
        # 数据打平
        x = tf.reshape(x, [-1, 28*28])
        # 构建模型并计算梯度,向前计算的过程需要在GradientTape()环境下,利用gradient()方法自动求解参数梯度并利用optimizers对象更新参数
        with tf.GradientTape() as tape:
            h1 = tf.nn.relu(tf.matmul(x, w1) +
                            tf.broadcast_to(b1, [x.shape[0], 256]))
            h2 = tf.nn.relu(tf.matmul(h1, w2) + b2)
            h3 = tf.nn.relu(tf.matmul(h2, w3) + b3)
            out = tf.matmul(h3, w4) + b4
            # 将标签one_hot编码化
            y_onehot = tf.one_hot(y, depth=10)
            loss = tf.reduce_mean(tf.square(out - y_onehot))
        # 更新本次迭代的梯度参数
        grad = tape.gradient(loss, [w1, b1, w2, b2, w3, b3, w4, b4])
        w1.assign_sub(lr*grad[0])
        b1.assign_sub(lr*grad[1])
        w2.assign_sub(lr*grad[2])
        b2.assign_sub(lr*grad[3])
        w3.assign_sub(lr*grad[4])
        b3.assign_sub(lr*grad[5])
        w4.assign_sub(lr*grad[6])
        b4.assign_sub(lr*grad[7])

        # 每进行100step,打印一次训练成果
        if step % 100 == 0:
            print('epoch:', epoch, 'step:', step, 'loss:', float(loss))
    # 每训练完一次,测试一次准确率
    total_num, total_correct = 0, 0
    for step, (x, y) in enumerate(test_data):
        # 数据打平
        x = tf.reshape(x, [-1, 28*28])
        h1 = tf.nn.relu(tf.matmul(x, w1) + b1)
        h2 = tf.nn.relu(tf.matmul(h1, w2) + b2)
        h3 = tf.nn.relu(tf.matmul(h2, w3) + b3)
        out = tf.matmul(h3, w4) + b4
        # 将输出映射到[0,1]范围内
        out = tf.nn.softmax(out, axis=1)
        # 获取概率最大值的索引即为对应的数字
        index = tf.argmax(out, axis=1)
        index = tf.cast(index, dtype=tf.int32)
        # 同标签进行比较以判断对错
        correct = tf.cast(tf.equal(index, y), dtype=tf.int32)
        correct = tf.reduce_sum(correct)
        total_correct += correct
        total_num += x.shape[0]
    print('acc:', float(total_correct / total_num))

# 测试手写数字
for i in range(10):
	path = "D:\\code_project\\vscode_python\\tensorflow_v2\\my_num\\"
	path = path + str(i) + '.jpg'
	img = tf.io.read_file(path)
	img = tf.image.decode_jpeg(img)
	img = tf.image.resize(img, [28, 28])
	img = tf.image.rgb_to_grayscale(img)
	x = tf.reshape(img, [1, 28*28])
	x = tf.cast(x, dtype=tf.float32) / 255.
	h1 = tf.nn.relu(tf.matmul(x, w1) + b1)
	h2 = tf.nn.relu(tf.matmul(h1, w2) + b2)
	h3 = tf.nn.relu(tf.matmul(h2, w3) + b3)
	out = tf.nn.softmax(tf.matmul(h3, w4) + b4, axis=1)
	index = tf.cast(tf.argmax(out, axis=1), dtype=tf.int32)
	print(path, int(index[0]))

你可能感兴趣的:(tensorflow2.0 使用mnist数据集训练模型并测试手写图片识别率)