【Tensorflow】Tensorflow实现简单神经网络进行手写数字识别

前言

【Tensorflow】Tensorflow实现线性回归及逻辑回归

【深度学习】神经网络与BP算法

前一篇介绍了使用 Tensorflow 实现线性回归及逻辑回归,并实现了手写数字识别的案例;后一篇介绍了BP神经网络,以及Python实现。本篇将通过 Tensorflow 实现简单神经网络(1个输入层、2个隐藏层、1个输出层),并应用有手写数字识别案例。

代码

# 引入包
import tensorflow as tf
import matplotlib as mpl
from tensorflow.examples.tutorials.mnist import input_data

# 设置字符集,防止中文乱码
mpl.rcParams['font.sans-serif'] = [u'simHei']
mpl.rcParams['axes.unicode_minus'] = False

# 数据加载
mnist = input_data.read_data_sets('../data/', one_hot=True)
# print(mnist.train.images.shape)
# print(mnist.train.labels)

# 构建神经网络(4层、1 input, 2 hidden,1 output)
n_unit_hidden_1 = 256  # 第一层hidden中的神经元数目
n_unit_hidden_2 = 128  # 第二层的hidden中的神经元数目
n_input = 784  # 输入的一个样本(图像)是28*28像素的
n_classes = 10  # 输出的类别数目

# 定义输入的占位符
x = tf.placeholder(tf.float32, shape=[None, n_input], name='x')
y = tf.placeholder(tf.float32, shape=[None, n_classes], name='y')

# 构建初始化的w和b
weights = {
    "w1": tf.Variable(tf.random_normal(shape=[n_input, n_unit_hidden_1], stddev=0.1)),
    "w2": tf.Variable(tf.random_normal(shape=[n_unit_hidden_1, n_unit_hidden_2], stddev=0.1)),
    "out": tf.Variable(tf.random_normal(shape=[n_unit_hidden_2, n_classes], stddev=0.1))
}
biases = {
    "b1": tf.Variable(tf.random_normal(shape=[n_unit_hidden_1], stddev=0.1)),
    "b2": tf.Variable(tf.random_normal(shape=[n_unit_hidden_2], stddev=0.1)),
    "out": tf.Variable(tf.random_normal(shape=[n_classes], stddev=0.1))
}

def multiplayer_perceotron(_X, _weights, _biases):
    # 第一层 -> 第二层  input -> hidden1
    layer1 = tf.nn.sigmoid(tf.add(tf.matmul(_X, _weights['w1']), _biases['b1']))
    # 第二层 -> 第三层 hidden1 -> hidden2
    layer2 = tf.nn.sigmoid(tf.add(tf.matmul(layer1, _weights['w2']), _biases['b2']))
    # 第三层 -> 第四层 hidden2 -> output
    return tf.matmul(layer2, _weights['out']) + _biases['out']


# 获取预测值
act = multiplayer_perceotron(x, weights, biases)

# 构建模型的损失函数
# softmax_cross_entropy_with_logits: 计算softmax中的每个样本的交叉熵,logits指定预测值,labels指定实际值
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=act, labels=y))

# 使用梯度下降求解
# 使用梯度下降,最小化误差
# learning_rate: 要注意,不要过大,过大可能不收敛,也不要过小,过小收敛速度比较慢
train = tf.train.GradientDescentOptimizer(learning_rate=0.01).minimize(cost)

# 得到预测的类别是那一个
# tf.argmax:对矩阵按行或列计算最大值对应的下标,和numpy中的一样
# tf.equal:是对比这两个矩阵或者向量的相等的元素,如果是相等的那就返回True,反正返回False,返回的值的矩阵维度和A是一样的
pred = tf.equal(tf.argmax(act, axis=1), tf.argmax(y, axis=1))
# 正确率(True转换为1,False转换为0)
acc = tf.reduce_mean(tf.cast(pred, tf.float32))

# 初始化
init = tf.global_variables_initializer()

# 执行模型的训练
batch_size = 100  # 每次处理的图片数
display_step = 1  # 每4次迭代打印一次
# LAUNCH THE GRAPH
with tf.Session() as sess:
    # 进行数据初始化
    sess.run(init)

    # 模型保存、持久化
    saver = tf.train.Saver()
    epoch = 0
    while True:
        avg_cost = 0
        # 计算出总的批次
        total_batch = int(mnist.train.num_examples / batch_size)
        # 迭代更新
        for i in range(total_batch):
            # 获取x和y
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            feeds = {x: batch_xs, y: batch_ys}
            # 模型训练
            sess.run(train, feed_dict=feeds)
            # 获取损失函数值
            avg_cost += sess.run(cost, feed_dict=feeds)

        # 重新计算平均损失(相当于计算每个样本的损失值)
        avg_cost = avg_cost / total_batch

        # DISPLAY  显示误差率和训练集的正确率以此测试集的正确率
        if (epoch + 1) % display_step == 0:
            print("批次: %03d 损失函数值: %.9f" % (epoch, avg_cost))
            feeds = {x: mnist.train.images, y: mnist.train.labels}
            train_acc = sess.run(acc, feed_dict=feeds)
            print("训练集准确率: %.3f" % train_acc)
            feeds = {x: mnist.test.images, y: mnist.test.labels}
            test_acc = sess.run(acc, feed_dict=feeds)
            print("测试准确率: %.3f" % test_acc)
			# 训练和测试准确率大于0.9退出训练
            if train_acc > 0.9 and test_acc > 0.9:
                saver.save(sess, './mn/model')
                break
        epoch += 1

    # 模型可视化输出
    writer = tf.summary.FileWriter('./mn/graph', tf.get_default_graph())
    writer.close()

运行结果:

在这里插入图片描述

代码可见:Github

tensorboard 可视化

终端执行:tensorboard --logdir F:\Github_sources\Tensorflow\tensorflow_bp\mn\graph

后面的路径是程序中:writer = tf.summary.FileWriter('./mn/graph', tf.get_default_graph()) 指定的,写绝对路径

在这里插入图片描述

打开浏览器输入:http://用户名:6006

在这里插入图片描述

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
利用tensorflow实现的卷积神经网络进行MNIST手写数字图像的分类。 #导入numpy模块 import numpy as np #导入tensorflow模块,程序使用tensorflow实现卷积神经网络 import tensorflow as tf #下载mnist数据集,并从mnist_data目录中读取数据 from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets('mnist_data',one_hot=True) #(1)这里的“mnist_data” 是和当前文件相同目录下的一个文件夹。自己先手工建立这个文件夹,然后从https://yann.lecun.com/exdb/mnist/ 下载所需的4个文件(即该网址中第三段“Four files are available on this site:”后面的四个文件),并放到目录MNIST_data下即可。 #(2)MNIST数据集是手写数字字符的数据集。每个样本都是一张28*28像素的灰度手写数字图片。 #(3)one_hot表示独热编码,其值被设为true。在分类问题的数据集标注时,如何不采用独热编码的方式, 类别通常就是一个符号而已,比如说是9。但如果采用独热编码的方式,则每个类表示为一个列表list,共计有10个数值,但只有一个为1,其余均为0。例如,“9”的独热编码可以为[00000 00001]. #定义输入数据x和输出y的形状。函数tf.placeholder的目的是定义输入,可以理解为采用占位符进行占位。 #None这个位置的参数在这里被用于表示样本的个数,而由于样本个数此时具体是多少还无法确定,所以这设为None。而每个输入样本的特征数目是确定的,即为28*28。 input_x = tf.placeholder(tf.float32,[None,28*28])/255 #因为每个像素的取值范围是 0~255 output_y = tf.placeholder(tf.int32,[None,10]) #10表示10个类别 #输入层的输入数据input_x被reshape成四维数据,其中第一维的数据代表了图片数量 input_x_images = tf.reshape(input_x,[-1,28,28,1]) test_x = mnist.test.images[:3000] #读取测试集图片的特征,读取3000个图片 test_y = mnist.test.labels[:3000] #读取测试集图片的标签。就是这3000个图片所对应的标签
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值