在上一篇博客中,我们实现了一层神经网络,现在,我们将通过TensorFlow实现两层神经网络;添加一个隐藏层到网络,让它建模更复杂的功能。而且隐藏层上使用非线性激活函数可以模拟非线性函数。

使用Relu在隐藏层作为激活函数,形成多层网络,如下图:

深度学习 之四 【TensorFlow 两层神经网络】_tensorflow

那么,这个隐藏层激活函数,我们就使用 ​​ReLu​​​ ,Relu是​​非线性激活函数​​​,又称作​​修正线性单元​​​,Relu对于所有的负的输入,返回0,大于等于0的输入返回自己。
如下公式:

深度学习 之四 【TensorFlow 两层神经网络】_神经网络_02

TensorFlow提供了Relu的函数 ​​tf.nn.relu()​​,如:

# 隐藏层用 ReLU 作为激活函数
hidden_layer = tf.add(tf.matmul(features, hidden_weights), hidden_biases)
hidden_layer = tf.nn.relu(hidden_layer)

output = tf.add(tf.matmul(hidden_layer, output_weights), output_biases)

上面的代码使用​​tf.nn.relu()​​,把负权重关掉了,就像开关一样。在激活函数运行后,添加输出层,就把模型变成了非线性函数。这个非线性的特征可以使网络解决更复杂的问题。

【深度神经网络】


深度学习 之四 【TensorFlow 两层神经网络】_tensorflow_03

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

from tqdm import tqdm
import math


# 1.加载mnist数据,该数据集已经把分批和one-hot encoding处理好了
mnist = input_data.read_data_sets(".", one_hot=True, reshape=False)


# 2.设置一些必要的参数
learning_rate = 0.5 # 定义学习率
training_epochs = 30 # 定义要训练的次数
batch_size = 128 # 分批,每批大小128张图

n_input = 784 # 数据集里是图片,图片大小是 28 * 28
n_classes = 10 # 所有的数据集都是,0 - 9的数字,所有就10个类别

n_hidden_layer = 256 # 神经网络隐藏层的大小,特征的层数,也称作层的宽度


# 神经网络每一层都有自己的权重和偏置项,如果神经网络比这更深,那每一层都有权重和偏置项。
# 层权重和偏置项的储存
weights = {
'hidden_layer': tf.Variable(tf.random_normal([n_input, n_hidden_layer])),
'out': tf.Variable(tf.random_normal([n_hidden_layer, n_classes]))
}
biases = {
'hidden_layer': tf.Variable(tf.random_normal([n_hidden_layer])),
'out': tf.Variable(tf.random_normal([n_classes]))
}

# 3.创建输入
x = tf.placeholder(tf.float32, [None, 28, 28, 1])
y = tf.placeholder(tf.float32, [None, n_classes])

# MNIST数据集是由 28px * 28px 的单通道图片组成。tf.reshape()函数就把 28px * 28px 的矩阵转换成了 784px * 1px的单行向量的x
x_flat = tf.reshape(x, [-1, n_input])


# 4.两层神经网络
# 我们之前见过 xW + b 的线性函数,这就是一层,再把这个线性函数和ReLU组合到一起,就形成了两层神经网络
layer_1 = tf.add(tf.matmul(x_flat, weights["hidden_layer"]), biases["hidden_layer"])
# ReLu作为隐藏层的激活函数来输出预测值
output_prediction = tf.nn.relu(layer_1)

# 计算输出层的线性激活函数 logit score
logits = tf.add(tf.matmul(output_prediction, weights["out"]), biases["out"])

# 定义误差值
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=y))

# 定义优化器
optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(cost)

# 评估模型 Evaluate the Model
# output_prediction是否是正确的,用 predicted value 和 target value 作比较,
# 返回的是一组Boolean列表,如:[True, False, True, True]
is_correct_prediction = tf.equal(tf.argmax(output_prediction, 1), tf.argmax(y, 1))

# 计算accuracy,通过reduce_mean()函数将这组布尔列表转成[1,0,1,1],再求均值
accuracy = tf.reduce_mean(tf.cast(is_correct_prediction, tf.float32))



# 5.训练神经网络
init_variables = tf.global_variables_initializer()

log_batch_step = 50

with tf.Session() as session:

# 初始化全局变量
session.run(init_variables)

# 分了 total_batch 个批次
total_batch = int(math.ceil(mnist.train.num_examples / batch_size))

# 训练epochs此数据
for epoch in range(training_epochs):

# 进度条
batches_pbar = tqdm(range(total_batch), desc='Epoch {:>2}/{}'.format(epoch+1, training_epochs), unit='batches')

for batch_i in batches_pbar:

# 此函数返回了训练数据的一个子集
batch_x, batch_y = mnist.train.next_batch(batch_size)

# 运行优化器进行反向传播,计算cost(也就是获取loss值)
loss = session.run(optimizer, feed_dict={x: batch_x, y: batch_y})

# Log every 50 batches
if not batch_i % log_batch_step:
print(accuracy.eval(feed_dict={x: mnist.test.images, y: mnist.test.labels}))

参考:
Advanced MNIST Tutorial: ​​​https://www.tensorflow.org/versions/r1.0/get_started/mnist/pros​​​
Beginner MNIST Tutorial: ​​​https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist_softmax.py​