矩阵是什么意思通俗 抖音矩阵是什么意思( 二 )


将各种各样的数据抽象成张量表示 , 然后再输入神经网络模型进行后续处理是一种非常必要且高效的策略 。因为如果没有这一步骤 , 我们就需要根据各种不同类型的数据组织形式定义各种不同类型的数据操作 , 这会浪费大量的开发者精力 。更关键的是 , 当数据处理完成后 , 我们还可以方便地将张量再转换回想要的格式 。例如Python NumPy包中numpy.imread和numpy.imsave两个方法 , 分别用来将图片转换成张量对象(即代码中的Tensor对象) , 和将张量再转换成图片保存起来 。
4.2 基于张量的各种操作
有了张量对象之后 , 下面一步就是一系列针对这一对象的数**算和处理过程 。
其实 , 整个神经网络都可以简单视为为了达到某种目的 , 针对输入张量进行的一系列操作过程 。而所谓的“学习”就是不断纠正神经网络的实际输出结果和预期结果之间误差的过程 。这里的一系列操作包含的范围很宽 , 可以是简单的矩阵乘法 , 也可以是卷积、池化和LSTM等稍复杂的运算 。而且各框架支持的张量操作通常也不尽相同 , 详细情况可以查看其官方文档(如下为NumPy、Theano和TensorFlow的说明文档) 。
NumPy:http://www.scipy-lectures.org/intro/numpy/operations.html
Theano:http://deeplearning.net/software/theano/library/tensor/basic.html
TensorFlow:https://www.tensorflow.org/api_docs/python/math_ops/
需要指出的是 , 大部分的张量操作都是基于类实现的(而且是抽象类) , 而并不是函数(这一点可能要归功于大部分的深度学习框架都是用面向对象的编程语言实现的) 。这种实现思路一方面允许开发者将各种类似的操作汇总在一起 , 方便组织管理 。另一方面也保证了整个代码的复用性、扩展性和对外接口的统一 。总体上让整个框架更灵活和易于扩展 , 为将来的发展预留了空间 。
4.3 计算图(Computation Graph)
有了张量和基于张量的各种操作之后 , 下一步就是将各种操作整合起来 , 输出我们需要的结果 。
但不幸的是 , 随着操作种类和数量的增多 , 管理起来就变得十分困难 , 各操作之间的关系变得比较难以理清 , 有可能引发各种意想不到的问题 , 包括多个操作之间应该并行还是顺次执行 , 如何协同各种不同的底层设备 , 以及如何避免各种类型的冗余操作等等 。这些问题有可能拉低整个深度学习网络的运行效率或者引入不必要的Bug , 而计算图正是为解决这一问题产生的 。
计算图首次被引入人工智能领域是在2009年的论文《Learning Deep Architectures for AI》 。当时的图片如下所示 , 作者用不同的占位符(* , + , sin)构成操作结点 , 以字母x、a、b构成变量结点 , 再以有向线段将这些结点连接起来 , 组成一个表征运算逻辑关系的清晰明了的“图”型数据结构 , 这就是最初的计算图 。
后来随着技术的不断演进 , 加上脚本语言和低级语言各自不同的特点(概括地说 , 脚本语言建模方便但执行缓慢 , 低级语言则正好相反) , 因此业界逐渐形成了这样的一种开发框架:前端用Python等脚本语言建模 , 后端用C++等低级语言执行(这里低级是就应用层而言) , 以此综合了两者的优点 。可以看到 , 这种开发框架大大降低了传统框架做跨设备计算时的代码耦合度 , 也避免了每次后端变动都需要修改前端的维护开销 。而这里 , 在前端和后端之间起到关键耦合作用的就是计算图 。
将计算图作为前后端之间的中间表示(Intermediate Representations)可以带来良好的交互性 , 开发者可以将Tensor对象作为数据结构 , 函数/方法作为操作类型 , 将特定的操作类型应用于特定的数据结构 , 从而定义出类似MATLAB的强大建模语言 。
需要注意的是 , 通常情况下开发者不会将用于中间表示得到的计算图直接用于模型构造 , 因为这样的计算图通常包含了大量的冗余求解目标 , 也没有提取共享变量 , 因而通常都会经过依赖性剪枝、符号融合、内存共享等方法对计算图进行优化 。
目前 , 各个框架对于计算图的实现机制和侧重点各不相同 。例如Theano和MXNet都是以隐式处理的方式在编译中由表达式向计算图过渡 。而Caffe则比较直接 , 可以创建一个Graph对象 , 然后以类似Graph.Operator(xxx)的方式显示调用 。