想要了解更多关于Apache Spark的信息,请在2016年2月在纽约出席Spark东部峰会。
神经网络在过去的几年中取得了惊人的进展,现在它是图像识别和自动翻译领域的领先技术。而 TensorFlow是Google发布的用于数值计算和神经网络的新架构。在这篇博文中,我们将展示如何使用TensorFlow和Spark来训练和应用深度学习模型。
您可能想知道:当大多数高性能深度学习是用单节点来实现时,Apache Spark这使用的是什么?为了回答这个问题,我们介绍了两种使用情况,并解释你可以怎样使用Spark和一组机器来改进TensorFlow的深度学习流程:
深度学习机器学习(ML)技术的一个典型范例是人造神经网络。他们用一个较复杂的输入,如一张照片或一段录音,然后对这些信号采用复杂的数学转换。这个变换输出一个更容易被其他ML算法操作的数字向量。人造神经网络通过模仿人类大脑视觉皮层中的神经元(以一种简化得多的形式)来实现这种转换。
就像人类学着解释他们所看到的东西一样,人造神经网络需要被训练去识别“有趣的”特定图案。比如,这些图案可能是一些简单的图形,例如棱,圆形,但是它们也可能复杂得多。在这里,我们准备使用NIST的经典数据集,训练一个神经网络来识别这些数字:
TensorFlow库自动为神经网络创建各种形状和尺寸的训练算法。然而,构建神经网络的实际过程比在数据集上运行某些函数要复杂得多。通常有许多非常重要的超参数(非专业人员的配置参数)要去设置,这个影响了模型如何被训练。选中了对的参数就会有高性能,而不好的参数则会导致训练时间过长和低性能。在实际运用中,机器学习实践者用不同的超参数多次重复运行相同的模型,以找到最优集。这是一种称为超参数调整的经典技术。
当建立神经网络时,有许多重要的超参数要慎重地选择。例如:
有趣的是,即使TensorFlow它本身不是分布式的,但超参数调整的过程是“高度并行”的,且它可以被Spark分配。在这种情况下,我们可以使用Spark来传送数据和模型描述等共用元素,然后在一组机器中以容错的方式调度独立重复的运算。
怎么利用Spark提高准确性呢?默认超参数组的准确度是99.2%。在测试集里超参数调优的最佳结果的准确率为99.47%,测试误差减少了34%。与添加到集群中的节点数按比例分配线性计算:使用13节点的集群,我们能够并行训练13个模型,相比于在一台机器上每次训练一个模型,这样可以使转换速率加速7倍。以下是关于群集中计算机数量的计算时间(以秒为单位)的柱图:
更重要的是,我们深入了解了训练程序于各种不同的超参数训练的灵敏度。例如,对于不同数量的神经元,我们绘制了有关学习率的最终测试表现图:
这展示了神经网络的一个经典权衡曲线:
利用参数的稀疏样本,我们可以将最有希望的一组参数归零。
由于TensorFlow可以使用每个工作者的所有内核,我们在每个工作者上一次只能运行一个任务,并将他们批处理以减少冲突。按照TensorFlow网站上的说明, TensorFlow库可以作为常规Python库被设置在在Spark集群上。下面的笔记展示了如何安装TensorFlow并让用户重新运行这篇博文的实验:
TensorFlow模型可以直接嵌入流程中,以便对数据集执行复杂的识别任务。例如,我们展示了如何从一个已被训练好的股票神经网络模型中标记一组图像。
用Spark内置的传送机制,这个模型首先被分配给集群的工作者:
with gfile.FastGFile( ‘classify_image_graph_def.pb’, ‘rb’) as f:
model_data = f.read()
model_data_bc = sc.broadcast(model_data)
然后这个模型被加载到每个节点上,被应用到图像中。这里是一个被运行在每个节点上的概要代码:
def apply_batch(image_url):
# Creates a new TensorFlow graph of computation and imports the model
with tf.Graph().as_default() as g:
graph_def = tf.GraphDef()
graph_def.ParseFromString(model_data_bc.value)
tf.import_graph_def(graph_def, name=”)
# Loads the image data from the URL:
image_data = urllib.request.urlopen(img_url, timeout=1.0).read()
# Runs a tensor flow session that loads the
with tf.Session() as sess:
softmax_tensor = sess.graph.get_tensor_by_name(‘softmax:0’)
predictions = sess.run(softmax_tensor, {‘DecodeJpeg/contents:0’: image_data})
return predictions
这个代码可以通过把凑图片拼凑在一起而变得高效。
这里有个图片的例子:
这是根据神经网络对这个图像的解释,这是相当准确的:
(‘coral reef’, 0.88503921),
(‘scuba diver’, 0.025853464),
(‘brain coral’, 0.0090828091),
(‘snorkel’, 0.0036010914),
(‘promontory, headland, head, foreland’, 0.0022605944)])
我们展示了如何结合Spark和TensorFlow在手写数字识别和图像标记上来训练和部署神经网络。尽管我们使用的神经网络框架只能在单节点中工作,但我们可以使用Spark来分配超参数调整进程和部署模型。这不仅减少了训练时间,而且提高了准确性,使我们更好地理解各种超参数的灵敏度。
虽然这个支持目前只在Python上适用,但我们期望在TensorFlow和其他部分Spark框架之间提供更深的一体化。
免费试用Databricks。从今天开始