1. 首页
  2. 数据挖掘

用TensorFlow实现神经网络很难吗?看完这篇详解,「小白」也可秒懂!

用TensorFlow实现神经网络很难吗?看完这篇详解,「小白」也可秒懂!

图:pixabay

作者:Faizan Shaikh

「机器人圈」编译:嗯~阿童木呀、多啦A亮

本文经公众号「雷克世界」授权转载(微信号:ROBO_AI)

用TensorFlow实现神经网络很难吗?看完这篇详解,「小白」也可秒懂!如果你一直在关注数据科学/机器学习等相关领域,那么你一定不会错过有关深度学习和神经网络的任何动态。组织正在寻找一些深谙深度学习技能的人,无论他们将深度学习的知识用于何处。从开启竞争到开源项目再到巨额奖金,人们正在试图尝尽一切办法来挖掘这个领域有限的人才资源。

如果你对深度学习的发展前景充满憧憬和期望,但还不曾开始迈进这个领域,那么,在这里我将助你开启旅程。

在本文中,我将介绍TensorFlow的相关知识。相信阅读本文后,你将能够了解神经网络的应用,并学会使用TensorFlow来解决现实生活中的问题。而在阅读本文之前,要求你能够了解神经网络的基础知识,并熟悉编程。尽管这篇文章中的代码是用Python编写的,但我会将重点放在概念上,并尽可能保持所谈论的内容与编程无关。

何时使用神经网络

众所周知,到目前为止,神经网络成为人们关注的焦点已有很长一段时间了。如果还不是很了解,点击链接,这里有有关神经网络和深度学习的更为详尽的阐述。(https://www.analyticsvidhya.com/blog/2016/10/an-introduction-to-implementing-neural-networks-using-tensorflow/?utm_source=dzone&utm_medium=social)其中,它的“更深度”版本已然在诸如图像识别、语音和自然语言处理等诸多领域取得了巨大的突破性进展。

而在神经网络的使用这有一个至关重要的问题出现了,那就是“什么时候应该使用神经网络?什么时候不应该使用神经网络呢”?现如今,这个领域俨然就是一座金矿,每天都会有许多“宝藏”破土而出,而如果想要成为这个“淘金热”的一部分,你必须注意几点:

•首先,神经网络需要清晰且翔实的数据(主要是大数据)进行训练。你可以试着将神经网络想象成一个孩子。在最初的时候,它首先要观察其父母的走路方式,然后,它试着自己走,一步一步地走下去,这个孩子就学会了如何去执行一项特定的任务。在这个过程中,它可能会跌倒几次,但经过几次失败的尝试之后,它就学会了如何走路。如果你不让它尝试着自己走,那么它可能永远也学不会如何走路。你为孩子提供的尝试机会越多,它就会越来越好。

•对于诸如图像处理这样的复杂问题,使用神经网络是一种需要很谨慎的行为。神经网络是隶属于一种称为表征学习算法(representation learning algorithms)的一类算法。这些算法将复杂问题分解成更为简单的形式,使其变得可以理解(或“可表征”)。其实你可以把它想象成是在你吞咽食物之前咀嚼食物的行为。而这对于传统算法(非表征学习)来说,将变得更加困难。

•当你认为有了适当的神经网络类型来解决问题时,殊不知每个问题都有自己的难点。而数据将决定你用以解决问题的方式。例如,如果是序列生成的问题,则选择循环神经网络是最为合适的,而如果它是一个和图像相关的问题,那么你可能就需要做些改变,采用卷积神经网络才是一个合适的选择。

•最后一点但也同样重要的是,硬件需求对运行深度神经网络模型来说是至关重要的。其实,神经网络很久以前就被“挖掘”出来了,但直到近年,它才开始“闪闪发光”,而这主要得益于计算资源的越来越好和越来越强大。如果你想要用这些网络来解决实际问题,建议你做好准备去购买一些高端硬件!

如何使用神经网络解决问题

神经网络是一种特殊类型的机器学习(ML)算法。因此,与每个ML算法一样,它遵循数据预处理,模型构建和模型评估的通用ML工作流。为了简明起见,我列出了一个如何处理神经网络问题的待办事项清单。

•检查神经网络是否提升了传统算法(参考上述章节中的检查列表)。

•做一项关于哪个神经网络架构最适合亟待解决问题的调查。

•通过你所选择的语言/库来定义神经网络架构。

•将数据转换为正确的格式,并将其分为若干批量。

•根据需要对数据进行预处理。

•添加数据以增加大小并做出更好的训练模型。

•将批量馈送到神经网络。

•训练、监测训练过程中的变化并验证数据集。

•对模型进行测试并保存以备将来使用。

对于这篇文章,我将重点介绍图像数据。在深入了解TensorFlow之前,需要首先对其有基本了解。

理解图像数据及用以解决问题的流行库

图像大部分以三维数组的形式排列,其中三维是指高度、宽度和颜色信号通道。例如,如果你在此刻拍摄个人电脑的屏幕截图,则首先将其转换成三维数组,然后将其压缩为PNG或JPG文件格式。

监管这些图像对于人类来说是很容易理解的,但对计算机来说就没有那么容易了。这种现象被称为语义鸿沟(semantic gap)。我们的大脑可以在几秒钟内看到图像,并对完整的图像加以了解。而另一方面,计算机则将图像视为一个数组。所以问题是,我们该如何将这个图像向机器加以解释。

在早期,人们试图将这种图像分解为像一个“模板”一样的机器 “可理解”的格式。例如,一张脸中总有一个特定的结构,它以某种形式在每个人身上保留下来,比如我眼睛和鼻子的位置,或者脸型。但是这种方法将会非常繁琐,因为当要识别的目标数量增加时,“模板”就不存在了。

到了2012年,深度神经网络架构赢得了ImageNet挑战赛,这是一个在从自然场景中识别目标领域的很有声望的挑战。后来在所有即将到来的ImageNet挑战中,神经网络都占据着主导地位,从而证明了其在解决图像问题的有效性。

那么人们通常会使用哪些库/语言来解决图像识别问题呢?最近的一项调查结果显示,大多数受欢迎的深度学习库都有一个Python接口,其次是Lua、Java和Matlab。下面是最受欢迎的库中的一些代表:

•Caffe(http://caffe.berkeleyvision.org/)

•DeepLearning4j(https://deeplearning4j.org/)

•TensorFlow(https://www.tensorflow.org/)

•Theano(http://www.deeplearning.net/software/theano/)

•Torch(http://torch.ch/)

现在,你应该了解图像是如何存储的以及常用的公共库有哪些了吧,下面请查看TensorFlow必须提供的内容有哪些。

什么是TensorFlow?

下面是官方定义:

TensorFlow是一个开源软件库,用于使用数据流图形进行数值计算。图中的节点表征数学运算,而图形边缘表征的是在它们之间传递的多维数据数组(又称张量)。灵活的体系结构使得你能够将计算部署到桌面,服务器或具有单个API的移动设备中的一个或多个CPU或GPU。

用TensorFlow实现神经网络很难吗?看完这篇详解,「小白」也可秒懂!

可能这听起来有点吓人,但不用担心。这里有一个简单定义,仅需要把TensorFlow看作一种有着一些难点的numpy。如果你以前曾使用过numpy,那理解TensorFlow也只不过是小菜一碟了! numpy和TensorFlow之间的一个主要区别在于TensorFlow遵循懒惰(lazy)的编程范式。它首先会构建一个需要完成的所有操作的图表,然后当“session”被调用时,它将“run”该图表。它的构建是可扩展的,因为它是通过将内部数据表征更改为张量(也就是多维数组)来实现的。构建计算图表可以被认为是TensorFlow的主要成分。要想了解更多关于计算图表的数学构成,请阅读本文。(http://colah.github.io/posts/2015-08-Backprop/)

将TensorFlow分类为神经网络库是一件很容易的事情,但它为并不仅仅如此。实质上来讲它是被设计成一个强大的神经网络库。但它所拥有的力量、能够做的事情远远不止如此。你可以在其上构建其他机器学习算法,如决策树或k最近邻算法。你可以使用它来做一切你经常使用numpy来做的事情!它恰恰称为“numpy on steroids”。

使用TensorFlow的优点是:

•它有一个直观的结构,顾名思义,它有一个“张量流”。你可以很容易将图表的每一部分可视化。

•轻松地在CPU / GPU上进行分布式计算。

•平台灵活性,你可以随时随地运行模型,无论是在移动设备,服务器还是PC上。

TensorFlow的典型 “流”

每个库都有自己的“实现细节”,即一种按照编码范式编写的方式。例如,当实现scikit-learn时,首先创建所需算法的对象,然后在训练集上建立一个模型,并对测试集进行预测,如下所示:

# define hyperparamters of ML algorithm

clf = svm.SVC(gamma=0.001, C=100.)

# train

clf.fit(X, y)

# test

clf.predict(X_test)

正如我前面所说,TensorFlow遵循一种懒惰(lazy)的方法。在TensorFlow中运行程序的通常工作流程如下:

•建立一个计算图,任何的数学运算可以使用TensorFlow支撑。

•初始化变量编译预先定义的变量。

•创建session,这是神奇开始的地方 !

•在session中运行图形,编译图形被传递到session,它开始执行操作。

•关闭session,结束这次使用。

TensorFlow 中使用的术语很少。

placeholder: A way to feed data into the graphs

feed_dict: A dictionary to pass numeric values to computational graph

让我们写一个小程序来添加两个数字!

# import tensorflow

import tensorflow as tf

# build computational graph

a = tf.placeholder(tf.int16)

b = tf.placeholder(tf.int16)

addition = tf.add(a, b)

# initialize variables

init = tf.initialize_all_variables()

# create session and run the graph

with tf.Session() as sess:

sess.run(init)

print “Addition: %i” % sess.run(addition, feed_dict={a: 2, b: 3})

# close session

sess.close()

在TensorFlow中实现神经网络

注意:我们可以使用不同的神经网络架构来解决这个问题,但是为了简单起见,我们深入实现了前馈多层感知器。

让我们先记住对神经网络的了解。

神经网络的典型实现如下:

•定义要编译的神经网络架构

•将数据传输到模型

•在引擎盖下,数据首先分成批次,以便可以获取。批次首先进行预处理、增强,然后送入神经网络进行训练。

•然后模型被逐步地训练。

•显示特定数量的时间步长的精度。

•训练后保存模型供将来使用。

•在新数据上测试模型并检查其执行情况。

在这里,我们解决深度学习实践问题,以用来识别数字。让我们再花一点时间看看问题陈述。

我们的问题是图像识别,以识别来自给定的 28×28 图像的数字。 我们有一部分图像用于训练,其余的用于测试模型。首先,下载训练和测试文件。数据集包含数据集中所有图像的压缩文件,train.csv和test.csv都具有相应训练和测试图像的名称。数据集中不提供任何其他功能,只是原始图像以 “.png” 格式提供。

如你所知,我们将使用TensorFlow来构建神经网络模型。所以,你应该先在系统中安装TensorFlow。根据你的系统规格,请参阅官方安装指南(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/g3doc/get_started/os_setup.md)进行安装。

我们将按照上述模板,使用Python 2.7内核创建Jupyter notebook ,并按照以下步骤操作。

导入所有必需的模块:

%pylab inline

import os

import numpy as np

import pandas as pd

from scipy.misc import imread

from sklearn.metrics import accuracy_score

import tensorflow as tf

设置种子值,以便我们可以控制模型的随机性:

# To stop potential randomness

seed = 128

rng = np.random.RandomState(seed)

第一步是设置目录路径,以便保管!

root_dir = os.path.abspath(‘../..’)

data_dir = os.path.join(root_dir, ‘data’)

sub_dir = os.path.join(root_dir, ‘sub’)

# check for existence

os.path.exists(root_dir)

os.path.exists(data_dir)

os.path.exists(sub_dir)

我们来看看我们的数据集。这些格式为CSV格式,并具有相应标签的文件名:

train = pd.read_csv(os.path.join(data_dir, ‘Train’, ‘train.csv’))

test = pd.read_csv(os.path.join(data_dir, ‘Test.csv’))

sample_submission = pd.read_csv(os.path.join(data_dir, ‘Sample_Submission.csv’))

train.head()

用TensorFlow实现神经网络很难吗?看完这篇详解,「小白」也可秒懂!

让我们看看我们的数据是什么样的!我们读取我们的图像并展示它。

img_name = rng.choice(train.filename)

filepath = os.path.join(data_dir, ‘Train’, ‘Images’, ‘train’, img_name)

img = imread(filepath, flatten=True)

pylab.imshow(img, cmap=’gray’)

pylab.axis(‘off’)

pylab.show()

用TensorFlow实现神经网络很难吗?看完这篇详解,「小白」也可秒懂!

上面的图像被表示为numpy数组,如下所示:

用TensorFlow实现神经网络很难吗?看完这篇详解,「小白」也可秒懂!

为了方便数据操作,我们将所有图像存储为numpy数组:

temp = []

for img_name in train.filename:

image_path = os.path.join(data_dir, ‘Train’, ‘Images’, ‘train’, img_name)

img = imread(image_path, flatten=True)

img = img.astype(‘float32’)

temp.append(img)

train_x = np.stack(temp)

temp = []

for img_name in test.filename:

image_path = os.path.join(data_dir,

由于这是一个典型的ML问题,为了测试我们模型的正常运行,我们创建一个验证集。我们采取70:30的分组大小,用于训练集与验证集对比:

split_size = int(train_x.shape[0]*0.7)

train_x, val_x = train_x[:split_size], train_x[split_size:]

train_y, val_y = train.label.values[:split_size], train.label.values[split_size:]

现在,我们定义一些辅助函数,我们稍后使用它们:

def dense_to_one_hot(labels_dense, num_classes=10):

“””Convert class labels from scalars to one-hot vectors”””

num_labels = labels_dense.shape[0]

index_offset = np.arange(num_labels) * num_classes

labels_one_hot = np.zeros((num_labels, num_classes))

labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1

return labels_one_hot

def preproc(unclean_batch_x):

“””Convert values to range 0-1″””

temp_batch = unclean_batch_x / unclean_batch_x.max()

return temp_batch

def batch_creator(batch_size, dataset_length, dataset_name):

“””Create batch with random samples and return appropriate format”””

batch_mask = rng.choice(dataset_length, batch_size)

batch_x = eval(dataset_name + ‘_x’)[[batch_mask]].reshape(-1, input_num_units)

batch_x = preproc(batch_x)

if dataset_name == ‘train’:

batch_y = eval(dataset_name).ix[batch_mask, ‘label’].values

batch_y = dense_to_one_hot(batch_y)

return batch_x, batch_y

现在是主要部分!让我们来定义我们的神经网络架构。我们定义一个三层神经网络:输入、隐藏和输出。输入和输出中的神经元数量是固定的,因为输入是我们的28×28图像,输出是代表类的10×1向量。我们在隐藏层中采集500个神经元。这个数字可以根据你的需要而变化。我们还为剩余的变量赋值。阅读文章以访问完整的代码(https://www.analyticsvidhya.com/blog/2016/10/an-introduction-to-implementing-neural-networks-using-tensorflow/?utm_source=dzone&utm_medium=social),并深入了解其工作原理。

### set all variables

# number of neurons in each layer

input_num_units = 28*28

hidden_num_units = 500

output_num_units = 10

# define placeholders

x = tf.placeholder(tf.float32, [None, input_num_units])

y = tf.placeholder(tf.float32, [None, output_num_units])

# set remaining variables

epochs = 5

batch_size = 128

learning_rate = 0.01

### define weights and biases of the neural network (refer this article if you don’t understand the terminologies)

weights = {

‘hidden’: tf.Variable(tf.random_normal([input_num_units, hidden_num_units], seed=seed)),

‘output’: tf.Variable(tf.random_normal([hidden_num_units, output_num_units], seed=seed))

}

biases = {

‘hidden’: tf.Variable(tf.random_normal([hidden_num_units], seed=seed)),

‘output’: tf.Variable(tf.random_normal([output_num_units], seed=seed))

}

现在创建我们的神经网络计算图:

hidden_layer = tf.add(tf.matmul(x, weights[‘hidden’]), biases[‘hidden’])

hidden_layer = tf.nn.relu(hidden_layer)

output_layer = tf.matmul(hidden_layer, weights[‘output’]) + biases[‘output’]

此外,我们需要定义神经网络的成本:

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(output_layer, y))

设置优化器,即我们的反向传播算法。这里我们使用Adam,这是梯度下降算法的高效变体。有在 tensorflow 中可用许多其它优化(参照此处(https://www.tensorflow.org/versions/r0.11/api_docs/python/train.html#optimizers)。

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)

定义我们的神经网络结构后,让我们来初始化所有的变量。

init = tf.initialize_all_variables()

现在让我们创建一个Session,并在Session中运行神经网络。我们还验证创建的验证集的模型准确性。

with tf.Session() as sess:

# create initialized variables

sess.run(init)

### for each epoch, do:

### for each batch, do:

### create pre-processed batch

### run optimizer by feeding batch

### find cost and reiterate to minimize

for epoch in range(epochs):

avg_cost = 0

total_batch = int(train.shape[0]/batch_size)

for i in range(total_batch):

batch_x, batch_y = batch_creator(batch_size, train_x.shape[0], ‘train’)

_, c = sess.run([optimizer, cost], feed_dict = {x: batch_x, y: batch_y})

avg_cost += c / total_batch

print “Epoch:”, (epoch+1), “cost =”, “{:.5f}”.format(avg_cost)

print “nTraining complete!”

# find predictions on val set

pred_temp = tf.equal(tf.argmax(output_layer, 1), tf.argmax(y, 1))

accuracy = tf.reduce_mean(tf.cast(pred_temp, “float”))

print “Validation Accuracy:”, accuracy.eval({x: val_x.reshape(-1, input_num_units), y: dense_to_one_hot(val_y)})

predict = tf.argmax(output_layer, 1)

pred = predict.eval({x: test_x.reshape(-1, input_num_units)})

这将是上面代码的输出。

Epoch: 1 cost = 8.93566

Epoch: 2 cost = 1.82103

Epoch: 3 cost = 0.98648

Epoch: 4 cost = 0.57141

Epoch: 5 cost = 0.44550

Training complete!

Validation Accuracy: 0.952823

眼见为实,我们将预测可视化:

img_name = rng.choice(test.filename)

filepath = os.path.join(data_dir, ‘Train’, ‘Images’, ‘test’, img_name)

img = imread(filepath, flatten=True)

test_index = int(img_name.split(‘.’)[0]) – 49000

print “Prediction is: “, pred[test_index]

pylab.imshow(img, cmap=’gray’)

pylab.axis(‘off’)

pylab.show()

Prediction is: 8(下图所示:)

我们看到模型性能是相当不错的!现在让我们创建一个提交:

sample_submission.filename = test.filename

sample_submission.label = pred

sample_submission.to_csv(os.path.join(sub_dir, ‘sub01.csv’), index=False)

终于完成了!我们刚刚创建了自己的训练神经网络!

TensorFlow的局限性

•尽管TensorFlow功能强大,但它仍然是一个低水平库,例如,它可以被认为是机器级语言,但对于大多数功能,你需要自己进行模块化和高级接口,如 keras。

•它仍然在继续开发和维护。

•它取决于你的硬件规格,配置越高越好。

•不是所有语言都能使用它的API。

•TensorFlow中仍然有很多库需要手动导入,比如OpenCL支持。

上面提到的大多数是TensorFlow开发人员的愿景,他们已经制定了一个路线图,计划库未来应该如何开发。

TensorFlow与其他库

TensorFlow建立在类似的原理,如使用数学计算图表的Theano和Torch,但是随着分布式计算的额外支持,TensorFlow能更好地解决复杂的问题。此外,TensorFlow模型的部署已经获得支持,这使得它更容易用于工业目的,打击了一些商业的三库,如Deeplearning4j、H2O和Turi。TensorFlow有用于Python,C ++和Matlab的API。最近还出现了对Ruby和R等其他语言的支持。因此,TensorFlow正试图获得通用语言的支持。

下一步在哪里?

以上你看到了如何用TensorFlow构建一个简单的神经网络,这段代码是为了让人们了解如何开始实现TensorFlow。要解决更复杂的现实生活中的问题,你必须在这篇文章的基础上再调整一些代码才行。

许多上述功能可以被抽象为提供无缝的端到端工作流,如果你使用scikit-learn,你可能知道一个高级库如何抽象“底层”实现,给终端用户一个更容易的界面。尽管TensorFlow已经提取了大多数实现,但是也有更高级的库,如TF-slim和TFlearn。

参考资源

TensorFlow官方库https://github.com/tensorflow/tensorflow

Rajat Monga(TensorFlow技术负责人) “TensorFlow为大家” 的视频https://youtu.be/wmw8Bbb_eIE

专门的资源列表:https://github.com/jtoy/awesome-tensorflow/#github-projects

PPV课推荐学习:

《3天学会TensorFlow | 香港科技大学》

近日,香港科技大学公开了一份“三日 TensorFlow 速成课程”的学习资料,主要涉及 TensorFlow 的安装、内部机制、机器学习基础、以及有关神经网络的一些 Tips 这四个部分,感兴趣的读者可以点击”阅读原文“自行下载查看。

↓↓↓

原文始发于微信公众号(PPV课数据科学社区):用TensorFlow实现神经网络很难吗?看完这篇详解,「小白」也可秒懂!

原创文章,作者:ppvke,如若转载,请注明出处:http://www.ppvke.com/archives/9346

联系我们

4000-51-9191

在线咨询:点击这里给我发消息

工作时间:周一至周五,9:30-18:30,节假日休息