摘要: 在这个算力还能够的时代,咱们的钻研人员一方面致力于一直地去钻研各中不同的场景中的的通用网络,一方面致力于优化神经网络的学习形式,这些都是在试图化缩小 AI 须要的算力资源。
本文分享自华为云社区《OCR 性能优化系列(二):从神经网络到橡皮泥》,原文作者:HW007。
OCR 是指对图片中的印刷体文字进行辨认,最近在做 OCR 模型的性能优化,用 Cuda C 将基于 TensorFlow 编写的 OCR 网络重写了一遍,最终做到了 5 倍的性能晋升。通过这次优化工作对 OCR 网络的通用网络结构和相干的优化办法有较深的意识,打算在此通过系列博文记录下来,也作为对本人最近工作的一个总结和学习笔记。在第一篇《OCR 性能优化系列(一):BiLSTM 网络结构概览》中,从动机的角度来推演下基于 Seq2Seq 构造的 OCR 网络是如何一步步搭建起来的。接下来咱们讲从神经网络到橡皮泥。
1. 深扒 CNN:也谈机器学习的实质
当初,从 OCR 性能优化系列(一)中的图 1 左下角的输出开始,串一遍图一的流程。首先是输出 27 张待辨认的文字片段图片,每张图片的大小为 32132。这些图片会通过一个 CNN 网络进行编码,输入 32 个 27384 的初步编码矩阵。如下图所示:
值得注意的是,在这步操作中呈现了维度秩序的调整,即输出由 27(32132)变成了 27(384),你能够了解为把尺寸为 32132 的图片拉长拍扁成一行(14224),而后再进行降维为 1384 了,相似于上文优化策略一中做计算量优化时把 1024 降到 128 的例子。怎么做这个从 274224 到 27384 的降维呢?最简略粗犷的办法就是下面的 Y =AX+ B 模型,间接给 274224 乘以一个 4224384 的矩阵 A,矩阵 A 是通过喂数据训练失去的。很显著,对同样的 X,不同的 A 失去的 Y 也不一样,而从 4224 到 384 这个维度降得又有点狠。于是,学者们便祭出了群殴大法,一个 A 不行,那就上多个 A 吧。于是在这里便祭出了 32 个 A,这个 32 便是前面的 LSTM 网络的序列长度,与输出图片的宽度 132 成比例。当输出图片的宽度变成 260 时,就须要 64 个 A 了。
兴许有人会问在 CNN 中看不到你说的 32 个 A 啊?确实,那只是我对 CNN 网络性能的形象,重点在于让大家对 CNN 编码过程中维度的变动及其下一层 LSTM 网络的序列长度有个形象的意识,晓得 LSTM 的序列长度其实是“降维器”的数量。如果你比拟机智的话,你应该发现我连“降维”都说错了,因为如果把 32 个“降维器”输入的后果拼一起的话是 32*384=12288,远大于 4224,数据通过 CNN 网络后,维度岂但没有缩小,反而减少了!其实这个货色比拟正式的叫法是“编码器”或“解码器”,“降维器”是我本文中为了形象点借鉴的,不论叫猫还是叫咪,我心愿你能记住,他的实质就是那个系数矩阵 A 而已。
当初咱们还是沿着 32 个 A 这个思路走上来,通过 CNN 网络后,从外表上看,对于每个文字图片来说,数据维度从 32132 变成了 32384,外表上看这个数据量增多了,但信息量并没有减少。就像我在这长篇累牍地介绍 OCR,文字是增多了,信息量还是 OCR 的原理,或者能晋升点可读性或趣味性。CNN 网络是怎么做到奇文瑰句(只减少数据量不减少信息量)的呢?这里隐含着一个机器学习模型中的一个顶级套路,学名叫“参数共享”。一个简略的例子,如果有一天你的敌人很快乐地通知你他有一个新发现,“买 1 个苹果要给 5 块钱,买 2 个苹果要给 10 块钱,买 3 个苹果要给 15 块钱 …”,置信你肯定会狐疑他的智商,间接说“买 n 个苹果要 5 * n 块钱”不就好了么?废话的实质在于,不做形象总结,间接疯狂的举例子,给一大堆冗余数据。不废话的实质就是总结出法则和教训,所谓的机器学习就是如这个买苹果的例子,你冀望简略粗犷的给机器举出大量的例子,机器便能总结出其中的法则和教训。这个法则和教训对应到上述的 OCR 例子中,便是整个模型的网络结构和模型参数。在模型网络上,目前支流还是靠人类智能,如对图片场景就上 CNN 网络,对序列场景就上 RNN 网络等等。网络结构选不对的话,学习进去的模型的成果会不好。
如下面的剖析中,其实在结构上,我用 32 个 4224384 的 A 矩阵是齐全能满足上述的 CNN 在数据的输出和输入的维度尺寸上的要求的,但这样的话训练进去的模型成果会不好。因为从实践上,用 32 个 4224384 的 A 矩阵的参数量是 324224384=51904512。这便意味着在学习过程中,模型太自在了,很容易学坏。在下面买苹果的例子中,用越少的字就能陈说分明这个事实的人的总结能力就越强,因为越多的文字除了引入冗余外,还有可能会引入一些息息相关的信息对当前在应用这个法则的时候进行烦扰,假如这个苹果的价格是用 10 个字就能说分明,你用了 20 个字,那很有可能你其余的 10 个字是在形容比方下雨啊、工夫点啊之类的无关信息。这就是赫赫有名的“奥坎姆剃刀法令”,不要把简略的货色复杂化!在机器学习畛域次要利用于模型构造的设计和抉择中,“参数共享”的是其罕用的套路之一,简略说就是,如果 32 个 4224384 的 A 矩阵参数量太大了,导致模型在学习中太自在了,那咱们就加限度让模型不那么自在,肯定要逼它在 10 个字内把买苹果的事件说分明。办法很简略,比如说如果这 32 个 A 长得齐全截然不同,那这里的参数个数就只有 4224384 个而已,一下子就缩小 32 倍,如果感觉缩小 32 倍太狠了,那我略微放松一点,不要求这 32 个 A 截然不同,只要求他们长得很像就好。
在此我称这个剃刀大法为“不逼模型一把就不晓得模型有多优良大法”。可能有人会提出异议,尽管我容许你用 20 个字来说分明苹果的价格,并没有抹杀你主动性很强,谋求极致,用 10 个字就说分明了的可能性。如果上文中的只用一个 A 矩阵就能 Cover 住的话,那么我不论我给 32 个 A 还是 64 个 A,模型都应该学出的是截然不同的 A 才对。这种说法在实践上是对的,但对于目前来说却是不事实的。
探讨这个问题还得回到机器学习的实质上,所有模型都能够形象示意为 Y=AX,其中 X 是模型输出,Y 是模型输入,A 是模型,留神在此段中的 A 不同于上文中的 A,其既蕴含了模型的构造和又蕴含了参数。模型的训练过程便是已知 X 和 Y,求解 A。下面的问题其实就是解进去的 A 是不是惟一的?首先我退一步,假如咱们认为在事实世界中这个问题是存在法则的,也就是说这个 A 在事实世界中是存在且惟一的,就像物理定律一样,那咱们的模型是否能在大量的训练数据中捕捉到这个法则呢?
以物理上的质能方程 E=MC^2 为例,在这个模型中,模型的构造是 E =MC^2,模型的参数是光速 C。这个模型爱因斯坦提出的,能够说是人类智能的结晶。如果用当初 AI 大法来解决这个问题呢,分两种状况,一种是强 AI,一种是弱 AI,首先说最极其的弱 AI 的办法,也就是目前的支流的 AI 办法,大部分人工小局部机器智能,具体说就是人类依据本人的智慧发现 E 和 M 之间的关系满足 E =MC^2 这样的模式,而后喂很多的 E 和 M 数据进去给机器,让机器把这个模型中的参数 C 学习进去,在这个例子中 C 的解是惟一的,而且只有喂给机器大量的 M 和 C,就能把 C 解进去了。显然智能局部的工作量次要在于爱因斯坦大神是如何去排除如工夫、温度、湿度等等各种乌七八糟的因素,确定 E 就只和 M 无关,且满足 E =MC^2。这部分工作在目前机器学习畛域被叫模型的“特征选择”,所以很多机器学习的工程师会戏称本人为“特色工程师”。
与之相同,强 AI 的预期就应该是咱们喂给机器一大堆的数据,如能量、品质、温度、体积、工夫、速度等等,由机器来通知我这外面的能量就只和品质相干,他们的关系是 E =MC^2,并且这个常数 C 的值就是 3.010^8(m/s)。在这里,机器岂但要把模型的构造学进去,还要把模型的参数学进去。要达到这个成果,首先要实现的第一步是,找到一种泛化的模型,通过加工后能形容世界上存在的所有模型构造,就像橡皮泥能被捏成各种各样的形态一样。这个橡皮泥在 AI 畛域就是神经网络了,所以很多偏实践的 AI 书或者课程都喜爱在一开始给你科普下神经网络的形容能力,证实它就是 AI 畛域的那块橡皮泥。既然橡皮泥有了,接下来就是怎么捏了,难点就在这里了,并不是生存中每个问题每个场景都能用一个个数学模型来完满示意的,就算这层成立,在这个模型构造被发现之前,没人晓得这个模型是什么样子,那你让机器怎么帮你捏出这个你自身都不晓得是什么形态的货色?惟一的方法就是,给机器喂很多的例子,说捏进去的货色要满足能走路、会飞等等。其实这个问题是没有惟一解的,机器能够给你捏出一只小鸟、也能够给你捏出一只小强。起因有二,其一在于你无奈把所有可能的例子都喂给机器,总会有“黑天鹅”事件;其二在于喂的例子太多的话,对机器的算力要求也高,这也是为啥神经网络很早就提出来了,这几年才火起来的起因。
通过下面一段的探讨,心愿你在此时能对机器学习的模型构造和模型参数能有一个比拟直观的了解。晓得如果靠人类智能设计出模型构造,再靠机器学习出参数的话,在模型构造精确的前提下,如下面的 E =M*C^2,咱们只须要喂给机器很少的数据就好,甚至模型都能有很好的解析解!但毕竟爱因斯坦只有一个,所以更多的是咱们这种平庸的人把大量的例子喂给机器,冀望他能捏出咱们本人都不晓得的那个形态,更别提有解析解这么丑陋的性质了。对机器学习训练过程相熟的同学应该晓得,机器学习捏橡皮泥用的“随机梯度降落法”,艰深点说,就是先捏一小下,看捏进去的货色是否能满足你提的要求(即喂的训练数据),如果不满足再捏一小下,如此循环直至满足你的要求才停下来。由此可见,机器捏橡皮泥的能源在于捏进去的货色不满足你的要求。这就证实了机器是个很“懒”的货色,当他用 20 个字形容出苹果的价格法则后,就没能源去做用 10 个字来形容苹果价格的法则了。所以,当你本人都不晓得你想让机器捏出什么货色时,最好就是不要给机器太大的自在,这样机器会给你捏出一个很简单的货色,只管能满足你的要求,也不会很好用,因为违反了剃刀法令。而在机器学习的模型中,参数的数量越多,往往意味着更大的自由度和更简单的构造,呈现“过拟合”景象。因而很多经典的网络后果中都会应用一些技巧来做“参数共享”,达到缩小参数的目标,如 CNN 网络中应用的卷积的形式来做参数共享,LSTM 中引入了一个变动不那么激烈的产量 C 矩阵来实现参数共享。
2. 牛刀小试:LSTM 等你扒
通过下面大节的探讨,置信你曾经 get 到剖析机器学习的一些套路了,最初以双向 LSTM 来练下手吧。
如上图,首先看 LSTM 网络的输出和输入,最显著能看到的输出有 32 个 27384 的紫色矩阵,输入是 32 个 27256 的矩阵,其中 27256 是由两个 27128 拼凑而成,别离由前向 LSTM 和反向 LSTM 网络输入。为了简略,咱们临时只看前向 LSTM,这样的话其实输出就是 32 个 27384 的矩阵,输入是 32 个 27128 的矩阵。依据上文中剖析的“降维器”套路,这里须要 32 个 384*128 的矩阵。在依据“参数共享”套路,真正的单个 LSTM 单元的构造如下图所示:
由图可知,真正的 LSTM 单元中并不是一个简略的 384128 的矩阵 A,而是把 LSTM 单元序列中的上一个单元的输入节点 H 拉下来和输出 X 拼在一起,造成一个 27512 的输出,在乘以一个 512512 的参数矩阵,再联结上一个序列输入的管制节点 C 对失去的数据进行加工,把 512 维降到 128 维,最初失去两个输入,一个是 27128 的新输入节点 H,一个是 27*128 的新管制节点 C。这个新输入的 H 和 C 会被引入到下一个 LSTM 单元,对下一个 LSTM 单元的输入进行影响。
在这里,能够看到因为矩阵 C 和矩阵 H 的存在,即便 LSTM 序列 32 个单元中的那个 512512 的参数矩阵是截然不同的,即使每个单元的输出 H 和 X 之间的关系都是不大一样的,但因为都是乘以一样的 512512 矩阵失去的,所以只管不一样,相互间应该还是比拟像,因为他们遵循了一套法则(那个截然不同的 512*512 矩阵)。在这里咱们能够看到 LSTM 是通过把上一个单元的输入 H 和输出 X 拼起来作为输出,同时引入管制矩阵 C 来实现剃刀大法,达到参数共享,简化模型的目标。这种网络结构的结构也使得以后序列单元的输入和上个序列单元的输入产生分割,实用于序列场景的建模,如 OCR、NLP、机器翻译和语音辨认等等。
在这里咱们还能看到,尽管神经网络是那块橡皮泥,但因为喂不了所有的状况的数据、机器算力不反对、或者咱们想进步机器的学习速度,在目前的 AI 利用场景中,咱们都是给依据理论利用场景精和本人的先验常识对网络结构进行精心地设计,再把这块由人类捏得差不多的橡皮泥交由机器来捏。因而我更喜爱称当初是个弱 AI 的时代,在这个算力还能够的时代,咱们的钻研人员一方面致力于一直地去钻研各中不同的场景中的的通用网络,如用于图像的 CNN、用于序列 RNN、LSTM、GRU 等等,一方面致力于优化神经网络的学习形式,如基于 SDG 的各种优化变种算法和强化学习的训练形式等等,这些都是在试图化缩小 AI 须要的算力资源。
置信在人类的致力下,强 AI 的时代会到来。
点击关注,第一工夫理解华为云陈腐技术~