tf卷积神经网络CNN进行mnist手写数字识别,dense,conv2d,batch_normalization

对此文内容做了简化和对一个卷积层做了batch_normalization的处理。

batch_normalization:
更有效的在各层间传递数据,加速训练平稳收敛。
训练时training设置true,测试时设置false。
batch_normalization需要在该层的激活函数之前做。

tf.nn.max_pool(value, ksize, strides, padding, name=None),参考此文

  1. 第一个参数value:需要池化的输入,一般池化层接在卷积层后面,所以输入通常是feature map,依然是[batch,height, width, channels]这样的shape
  2. 第二个参数ksize:池化窗口的大小,取一个四维向量,一般是[1,height, width, 1],因为我们不想在batch和channels上做池化,所以这两个维度设为了1
  3. 第三个参数strides:和卷积类似,窗口在每一个维度上滑动的步长,一般也是[1, stride,stride, 1]
  4. 第四个参数padding:和卷积类似,可以取’VALID’ 或者’SAME’
  5. 返回一个Tensor,类型不变,shape仍然是[batch, height, width, channels]这种形式
import tensorflow.compat.v1 as tf
import tensorflow as tf2

tf.disable_v2_behavior()
import numpy as np
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt


def max_pool_2x2(x):        #x:输入的数据
    return tf.nn.max_pool(x,ksize=[1,2,2,1],strides=[1,2,2,1],padding="SAME")

def model(x_data, y_data):
    global pred, xs, ys, keep_prob,is_train_
    # 保存和记载模型时,需要使用placeholder的name属性
    xs = tf.placeholder(tf2.float32, [None, x_data.shape[-1]], name='input_xs')
    ys = tf.placeholder(tf2.float32, [None, 10], name='input_ys')
    keep_prob = tf.placeholder(tf.float32, name='input_kp')
    is_train_=tf.placeholder(tf2.bool, name='is_train')

    x_image = tf2.reshape(xs, [-1, 28, 28, 1])

    #strides默认值(1, 1),也可写成activation=tf.nn.relu
    # 卷积层输出28,28,32
    Conv1=tf.keras.layers.Conv2D(filters=32,kernel_size=(5,5),activation="relu",padding="SAME")
    # 池化层输出14,14,32
    res = max_pool_2x2(Conv1(x_image))

    # 卷积层输出14,14,64
    Conv2=tf.keras.layers.Conv2D(filters=64,kernel_size=(5,5),padding="SAME")
    res=Conv2(res)
    #axis指定channel的所在维度,如图片数据指定rgb的维度,卷积后的数据指定卷积的个数的维度
    res=tf.layers.batch_normalization(res, training=is_train_,axis=-1)
    res=tf.nn.relu(res)
    # 池化层输出7,7,64
    res = max_pool_2x2(res)

    res=tf.reshape(res, [-1, 7 * 7 * 64])
    
    # 全连接层输出1024
    res=tf.layers.dense(res,1024,activation=tf2.nn.relu)
    res= tf.nn.dropout(res, keep_prob)
    # 全连接层输出10
    pred=tf.layers.dense(res,10,activation=tf2.nn.softmax)

    return pred


def run(x_data, y_data):
    pred = model(x_data, y_data)
    cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(tf.clip_by_value(pred, 1e-10, 1.0)), reduction_indices=1))

    train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

    se.run(tf.global_variables_initializer())

    results = []
    for i in range(1000):
        # 随机取数据进行训练
        random_index = np.random.choice(x_train.shape[0], 10, replace=False)
        batch_xs, batch_ys = x_train[random_index], y_train[random_index]

        se.run(train_step, feed_dict={xs: batch_xs, ys: batch_ys, keep_prob: .5,is_train_:True})

        if i % 50 == 0:
            acc = compute_accuracy(x_test, y_test, 1)
            results.append(acc)
            print(i, acc)

    plt.plot([50 * i for i in range(len(results))], results)
    y_major_locator = plt.MultipleLocator(.1)
    ax = plt.gca()
    ax.yaxis.set_major_locator(y_major_locator)
    plt.ylim(0, 1)
    plt.show()


def compute_accuracy(v_xs, v_ys, v_kp=1):
    y_pre = se.run(pred, feed_dict={xs: v_xs, keep_prob: 1,is_train_:False})
    correct_pred = tf.equal(tf.argmax(y_pre, 1), tf.argmax(v_ys, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_pred, tf2.float32), name='acc_')
    result = se.run(accuracy, feed_dict={xs: v_xs, ys: v_ys, keep_prob: 1,is_train_:False})
    return result



if __name__ == "__main__":
    (x_train, y_train), (x_test, y_test) = mnist.load_data()
    mym = mnist.load_data()

    x_train = x_train.reshape(x_train.shape[0], -1) / 255
    x_test = x_test.reshape(x_test.shape[0], -1) / 255
    se = tf.Session()

    y_train = np.eye(10)[y_train]
    y_test = np.eye(10)[y_test]

    run(x_test, y_test)

你可能感兴趣的:(python,机器学习,tf)