TensorFlow实战:多层感知机

首先,载入TensorFlow并加载MNIST数据集,创建一个TensorFlow默认的Interactive Session,这样后面执行各项操作就无须指定Session了。

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

mnist = input_data.read_data_sets("MNIST_data/", one_hot = True)
#创建一个IntercativeSession,这样后面的操作就无需指定Session
sess = tf.InteractiveSession()

接下来我们要给隐含层的参数设置Variable并进行初始化,这里in_units是输入节点数,h1_units即隐含层的输出节点数设为300(在此模型中隐含节点数设在200~1000范围内的区别都不大)。W1、并是隐含层的权重和偏置,我们将偏置全部赋值为0,并将权重初始化为截断的正态分布,其标准差为0.1,这一步可以通过tf.truncated_normal方便地实现。因为模型使用的激活函数是ReLU,所以需要使用正态分布给参数加一点噪声,来打破完全对称并且避免0梯度。在其他一些模型中,有时还需要给偏置加上一些小的非零值来避免dead neuron(死亡神经元),不过在这里作用不太明显。而对最后输出层的softmax,直接将权重w2和偏置b2全部初始化为0即可(对于Sigmoid在0附近最敏感、梯度最大)。

#隐含层输出节点设置为300,(在此模型中隐含节点数设在200~1000结果区别不大)
in_units = 784
h1_units = 300
#利用tf.truncated_normal实现截断的正态分布,其标准差为0.1 [-1, 784]x[784, 300]
w1 = tf.Variable(tf.truncated_normal([in_units, h1_units], stddev=0.1))
b1 = tf.Variable(tf.zeros([h1_units]))
#[784, 300]x[300, 10]
w2 = tf.Variable(tf.zeros([h1_units, 10]))
b2 = tf.Variable(tf.zeros([10]))

接下来定义输入的x的placeholder。另外因为在训练和预测时,Dropout的比率keep_prob(即保留节点的概率)是不一样的,通常在训练时小于1,而预测时则等于1,所以也把Dropout的比率作为计算图的输入,并定义成一个placeholder。

#定义输入x,Dropout的比率keep_prob(通常在训练时小于1,而预测时等于1)
x = tf.placeholder(tf.float32, [None, in_units])
keep_prob = tf.placeholder(tf.float32)

下面定义模型结构。首先需要一个隐含层,命名为hidden1,可以通过tf.nn.relu(tf.matmul(x,w1)+b1)实现一个激活函数为ReLU的隐含层,这个隐含层的计算公式就是y=relu(w1x+b1)。接下来,调用tf.nn.dropout实现Dropout的功能,即随机将一部分节点置为0,这里的keep_prob参数机为保留数据而部置为0的比例,在训练时应该是小于1的,用以制造随机性,防止过拟合;在预测时应该等于1,即用全部特征来预测样本的类别。最后是输出层(softmax)。

第1步:定义算法公式,即神经网络forward时的计算。

#hidden1:隐含层 y = relu(W1*x+b1)
hidden1 = tf.nn.relu(tf.matmul(x, w1) + b1)
'''调用tf.nn.dropout实现Dropout,keep_prob在训练时小于1,用于制造随机性,防止过拟合;
在预测时等于1,即使用全部特征来预测样本类别'''
hidden1_drop = tf.nn.dropout(hidden1, keep_prob)

#prediction
y = tf.nn.softmax(tf.matmul(hidden1_drop, w2)+b2)

第2步:定义损失函数和选择优化器来优化loss,这里的损失函数继续使用交叉信息熵,和之前一致,但是优化器选择自适应的优化器Adagrad,并把学习率设为0.3,这里我们直接使用tf.train.AdagradOptimizer就可以了。

y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y), reduction_indices=[1]))
trian_step = tf.train.AdagradOptimizer(0.3).minimize(cross_entropy)

第3步:训练。这里和之前有一点不同,我们加入了keep_prob作为计算图的输入,并且在训练时设为0.75,即保留75%的节点,其余的25%置为0,一般来说,对越复杂越大规模的神经网络,Dropout的效果越显著。另外因为加入了隐含层,我们需要更多的训练迭代来优化模型参数以达到一个比较好的效果。所以一共采用了3000个batch,每个batch包含100条样本,一共30万的样本,相当于是对全数据集进行了5轮(epoch)迭代。

tf.global_variables_initializer().run()

for i in range(3000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    trian_step.run({x: batch_xs, y_: batch_ys, keep_prob: 0.75})

第4步:对模型进行准确率评测。预测部分设置keep_prob等于1

    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    if i % 500 == 0:
        print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))

完整代码如下:

#多层感知机

#coding = utf-8
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf

mnist = input_data.read_data_sets("MNIST_data/", one_hot = True)
#创建一个IntercativeSession,这样后面的操作就无需指定Session
sess = tf.InteractiveSession()

#隐含层输出节点设置为300,(在此模型中隐含节点数设在200~1000结果区别不大)
in_units = 784
h1_units = 300
#利用tf.truncated_normal实现截断的正态分布,其标准差为0.1 [-1, 784]x[784, 300]
w1 = tf.Variable(tf.truncated_normal([in_units, h1_units], stddev=0.1))
b1 = tf.Variable(tf.zeros([h1_units]))
#[784, 300]x[300, 10]
w2 = tf.Variable(tf.zeros([h1_units, 10]))
b2 = tf.Variable(tf.zeros([10]))

#定义输入x,Dropout的比率keep_prob(通常在训练时小于1,而预测时等于1)
x = tf.placeholder(tf.float32, [None, in_units])
keep_prob = tf.placeholder(tf.float32)

#hidden1:隐含层 y = relu(W1*x+b1)
hidden1 = tf.nn.relu(tf.matmul(x, w1) + b1)
'''调用tf.nn.dropout实现Dropout,keep_prob在训练时小于1,用于制造随机性,防止过拟合;
在预测时等于1,即使用全部特征来预测样本类别'''
hidden1_drop = tf.nn.dropout(hidden1, keep_prob)

#prediction
y = tf.nn.softmax(tf.matmul(hidden1_drop, w2)+b2)

y_ = tf.placeholder(tf.float32, [None, 10])
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y), reduction_indices=[1]))
trian_step = tf.train.AdagradOptimizer(0.3).minimize(cross_entropy)

tf.global_variables_initializer().run()

for i in range(3000):
    batch_xs, batch_ys = mnist.train.next_batch(100)
    trian_step.run({x: batch_xs, y_: batch_ys, keep_prob: 0.75})
    #out correct prediction
    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    if i % 500 == 0:
        print(accuracy.eval({x: mnist.test.images, y_: mnist.test.labels, keep_prob: 1.0}))
最终,我们在测试集上可以达到98%的准确率。

猜你喜欢

转载自blog.csdn.net/qq_33144323/article/details/80794857