这一节使用TF实现一个多层神经网络模型来对MNIST数据集进行分类,这里我们设计一个含有两个隐藏层的神经网络,在输出部分使用softmax对结果进行预测。

使用高级API实现多层神经网络###

这里我们使用tensorflow.contrib包,这是一个高度封装的包,里面包含了许多类似seq2seq、keras一些实用的方法。

先引入数据

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("./") #自动下载数据到这个目录
X_train = mnist.train.images
X_test = mnist.test.images
y_train = mnist.train.labels.astype("int")
y_test = mnist.test.labels.astype("int")
>>X_train
array([[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
...,
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.],
[ 0., 0., 0., ..., 0., 0., 0.]], dtype=float32)
>>len(X_train)
55000
>>len(X_train[0])
784
>>X_train[0]
array([ 0., 0., 0., ..., 0., 0., 0.], dtype=float32)
>>y_test
array([7, 2, 1, ..., 4, 5, 6])

模型的主要代码

features_cols = tf.contrib.learn.infer_real_valued_columns_from_input(X_train)
dnn_clf = tf.contrib.learn.DNNClassifier(hidden_units=[300,100], n_classes=10, feature_columns=features_cols)
dnn_clf.fit(X_train, y_train, batch_size=50, steps=10000)
from sklearn.metrics import accuracy_score
y_pred = dnn_clf.predict(X_test)
print(accuracy_score(y_test, list(y_pred)))

其中infer_real_valued_columns_from_input这个方法根据名字可以看出,它是根据输入的数据来推算出数据的类型,该例子中features_cols 的值为

[_RealValuedColumn(column_name='', dimension=784, default_value=None, dtype=tf.float32, normalizer=None)],短短几行代码就实现了一个多层神经网络模型。并且可能会发现上面这些与之前介绍的有些不同,不需要对变量进行初始化,不需要创建session,使用起来十分的简单。

使用TF实现多层神经网络###

高度封装的API调用起来固然很爽,但是自己不了解内部的原理使用起来就不是那么的踏实,下面就使用TF实现同样的模型,代码主要分为两部分,构建TF计算流图和执行计算图。希望读者能够对比上面的代码来看接下来的部分。

构建TF计算流图####

首先我们需要根据输入的数据来设定输入的参数,使用的数据集MNIST为28*28的矩阵,整个神经网络包含两个隐藏层

n_inputs = 28 * 28
n_hidden1 = 300
n_hidden2 = 100
n_output = 10
X = tf.placeholder(tf.float32,shape=(None,n_inputs),name='X')
y = tf.placeholder(tf.int64,shape=(None),name='y')#注意数据类型

上面使用占位符的方法来声明模型的输入X和y,需要注意的是占位符的数据类型,在执行阶段,占位符会被输入的数据所替代。接下来我们需要创建模型的两个隐藏层和输出层,两个隐藏使用Relu作为激活函数,输出层使用softmax。每一层需要指定节点的个数。

def neuron_layer(X,n_neurons,name,activation=None):
with tf.name_scope(name):
n_inputs = int(X.get_shape()[1]) #特征个数
stddev = 2 / np.sqrt(n_inputs)
init = tf.truncated_normal((n_inputs,n_neurons),stddev=stddev)
W = tf.Variable(init,name='weight')
b = tf.Variable(tf.zeros([n_neurons]),name='baise')
z = tf.matmul(X,W) + b
if activation == "relu":
return tf.nn.relu(z)
else:
return z

我将逐行的对上面代码进行解释:

  • 1.为了方便在TensorBoard上面查看,每一层的神经网络都创建一个name_scope。这一步是可选操作,如果不需要在TensorBoard查看那就可以忽略掉。
  • 2.根据输入的数据的形状来获取数据的特征个数(第二个维度)
  • 3.接下来的代码是创建权重矩阵W和偏置b,权重W不能使用0进行初始化,这样会导致所有的神经元的输出为0,出现对称失效问题,这里使用truncated normal分布(Gaussian)来初始化权重,
tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)

通过指定均值和标准方差来生成正态分布,抛弃那些大于2倍stddev的值。这样将有助于加快训练速度。在初始化b的时候,每一层只有一个偏置,我们全部设置为0,这样并不会出现对称失效问题。

  • 4.下面的是在每一个神经元中的操作\(y=X·W+b\),使用向量化运算计算输入与权重的和运算
  • 5.最后就是激活函数的选择了

下面我们就开始像搭建积木一样创建我们的神经网络了,每一层的输入为上一层的输出:

with tf.name_scope("dnn"):
hidden1 = neuron_layer(X,n_hidden1,"hidden1",activation="relu")
hidden2 = neuron_layer(hidden1,n_hidden2,"hidden2",activation="relu")
logits = neuron_layer(hidden2,n_output,"output")

上面这一段代码的输出层并没有经过softmax激活函数,这是考虑到后续优化求解原因,在后续工作中单独做处理。上面这段代码就是一个神经网络全连接的简化版本,当然TF的contrib模块也提供了全连接的函数fully_connected

from tensorflow.contrib.layers import fully_connected
with tf.name_scope("dnn"):
hidden1 = fully_connected(X, n_hidden1, scope="hidden1")#激活函数默认为relu
hidden2 = fully_connected(hidden1, n_hidden2, scope="hidden2")
logits = fully_connected(hidden2, n_outputs, scope="outputs",activation_fn=None)

现在,模型已经有了。接下来套路就是设计损失函数,优化损失函数求解参数。输出层softmax输出的为在各个类别上面的得分,损失函数使用交叉熵

\(-\sum{y'}log(y')\)。在这里我们使用TF提供的tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None, labels=None, logits=None, name=None)来计算损失函数,该方法先计算softmax再计算cross entropy,主要有两个参数需要考虑

  • 1.labels:输入的为标签的index,例如本例子有10个类别,取值范围为0-9
  • 2.logits:为输入到softmax激活函数之前的模型的输出

最后再使用reduce_mean()计算loss。

with tf.name_scope("loss"):
xentropy = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=y,logits=logits)#labels允许的数据类型有int32, int64
loss = tf.reduce_mean(xentropy,name="loss")

note:TF还提供了softmax_cross_entropy_with_logits(),和上面方法的区别该方法输入的label为一个one-hot向量。

到这里我们的模型损失函数已经都有了,就到了优化阶段,本文使用梯度下降方法

learning_rate = 0.01
with tf.name_scope("train"):
optimizer = tf.train.GradientDescentOptimizer(learning_rate)
training_op = optimizer.minimize(loss)

模型有了结果,就需要对得到的模型进行衡量。简单起见,这里使用accuracy作为评估指标,判断模型输出结果的最高值的index是否和label的index相等

with tf.name_scope("eval"):
correct = tf.nn.in_top_k(logits,y,1) #取值最高的一位
accuracy = tf.reduce_mean(tf.cast(correct,tf.float32)) #结果boolean转为0,1

模型构建阶段最后一个工作就是初始化里面的变量

init = tf.global_variables_initializer()
saver = tf.train.Saver()

执行计算流图####

这一部分相对前面工作要简单很多,

n_epoch = 400
batch_size = 50
with tf.Session() as sess:
init.run()
for epoch in range(n_epoch):
for iteration in range(mnist.train.num_examples // batch_size):#需要迭代的轮数
X_batch,y_batch = mnist.train.next_batch(batch_size)
sess.run(training_op,feed_dict={X:X_batch,y:y_batch})
acc_train = accuracy.eval(feed_dict={X:X_batch,y:y_batch})
acc_test = accuracy.eval(feed_dict={X:mnist.test.images,mnist.test.labels})
print (epoch,"Train accuracy", acc_train,"Test accuracy",acc_test)
saver.save(sess, "./my_model.pk")

上面这段代码使用的是mini-batch方法训练神经网络,最后将模型持久化到本地。后续的使用

with tf.Session() as sess:
saver.restore(sess, "./my_model.pk") #加载
X_new_scaled = mnist.test.images[:20]
Z = logits.eval(feed_dict={X: X_new_scaled}) #模型
y_pred = np.argmax(Z, axis=1)

总结###

本文介绍了TF在实际数据集MNIST上面的使用,为input和target创建占位符,创建神经网络的layer,得到一个DNN,并为整个模型设置损失函数,对损失函数进行优化求解,最后对模型进行评估。

又是一个凌晨12点,晚安~

使用TensorFlow实现DNN的更多相关文章

  1. TensorFlow之DNN(二):全连接神经网络的加速技巧(Xavier初始化、Adam、Batch Norm、学习率衰减与梯度截断)

    在上一篇博客<TensorFlow之DNN(一):构建“裸机版”全连接神经网络>中,我整理了一个用TensorFlow实现的简单全连接神经网络模型,没有运用加速技巧(小批量梯度下降不算哦) ...

  2. TensorFlow之DNN(一):构建“裸机版”全连接神经网络

    博客断更了一周,干啥去了?想做个聊天机器人出来,去看教程了,然后大受打击,哭着回来补TensorFlow和自然语言处理的基础了.本来如意算盘打得挺响,作为一个初学者,直接看项目(不是指MINIST手写 ...

  3. TensorFlow之DNN(三):神经网络的正则化方法(Dropout、L2正则化、早停和数据增强)

    这一篇博客整理用TensorFlow实现神经网络正则化的内容. 深层神经网络往往具有数十万乃至数百万的参数,可以进行非常复杂的特征变换,具有强大的学习能力,因此容易在训练集上过拟合.缓解神经网络的过拟 ...

  4. DNN网络(三)python下用Tensorflow实现DNN网络以及Adagrad优化器

    摘自: https://www.kaggle.com/zoupet/neural-network-model-for-house-prices-tensorflow 一.实现功能简介: 本文摘自Kag ...

  5. keras和tensorflow搭建DNN、CNN、RNN手写数字识别

    MNIST手写数字集 MNIST是一个由美国由美国邮政系统开发的手写数字识别数据集.手写内容是0~9,一共有60000个图片样本,我们可以到MNIST官网免费下载,总共4个.gz后缀的压缩文件,该文件 ...

  6. Tensorflow 模型线上部署

    获取源码,请移步笔者的github: tensorflow-serving-tutorial 由于python的灵活性和完备的生态库,使得其成为实现.验证ML算法的不二之选.但是工业界要将模型部署到生 ...

  7. GPU加速:宽深度推理

    GPU加速:宽深度推理 Accelerating Wide & Deep Recommender Inference on GPUs 推荐系统推动了许多最流行的在线平台的参与.随着为这些系统提 ...

  8. 【TensorFlow篇】--DNN初始和应用

    一.前述 ANN人工神经网络有两个或两个以上隐藏层,称为DNN 只有一个隐藏层是多层感知机 没有隐藏层是感知机 二.反向传播应用举例 举例: 正向传播,反向传播是一次迭代, 正向传播:在开始的每一层上 ...

  9. tensorflow下基于DNN实现实时分辨人脸微表情

    参加学校的国创比赛的时候,我们小组的项目有一部分内容需要用到利用摄像头实现实时检测人脸的表情,因为最近都在看深度学习方面的相关知识,所以就自己动手实现了一下这个小Demo.参考网上的资料,发现大部分是 ...

随机推荐

  1. continous integration environment (Jenkins and bitbucket configuration)

    ================================================================================ continous integrati ...

  2. Milking Time

    Description Bessie is such a hard-working cow. In fact, she is so focused on maximizing her producti ...

  3. 哈尔滨理工大学第六届程序设计团队 I-Team

    /* 以前做过一个插队的题,这个类似从后往前操作 */ #include <iostream> #include <stdio.h> #include <algorith ...

  4. 网络基础二 tcp/ip协议簇 端口 三次握手 四次挥手 11种状态集

    第1章 概念介绍 1.1 VLAN 1.1.1 什么是VLAN VLAN(Virtual LAN),翻译成中文是“虚拟局域网”.LAN可以是由少数几台家用计算机构成的网络,也可以是数以百计的计算机构成 ...

  5. Problem E: 动物爱好者

    Problem E: 动物爱好者 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 882  Solved: 699[Submit][Status][Web ...

  6. 简单聊聊java中如何判定一个对象可回收

    背景 说到java的特性,其中一个最重要的特性便是java通过new在堆中分配给对象的内存,不需要程序员主动去释放,而是由java虚拟机自动的回收.这也是java和C++的主要区别之一:那么虚拟机是如 ...

  7. 多线程+socket实现多人聊天室

    最近在学习多线程的时候打算做一个简单的多线程socke聊天的程序,结果发现网上的代码都没有完整的实现功能,所以自己实现了一个demo: demo功能大致就是,有一个服务端负责信息转发,多个客户端发送消 ...

  8. Python StringIO与BytesIO、类文件对象

    StringIO与BytesIO StringIO与BytesIO.类文件对象的用途,应用场景,优.缺点. StringIO StringIO 是io 模块中的类,在内存中开辟的一个文本模式的buff ...

  9. SpringMVC 表单验证

    SpringMVC 表单验证 本章节内容很丰富,主要有基本的表单操作,数据的格式化,数据的校验,以及提示信息的国际化等实用技能. 首先看效果图 项目结构图 接下来用代码重点学习SpringMVC的表单 ...

  10. 拼写纠错的利器,BK树算法

    BK树或者称为Burkhard-Keller树,是一种基于树的数据结构,被设计于快速查找近似字符串匹配,比方说拼写纠错,或模糊查找,当搜索”aeek”时能返回”seek”和”peek”. 本文首先剖析 ...