• 卷积神经网络手写数字分类



    活动地址:CSDN21天学习挑战赛

    *学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。

    数据集:MNIST由60000个手写体数字的图片组成。

    1.导入tensorflow、matplotlib、random和numpy。然后,导入mnist数据集并进行独热编码。请注意,TensorFlow有一些内置的库来处理MNIST,我们也会用到它们:

    import tensorflow as tf
    import matplotlib.pyplot as plt
    import numpy as np
    import random as ran
    # Import MNIST data
    from tensorflow.examples.tutorials.mnist import input_data
    mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.仔细观察一些数据有助于理解MNIST数据集。了解训练数据集中有多少张图片,测试数据集中有多少张图片。可视化一些数字,以便了解它们是如何表示的。这种输出可以对于识别手写体数字的难度有一种视觉感知,即使是对于人类来说也是如此。

    def train_size(num):
        print ('Total Training Images in Dataset = ' + str(mnist.train.images.shape))
        print ('--------------------------------------------------')
        x_train = mnist.train.images[:num,:]
        print ('x_train Examples Loaded = ' + str(x_train.shape))
        y_train = mnist.train.labels[:num,:]
        print ('y_train Examples Loaded = ' + str(y_train.shape))
        print('')
        return x_train, y_train
    
    def test_size(num):
        print ('Total Test Examples in Dataset = ' + str(mnist.test.images.shape))
        print ('--------------------------------------------------')
        x_test = mnist.test.images[:num,:]
        print ('x_test Examples Loaded = ' + str(x_test.shape))
        y_test = mnist.test.labels[:num,:]
        print ('y_test Examples Loaded = ' + str(y_test.shape))
        return x_test, y_test
    
    def display_digit(num):
        print(y_train[num])
        label = y_train[num].argmax(axis=0)
        image = x_train[num].reshape([28,28])
        plt.title('Example: %d  Label: %d' % (num, label))
        plt.imshow(image, cmap=plt.get_cmap('gray_r'))
        plt.show()
    
    def display_mult_flat(start, stop):
        images = x_train[start].reshape([1,784])
        for i in range(start+1,stop):
            images = np.concatenate((images, x_train[i].reshape([1,784])))
        plt.imshow(images, cmap=plt.get_cmap('gray_r'))
        plt.show()
    
    x_train, y_train = train_size(55000)
    display_digit(ran.randint(0, x_train.shape[0]))
    display_mult_flat(0,400)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    在这里插入图片描述
    3.设置学习参数batch_size和display_step。另外,MNIST图片都是28×28像素,因此设置n_input=784,n_classes=10代表输出数字[0-9],并且dropout概率是0.85,则:

    # Parameters`在这里插入代码片`
    learning_rate = 0.001
    training_iters = 500
    batch_size = 128
    display_step = 10
    # Network Parameters
    n_input = 784 # MNIST data input (img shape: 28*28)
    n_classes = 10 # MNIST total classes (0-9 digits)
    dropout = 0.85 # Dropout, probability to keep units
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.设置TensorFlow计算图的输入。定义两个占位符来存储预测值和真实标签:

    x = tf.placeholder(tf.float32, [None, n_input])
    y = tf.placeholder(tf.float32, [None, n_classes])
    keep_prob = tf.placeholder(tf.float32) 
    
    • 1
    • 2
    • 3

    5.定义一个输入为x,权值为W,偏置为b,给定步幅的卷积层。激活函数是ReLU,padding设定为SAME模式:

    def conv2d(x, W, b, strides=1):
        x = tf.nn.conv2d(x, W, strides=[1, strides, strides, 1], padding='SAME')
        x = tf.nn.bias_add(x, b)
        return tf.nn.relu(x)
    
    • 1
    • 2
    • 3
    • 4

    6.定义一个输入是x的maxpool层,卷积核为ksize并且padding为SAME:

    def maxpool2d(x, k=2):
        return tf.nn.max_pool(x, ksize=[1, k, k, 1], strides=[1, k, k, 1],
                              padding='SAME')
    
    • 1
    • 2
    • 3

    7.定义convnet,其构成是两个卷积层,然后是全连接层,一个dropout层,最后是输出层:

    def conv_net(x, weights, biases, dropout):
        # reshape the input picture
        x = tf.reshape(x, shape=[-1, 28, 28, 1])
    
        # First convolution layer
        conv1 = conv2d(x, weights['wc1'], biases['bc1'])
        # Max Pooling used for downsampling
        conv1 = maxpool2d(conv1, k=2)
    
        # Second convolution layer
        conv2 = conv2d(conv1, weights['wc2'], biases['bc2'])
        # Max Pooling used for downsampling
        conv2 = maxpool2d(conv2, k=2)
    
        # Reshape conv2 output to matcht the input of fully connected layer 
        fc1 = tf.reshape(conv2, [-1, weights['wd1'].get_shape().as_list()[0]])
    
        # Fully connected layer
        fc1 = tf.add(tf.matmul(fc1, weights['wd1']), biases['bd1'])
        fc1 = tf.nn.relu(fc1)
        
        # Dropout
        fc1 = tf.nn.dropout(fc1, dropout)
    
        # Output the class prediction
        out = tf.add(tf.matmul(fc1, weights['out']), biases['out'])
        return out
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    8.定义网络层的权重和偏置。第一个conv层有一个5×5的卷积核,1个输入和32个输出。第二个conv层有一个5×5的卷积核,32个输入和64个输出。全连接层有7×7×64个输入和1024个输出,而第二层有1024个输入和10个输出对应于最后的数字数目。所有的权重和偏置用randon_normal分布完成初始化:

    weights = {
        # 5x5 conv, 1 input, and 32 outputs
        'wc1': tf.Variable(tf.random_normal([5, 5, 1, 32])),
        # 5x5 conv, 32 inputs, and 64 outputs
        'wc2': tf.Variable(tf.random_normal([5, 5, 32, 64])),
        # fully connected, 7*7*64 inputs, and 1024 outputs
        'wd1': tf.Variable(tf.random_normal([7*7*64, 1024])),
        # 1024 inputs, 10 outputs for class digits
        'out': tf.Variable(tf.random_normal([1024, n_classes]))
    }
    
    biases = {
        'bc1': tf.Variable(tf.random_normal([32])),
        'bc2': tf.Variable(tf.random_normal([64])),
        'bd1': tf.Variable(tf.random_normal([1024])),
        'out': tf.Variable(tf.random_normal([n_classes]))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    9.建立一个给定权重和偏置的convnet。定义基于cross_entropy_with_logits的损失函数,并使用Adam优化器进行损失最小化。优化后,计算精度:

    pred = conv_net(x, weights, biases, keep_prob)
    
    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
    optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
    
    correct_prediction = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    
    init = tf.global_variables_initializer()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    10.启动计算图并迭代training_iterats次,其中每次输入batch_size个数据进行优化。请注意,用从mnist数据集分离出的mnist.train数据进行训练。每进行display_step次迭代,会计算当前的精度。最后,在2048个测试图片上计算精度,此时无dropout。

    train_loss = []
    train_acc = []
    test_acc = []
    
    with tf.Session() as sess:
        sess.run(init)
        step = 1
        while step <= training_iters:
            batch_x, batch_y = mnist.train.next_batch(batch_size)
            sess.run(optimizer, feed_dict={x: batch_x, y: batch_y,
                                           keep_prob: dropout})
            if step % display_step == 0:
                loss_train, acc_train = sess.run([cost, accuracy], 
                                                 feed_dict={x: batch_x,
                                                            y: batch_y,
                                                            keep_prob: 1.})
                print "Iter " + str(step) + ", Minibatch Loss= " + \
                      "{:.2f}".format(loss_train) + ", Training Accuracy= " + \
                      "{:.2f}".format(acc_train)
        
                # Calculate accuracy for mnist test images. 
                # Note that in this case no dropout
                acc_test = sess.run(accuracy, 
                                    feed_dict={x: mnist.test.images,
                                          y: mnist.test.labels,
                                          keep_prob: 1.})
        
                print "Testing Accuracy:" + \
                   "{:.2f}".format(acc_train)
        
                train_loss.append(loss_train)
                train_acc.append(acc_train)
                test_acc.append(acc_test)
                
            step += 1
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    画出每次迭代的Softmax损失以及训练和测试的精度:

    eval_indices = range(0, training_iters, display_step)
    # Plot loss over time
    plt.plot(eval_indices, train_loss, 'k-')
    plt.title('Softmax Loss per iteration')
    plt.xlabel('Iteration')
    plt.ylabel('Softmax Loss')
    plt.show()
    # Plot train and test accuracy
    plt.plot(eval_indices, train_acc, 'k-', label='Train Set Accuracy')
    plt.plot(eval_indices, test_acc, 'r--', label='Test Set Accuracy')
    plt.title('Train and Test Accuracy')
    plt.xlabel('Generation')
    plt.ylabel('Accuracy')
    plt.legend(loc='lower right')
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

  • 相关阅读:
    无线蓝牙运动耳机哪个品牌好用、优质的蓝牙无线耳机推荐
    【编程之路】面试必刷TOP101:字符串(83-86,Python实现)
    linux信号相关概念
    深入理解Android音视频同步机制(一)ExoPlayer的avsync逻辑
    C++ Qt 学习(十):Qt 其他技巧
    Vue-07-vue-router路由
    正点原子嵌入式linux驱动开发——Linux内核顶层Makefile详解
    温度对免疫代谢调节和癌症进展的影响
    消失的遗传力的进一步剖分及应用
    Java JSON格式简介说明
  • 原文地址:https://blog.csdn.net/leva345/article/details/126175409