在MNIST数据集上用Tensorflow实现AlexNet

在MNIST数据集上用Tensorflow实现AlexNet

  • 前言
  • 需要下载的东西(数据和代码)
  • 代码讲解

前言

MNIST是一个被广泛使用的数据集,科研领域中也时常使用到它。

MNIST数据集,是一个在科研界都被广泛使用的数据集,其由Yann LeCun, Courant Institute, NYU、Corinna Cortes, Google Labs, New York和Christopher J.C. Burges, Microsoft Research, Redmond共同维护,该数据集比较适合用来练习卷积神经网络以及其它各种神经网络,官网网址为:MNIST官网,上面有不同文章不同算法得到的对于MNIST的最优的结果。

若想看更为基础的在MNIST数据集上用Tensorflow实现多层神经网络算法,请点击右侧超链接:请点我。

该代码是AlexNet神经网络用于MNIST数据集的一个复现,其中对应于MNIST,调整了一些参数使得网络性能更好,若想了解AlexNet,请点击:AlexNet论文解说博客

全连接层层都加入了dropout,若想了解dropout,请点击dropout解说博客

下述代码中除了缩减了卷积的通道数和卷积核的大小外,还将原文使用的带动量的小批量梯度下降算法给换成了RMSProp算法,由于技术问题,还不会往里面增加原文中的权重衰减。全连接层方面由于输出只有10个类别,因此将全连接层从原始AlexNet的4096变成了1024。

需要下载的东西(数据和代码)

训练集、测试集以及相关代码都在如下的百度云盘中:

链接:https://pan.baidu.com/s/1vC9SjqwaDr9dYg6W9ZVwxA 
提取码:5o92 

代码讲解

首先先导入必要的库

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

import tensorflow as tf
import numpy as np

调参时固定随机种子

# 调参时固定随机种子
seed = 1
tf.set_random_seed(seed)
np.random.seed(seed) 

定义权值和偏差的函数

#权值和偏差
# 定义变量函数 (weights and bias)
def init_weight(shape, st_dev):
    weight = tf.Variable(tf.truncated_normal(shape, stddev=st_dev))
    return(weight)
    

def init_bias(shape, st_dev):
    bias = tf.Variable(tf.truncated_normal(shape, stddev=st_dev))
    return(bias)

创建输入数据的占位符(placeholder)

# 创建输入数据的占位符(placeholder)
x_data = tf.placeholder(shape=[None, 784], dtype=tf.float32)
y_target = tf.placeholder(shape=[None, 10], dtype=tf.float32)

预处理数据集以使其维度匹配

# 预处理数据集以使其维度匹配
x_image = tf.reshape(x_data,[-1,28,28,1])

构建3层卷积加2层全连接层的神经网络

# 构建AlexNet
p_keep_hidden=tf.placeholder('float')
rand_st_dev=0.01

w=init_weight([3,3,1,32], st_dev=rand_st_dev)
w2=init_weight([3,3,32,64], st_dev=rand_st_dev)
w3=init_weight([3,3,64,128], st_dev=rand_st_dev)
w4=init_weight([1,1,128,128], st_dev=rand_st_dev)
w5=init_weight([1,1,128,64], st_dev=rand_st_dev)
w6=init_weight([64*4*4,64*4*4], st_dev=rand_st_dev)
w7=init_weight([64*4*4,1024], st_dev=rand_st_dev)
w_o=init_weight([1024,10], st_dev=rand_st_dev)

#定义第一组卷积层和池化层,最后dropout掉一些神经元
l1a=tf.nn.relu(tf.nn.conv2d(x_image,w,strides=[1,1,1,1],padding='SAME'))
l1=tf.nn.max_pool(l1a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
    
#定义第二组卷积层和池化层,最后dropout掉一些神经元
l2a=tf.nn.relu(tf.nn.conv2d(l1,w2,strides=[1,1,1,1],padding='SAME'))
l2=tf.nn.max_pool(l2a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')

#定义第三组卷积层和池化层,最后dropout掉一些神经元
l3=tf.nn.relu(tf.nn.conv2d(l2,w3,strides=[1,1,1,1],padding='SAME'))

#定义第四组卷积层和池化层,最后dropout掉一些神经元
l4=tf.nn.relu(tf.nn.conv2d(l3,w4,strides=[1,1,1,1],padding='SAME'))  
  
#定义第五组卷积层和池化层,最后dropout掉一些神经元
l5a=tf.nn.relu(tf.nn.conv2d(l4,w5,strides=[1,1,1,1],padding='SAME'))
l5=tf.nn.max_pool(l5a,ksize=[1,2,2,1],strides=[1,2,2,1],padding='SAME')
l5=tf.reshape(l5,[-1,w6.get_shape().as_list()[0]])

    
#第一个全连接层,最后dropout掉一些神经元
l6=tf.nn.relu(tf.matmul(l5,w6))
l6=tf.nn.dropout(l6,p_keep_hidden)

#第二个全连接层,最后dropout掉一些神经元
l7=tf.nn.relu(tf.matmul(l6,w7))
l7=tf.nn.dropout(l7,p_keep_hidden)
    
#输出层
final_output=tf.matmul(l7,w_o)

loss=tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=final_output,labels=y_target))
train_step=tf.train.RMSPropOptimizer(0.001,0.9).minimize(loss)


y = tf.nn.softmax(final_output)

定义计算准确度的op

# 定义计算准确度的op
correct_prediction_op = tf.equal(tf.argmax(y,1), tf.argmax(y_target,1))
accuracy_op=tf.reduce_mean(tf.cast(correct_prediction_op, tf.float32))

初始化变量

# Session
sess = tf.InteractiveSession()

#初始化变量
tf.global_variables_initializer().run()

训练模型,训练10000次

#训练模型,训练20000次
for i in range(20000):
    batch_xs, batch_ys = mnist.train.next_batch(128)
    sess.run(train_step, feed_dict={x_data: batch_xs, y_target: batch_ys,
                                  p_keep_hidden:0.5})
    
## 显存不够用时请使用这段被注释的代码代替下方的正确率计算代码
#    if (i+1)%1000==0:
#        # 计算测试集的正确率
#        accuracy_sum=0;
#        # 为了限制显存的使用,因此将测试集也分为小批次来计算然后求和再求平均
#        for j in range(50):
#            batch_xs_test, batch_ys_test = mnist.test.next_batch(200)
#            accuracy = sess.run(accuracy_op,feed_dict={x_data: batch_xs_test,
#                                                 y_target: batch_ys_test,
#                                                 p_keep_hidden:1.0})
#            accuracy_sum=accuracy_sum+accuracy
#    
#        accuracy_sum=accuracy_sum/(j+1)
#        print("第"+str(i)+"次迭代时,在测试集上的准确率为:"+str(accuracy_sum))


    if (i+1)%1000==0: 
        # 计算测试集的正确率
        accuracy = sess.run(accuracy_op,feed_dict={x_data: mnist.test.images,
                                                   y_target: mnist.test.labels,
                                                   p_keep_hidden:1.0})
        print("第"+str(i)+"次迭代时,在测试集上的准确率为:"+str(accuracy))
        
sess.close()

结果输出如下所示:
在MNIST数据集上用Tensorflow实现AlexNet_第1张图片
最好的结果出现在第8999次迭代时,此时在测试集上的准确率为:0.9924,即 99.24 % 99.24\% 99.24%

你可能感兴趣的:(AlexNet,卷积神经网络,MNIST)