Tensorflow——nn、cnn、rnn玩mnist

前言

代码中文注释还算齐全,直接阅读源码即可!

基于神经网络mnist数字识别

# coding=utf-8

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

""""双层神经网络实现mnist"""

mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

# 定义网络维度
dim_input = 784
neural_num_hidden_1 = 256
neural_num_hidden_2 = 128
dim_output = 10

# 定义数据集输入以及ground truth
x_data = tf.placeholder(tf.float32, [None, dim_input])  # 样本个数不确定,所以为None
y_real = tf.placeholder(tf.float32, [None, dim_output])

# 搭建网络模型
stddev = 0.1
weights = {"w1": tf.Variable(tf.random_normal([dim_input, neural_num_hidden_1], stddev=stddev)),
           "w2": tf.Variable(tf.random_normal([neural_num_hidden_1, neural_num_hidden_2], stddev=stddev)),
           "w_out": tf.Variable(tf.random_normal([neural_num_hidden_2, dim_output], stddev=stddev))}
biases = {"b1": tf.Variable(tf.zeros([neural_num_hidden_1])),
          "b2": tf.Variable(tf.zeros([neural_num_hidden_2])),
          "b_out": tf.Variable(tf.zeros([dim_output]))}

print("网络参数:", weights, biases)


def forward_prop(X_input, _weights, _biases):
    """
    通过网络前向传播预测
    :param X_input: 输入
    :param _weights: 权重
    :param _biases: 偏置
    """
    layer_1 = tf.nn.relu(tf.add(tf.matmul(X_input, _weights["w1"]), _biases["b1"]))
    layer_2 = tf.nn.relu(tf.add(tf.matmul(layer_1, _weights["w2"]), _biases["b2"]))
    return tf.add(tf.matmul(layer_2, _weights["w_out"]), _biases["b_out"])


y_pred = forward_prop(x_data, weights, biases)  # 预测值

# 定义loss函数以及优化器
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y_pred, labels=y_real))
op = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss=loss)

# 定义准确率
correct = tf.equal(tf.arg_max(y_pred, 1), tf.arg_max(y_real, 1))  # 计算出预测值与真实值是否相等(独热码为1的索引是否相等)
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))  # 每个batch的平均准确率 将True转成float

# 训练参数
training_epoch = 100
batch_size = 128
display_step = 2  # 设置打印间隔

# =========《准备训练测试》==========
init = tf.global_variables_initializer()

total_batch = mnist.train.num_examples // batch_size  # 计算batch数量取整
print("共有%d个batch,每个batch大小为:%d" % (total_batch, batch_size))

with tf.Session() as sess:
    sess.run(init)

    for epoch in range(training_epoch):
        avg_loss = 0  # 储存所有batch平均loss值

        for i_batch in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            feed_dict = {x_data: batch_xs, y_real: batch_ys}
            sess.run(op, feed_dict=feed_dict)  # 不断的进行优化
            avg_loss += sess.run(loss, feed_dict=feed_dict)

        avg_loss = avg_loss / total_batch

        # 打印
        if epoch % display_step == 0:
            print("Epoch:%3d/%3d, loss:%.6f" % (epoch, training_epoch, avg_loss))

            feed_dict = {x_data: batch_xs, y_real: batch_ys}
            train_accuracy = sess.run(accuracy, feed_dict=feed_dict)
            print("训练准确率:%.6f" % train_accuracy)

            feed_dict = {x_data: mnist.test.images, y_real: mnist.test.labels}
            test_accuracy = sess.run(accuracy, feed_dict=feed_dict)
            print("测试准确率:%.6f" % test_accuracy)

    print("结束!")

基于CNN的mnist数字识别

# coding=utf-8

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

""""VGG-style卷积神经网络实现mnist"""

# 读取数据
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
train_img = mnist.train.images
train_lab = mnist.train.labels
test_img = mnist.test.images
test_lab = mnist.test.labels

# 定义网络维度参数
dim_input = 784
dim_output = 10

# 定义数据集输入以及ground truth
x_data = tf.placeholder(tf.float32, [None, dim_input])  # 样本个数不确定,所以为None
y_real = tf.placeholder(tf.float32, [None, dim_output])

stddev = 0.1
weights = {"w_conv1": tf.Variable(tf.random_normal([3, 3, 1, 64], stddev=stddev)),
           "w_conv2": tf.Variable(tf.random_normal([3, 3, 64, 128], stddev=stddev)),
           "w_fc1": tf.Variable(tf.random_normal([7 * 7 * 128, 1024], stddev=stddev)),
           "w_fc2": tf.Variable(tf.random_normal([1024, dim_output], stddev=stddev))}

biases = {"b_conv1": tf.Variable(tf.zeros([64])),
          "b_conv2": tf.Variable(tf.zeros([128])),
          "b_fc1": tf.Variable(tf.zeros([1024])),
          "b_fc2": tf.Variable(tf.zeros([dim_output]))}


def forward_prop(_input, _w, _b, keep_prob):
    """
    搭建网络模型
    :param _input:
    :param _w:
    :param _b:
    :param keep_prob:
    """
    # 输入reshape
    _input_r = tf.reshape(_input, shape=[-1, 28, 28, 1])
    # 第一层卷积层
    _conv1 = tf.nn.conv2d(_input_r, _w["w_conv1"], strides=[1, 1, 1, 1], padding="SAME")
    _conv1 = tf.nn.relu(tf.nn.bias_add(_conv1, _b["b_conv1"]))
    # 池化层
    _pool1 = tf.nn.max_pool(_conv1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
    # dropout
    _pool_dr1 = tf.nn.dropout(_pool1, keep_prob=keep_prob)

    # 第二层卷积层
    _conv2 = tf.nn.conv2d(_pool_dr1, _w["w_conv2"], strides=[1, 1, 1, 1], padding="SAME")
    _conv2 = tf.nn.relu(tf.nn.bias_add(_conv2, _b["b_conv2"]))
    _pool2 = tf.nn.max_pool(_conv2, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding="SAME")
    _pool_dr2 = tf.nn.dropout(_pool2, keep_prob=keep_prob)

    # flatten
    flatten = tf.reshape(_pool_dr2, shape=[-1, _w["w_fc1"].get_shape().as_list()[0]])

    # 第一层全连接层
    _fc1 = tf.nn.relu(tf.add(tf.matmul(flatten, _w["w_fc1"]), _b["b_fc1"]))
    # dropout
    _fc_dr1 = tf.nn.dropout(_fc1, keep_prob=keep_prob)

    # 第二层全连接层
    _out = tf.nn.relu(tf.add(tf.matmul(_fc_dr1, _w["w_fc2"]), _b["b_fc2"]))

    return {"input_r": _input_r, "conv1": _conv1, "pool1": _pool1, "pool_dr1": _pool_dr1, "conv2": _conv2,
            "pool2": _pool2, "pool_dr2": _pool_dr2, "flatten": flatten, "fc1": _fc1, "fc_dr1": _fc_dr1, "out": _out}


keep_prob = tf.placeholder(tf.float32)  # droupout

y_pred = forward_prop(x_data, weights, biases, keep_prob)["out"]
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y_pred, labels=y_real))
op = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss)

# 定义准确率
correct = tf.equal(tf.arg_max(y_pred, 1), tf.arg_max(y_real, 1))  # 计算出预测值与真实值是否相等(独热码为1的索引是否相等)
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))  # 每个batch的平均准确率 将True转成float

# 训练参数
training_epoch = 100
batch_size = 128
display_step = 2  # 设置打印间隔

# =========《准备训练测试》==========
init = tf.global_variables_initializer()

total_batch = mnist.train.num_examples // batch_size  # 计算batch数量取整
print("共有%d个batch,每个batch大小为:%d" % (total_batch, batch_size))

saver = tf.train.Saver(max_to_keep=2)
is_training = False

with tf.Session() as sess:
    sess.run(init)

    if is_training:
        for epoch in range(training_epoch):
            avg_loss = 0  # 储存所有batch平均loss值

            for i_batch in range(total_batch):
                batch_xs, batch_ys = mnist.train.next_batch(batch_size)
                feed_dict = {x_data: batch_xs, y_real: batch_ys, keep_prob: 0.5}
                sess.run(op, feed_dict=feed_dict)  # 不断的进行优化
                avg_loss += sess.run(loss, feed_dict=feed_dict)

            avg_loss = avg_loss / total_batch

            # 打印
            if epoch % display_step == 0:
                print("Epoch:%3d/%3d, loss:%.6f" % (epoch, training_epoch, avg_loss))

                feed_dict = {x_data: batch_xs, y_real: batch_ys, keep_prob: 0.5}
                train_accuracy = sess.run(accuracy, feed_dict=feed_dict)
                print("训练准确率:%.6f" % train_accuracy)

                # feed_dict = {x_data: mnist.test.images, y_real: mnist.test.labels, keep_prob: 1.0}
                # test_accuracy = sess.run(accuracy, feed_dict=feed_dict)
                # print("测试准确率:%.6f" % test_accuracy)

                saver.save(sess, "MNIST_model/model.ckpt-" + str(epoch))
    else:
        saver.restore(sess, tf.train.latest_checkpoint(checkpoint_dir="MNIST_model/"))
        feed_dict = {x_data: mnist.test.images, y_real: mnist.test.labels, keep_prob: 1.0}
        test_accuracy = sess.run(accuracy, feed_dict=feed_dict)
        print("测试准确率:%.6f" % test_accuracy)

    print("结束!")

基于RNN的mnist数字识别

# coding=utf-8

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

"""RNN-LSTM卷积神经网络实现mnist"""

# 读取数据
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
train_imgs = mnist.train.images
train_labs = mnist.train.labels
test_imgs = mnist.test.images
test_labs = mnist.test.labels

num_train = train_imgs.shape[0]  # 训练集个数
num_test = test_imgs.shape[0]  # 测试集个数
dim = train_imgs.shape[1]  # 单张图片维度28*28
num_classes = train_labs.shape[1]  # 类别

# 定义网络维度
dim_input = 28  # 输入为1*28
dim_hidden = 128  # 隐层维度为128
dim_output = num_classes  # 输出维度1*10
num_steps = 28  # 将一张图拆成28个1*28输入

# 定义数据集输入以及ground truth
x_data = tf.placeholder(tf.float32, [None, num_steps, dim_input])  # 样本个数不确定,所以为None
y_real = tf.placeholder(tf.float32, [None, dim_output])

# 权重参数
stddev = 0.1
weights = {"hidden": tf.Variable(tf.random_normal([dim_input, dim_hidden], stddev=stddev)),
           "out": tf.Variable(tf.random_normal([dim_hidden, dim_output], stddev=stddev))}
biases = {"hidden": tf.Variable(tf.zeros([dim_hidden])), "out": tf.Variable(tf.zeros([dim_output]))}


def RNN_network(_X, _W, _b, _num_steps, _name):
    """
    RNN-lstm 网络结构
    :param _X:
    :param _W:
    :param _b:
    :param _num_steps:
    :param _name:
    :return:
    """
    # 1. 对输入进行转换
    # -1.1 将[batch_size, num_steps, dim_input]转换成[num_steps, batch_size, dim_input]
    _X = tf.transpose(_X, perm=[1, 0, 2])
    # -1.2 再将[num_steps, batch_size, dim_input]转换成[num_steps*batch_size, dim_input]
    _X = tf.reshape(_X, [-1, dim_input])

    # 2. 通过隐层
    _H = tf.add(tf.matmul(_X, _W["hidden"]), _b["hidden"])

    # 3. 隐层输出进行切分
    _H_split = tf.split(value=_H, num_or_size_splits=num_steps, axis=0)

    # 4. 获得LSTM的输出(LSTM_0)和状态(LSTM_S)
    with tf.variable_scope(_name, reuse=tf.AUTO_REUSE):  # 指定scope
        lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(dim_hidden, forget_bias=1.0)
        _LSTM_0, _LSTM_S = tf.nn.static_rnn(lstm_cell, _H_split, dtype=tf.float32)

    # 5. 输出
    _O = tf.add(tf.matmul(_LSTM_0[-1], _W["out"]), _b["out"])  # 取最后一个_LSTM_0经过神经元

    return {"X": _X, "H": _H, "H_split": _H_split, "LSTM_0": _LSTM_0, "LSTM_S": _LSTM_S, "OUT": _O}


y_pred = RNN_network(x_data, weights, biases, num_steps, "basic")["OUT"]

# 定义loss函数以及优化器
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y_pred, labels=y_real))
op = tf.train.GradientDescentOptimizer(learning_rate=0.001).minimize(loss)

# 定义准确率
correct = tf.equal(tf.arg_max(y_pred, 1), tf.arg_max(y_real, 1))  # 计算出预测值与真实值是否相等(独热码为1的索引是否相等)
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))  # 每个batch的平均准确率 将True转成float

# 训练参数
training_epoch = 100
batch_size = 64
display_step = 2  # 设置打印间隔

# =========《准备训练测试》==========
init = tf.global_variables_initializer()

total_batch = mnist.train.num_examples // batch_size  # 计算batch数量取整
print("共有%d个batch,每个batch大小为:%d" % (total_batch, batch_size))

with tf.Session() as sess:
    sess.run(init)

    for epoch in range(training_epoch):
        avg_loss = 0  # 储存所有batch平均loss值

        for i_batch in range(total_batch):
            batch_xs, batch_ys = mnist.train.next_batch(batch_size)
            batch_xs = batch_xs.reshape(batch_size, num_steps, dim_input)
            feed_dict = {x_data: batch_xs, y_real: batch_ys}
            sess.run(op, feed_dict=feed_dict)  # 不断的进行优化
            avg_loss += sess.run(loss, feed_dict=feed_dict)

        avg_loss = avg_loss / total_batch

        # 打印
        if epoch % display_step == 0:
            print("Epoch:%3d/%3d, loss:%.6f" % (epoch, training_epoch, avg_loss))

            feed_dict = {x_data: batch_xs, y_real: batch_ys}
            train_accuracy = sess.run(accuracy, feed_dict=feed_dict)
            print("训练准确率:%.6f" % train_accuracy)

            test_imgs = test_imgs.reshape(num_test, num_steps, dim_input)
            feed_dict = {x_data: test_imgs, y_real: mnist.test.labels}
            test_accuracy = sess.run(accuracy, feed_dict=feed_dict)
            print("测试准确率:%.6f" % test_accuracy)

结果

  1. nn-mnist

    ...
    Epoch: 90/100, loss:0.229778
    训练准确率:0.921875
    测试准确率:0.937500
    Epoch: 92/100, loss:0.227928
    训练准确率:0.929688
    测试准确率:0.938000
    Epoch: 94/100, loss:0.223730
    训练准确率:0.929688
    测试准确率:0.938200
    Epoch: 96/100, loss:0.221924
    训练准确率:0.945312
    测试准确率:0.938500
    Epoch: 98/100, loss:0.221472
    训练准确率:0.953125
    测试准确率:0.938700
    结束!
  2. cnn-mnist

    Epoch: 90/100, loss:0.403413
    训练准确率:0.875000
    测试准确率:0.955900
    Epoch: 92/100, loss:0.396546
    训练准确率:0.828125
    测试准确率:0.956800
    Epoch: 94/100, loss:0.382558
    训练准确率:0.929688
    测试准确率:0.956900
    Epoch: 96/100, loss:0.384647
    训练准确率:0.835938
    测试准确率:0.958100
    Epoch: 98/100, loss:0.385285
    训练准确率:0.921875
    测试准确率:0.957600
    结束!
  3. rnn-mnist

    Epoch: 90/100, loss:0.068436
    训练准确率:1.000000
    测试准确率:0.969900
    Epoch: 92/100, loss:0.067309
    训练准确率:1.000000
    测试准确率:0.965800
    Epoch: 94/100, loss:0.065066
    训练准确率:0.984375
    测试准确率:0.970100
    Epoch: 96/100, loss:0.064390
    训练准确率:1.000000
    测试准确率:0.968700
    Epoch: 98/100, loss:0.061638
    训练准确率:0.984375
    测试准确率:0.972000

猜你喜欢

转载自blog.csdn.net/bskfnvjtlyzmv867/article/details/79890933