用TensorFlow.layer package来构建深度神经网络--上原创
金蝶云社区-墨家总院
墨家总院
2人赞赏了该文章 419次浏览 未经作者许可,禁止转载编辑于2021年10月21日 16:21:59

(本文独家发布在金蝶云社区上)


1. 深度学习简介

深度学习已经被证明了在很多领域都有很好的表现,比如计算机视觉,自然语言处理,文本翻译,或者语音识别。就像“深度学习”这个名字一样,深度学习通过很多层的计算单元来完成机器学习任务。深度学习网络的种类有很多种类,其内部计算层也有很多种类,但是基本规则是一样的,即网络层数越多,网络的复杂性就越高。这篇文章主要介绍了神经网络层的基本概念,以及利用TensorFlow来搭建一个包含几种计算层的网络。

2. TensorFlow介绍

因为TensorFlow平台的横空出世,将深度学习带到了公众视野。它是一个受众很广泛的开源软件库,得到了很多机构的支持。TensorFlow为用户提供了很多函数包与工具,用户可以方便得搭建神经网络,并训练模型,使用模型。TensorFlow所提供了不同层面的抽象接口,你既可以高屋建瓴地对整个机器学习流程进行裁剪,也可以用更底层的操作完成非常复杂精细的计算。

TensorFlow在tf.layers package里提供了很多layer的种类。这个模块能够让用户不需要在意过多琐碎细节而轻易地在深度学习模块里建立layer(计算层)。同时,它也支持在卷积神经网络里用得最广泛的几种layer。至于其他网络,比如RNN,你需要查看一下t tf.contrib.rnn 或者 tf.nn这两个包。其中最基本的layer类型是FullyConnected layer,为了实现这个这个layer,你需要在Dense类里建立输入数据和数据的规模。其他种类的layers,还需要设置更多的参数,但是贴心的TensorFlow的实现方式给用户提供了默认缺省的参数设置,这样节省了用户很多时间。

但是关于layer还有争议。一种观点认为一个layer必须能够存储训练参数,比如W和b。这意味着,比如激活函数就不能被叫做layer。也确实,tf.layers里的函数利用了一个输入参数来实现这个功能。虽然这个模块里的其他layer的实现并没有严格按照这个规则。你可以找到一坨这样的layer:fully connected, convolution, pooling, flatten, batch normalization, dropout, 还有 convolution transpose。这似乎看起来,比如,flattening layer 和 max pooling在训练过程中并没有存储任何参数。尽管如此,他们还是实现了比激活函数更复杂的功能,因此这个模块的设计者还是决定把那些复杂一点不存储参数的layer定义为独立的类,函数。在后面的章节里,我们将会看到如何使用他们来建立一个深度卷积网络。

一个典型的卷积神经网络是由卷积层和pooling层(池层)成对组成的,然后后面再接上几个FullyConnect层。一个卷积操作就像是一个小的神经网络在二维的输入数据上的不同的位置持续得做计算。造成的结果是网络层的尺寸减小,但是深度在增加。Pooling操作通常是用来减小输入图像的尺寸。Max pooling是最常用的pooling算法,也同时在计算机视觉上被证明其非常高效。

在这篇文章里,我将介绍如何用TensorFlow来实现卷积神经网络的图像处理应用,并使用MNIST数据集来作为训练数据。其任务是从手写的图片中识别出来从0到9的阿拉伯数字。

3. 开始第一个模型

首先,TensorFlow有加载数据的能力。你只需要使用input_data模块:

from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets(folder_path, one_hot=True)

我们现在就准备构造一个多层的网络。在介绍完训练过程,我将带你用各种不同的layer来应对MNIST数据集。训练过程主要就是通过不断地减少网络预测值和训练数据标签之间的区别来优化损失函数的过程。深度学习经常使用cross entrop来定义损失函数。

TensorFlow提供了tf.losses.softmax_cross_entropy函数,其内部主要是利用了Softmax算法来对网络的预测数据进行多类别的统计分析。在我们的例子里,我们使用了td.train API里提供的Adam optimizer。在训练和测试中,训练数据的标签将被用到,题目代表了实际的真实情况。而模型的输出代表了网络的预测,一会儿我构建网络的时候就会定义它。

loss = tf.losses.softmax_cross_entropy(labels, output)
train_step = tf.train.AdamOptimizer(1e-4).minimize(loss)

为了衡量训练过程的的性能,我将会将真实的标签和网络输出进行比较,并且计算精确度。

correct_prediction = tf.equal(tf.argmax(output, 1), tf.argmax(labels, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))

现在我将用batches(批次),固定数量的步骤以及学习比率来介绍一个简单的训练过程。对于MNIST数据集来说,next_batch函数将会调用mnist.train.next_batch函数。当网络训练完毕后,我们将在测试集上验证模型的性能。

# Open the session
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())

for i in range(steps):
# Get the next batch
   input_batch, labels_batch = next_batch(100)
   feed_dict = {x_input: input_batch, y_labels: labels_batch}

   # Print the current batch accuracy every 100 steps
   if i%100 == 0:
      train_accuracy = accuracy.
      print("Step %d, training batch accuracy %g"%(i, train_accuracy))

   # Run the optimization step
   train_step.run(feed_dict=feed_dict)

# Print the test accuracy once the training is over
print("Test accuracy: %g"%accuracy.)

对于真实的训练,为了简单起见,我们就构建只有一个输出layer的网络。首先我们给输入数据和标签建立placeholder。在训练期间,这两个placeholder将会被mnist的装填。因为我们的数据在网络中是被扁平化处理的,所以输入layer只有一个维度,一维向量。而输出向量是和标签的类别数量一致的,即十个。另外,输入数据和标签都有一个另外的维度,设置成None,这表示数据的数量,它在训练前是不为人所知的。

input = tf.placeholder(tf.float32, [None, image_size*image_size])
labels = tf.placeholder(tf.float32, [None, labels_size])

接下来是最精彩的部分了:输出层。每一个神经单元都有一个权值和偏值,即W和b,然后从每次输入得到数据,然后做一些计算。这就是基本的Fully Connect layer,即全连接层。

output = tf.layers.dense(inputs=input, units=labels_size)

我们第一个网络的精确度欠佳,但是它很简单,训练起来速度也快。下一篇将介绍改进版的模型。


赞 2