CNN模型调优策略

CNN应该是最常用的Tensorflow模型,实际使用过程中可能会出现 调用速度过慢的情况。

卷积

关于卷积,在 TensorFlow Tutorial #02 Convolutional Neural Network 有过笔记,这里略微提一下。

理解卷积作用

如果原始的图像是最左边的那个7,卷积操作为 16个channel,每个卷积核大小是[5,5],SAME方式,2*2的Max Pooling 一下,所以最终输出是这个样子。

这里因为比较简单,我们可以把卷积核拿出来,单独看看,每个卷积核都画出来的话,我们会发现,每个卷积核有着不同的敏感度。

举个例子有的卷积核可能对直线比较敏感,有的卷积核可能对圆比较敏感,对圆比较敏感的卷积核对识别0就比较有用。

所以卷积核,也就是神经网络的核心思想,其实是希望神经元(这里的卷积核),能够学到一些东西,并记下来。

如果下回再来一个7,那么卷积核发现,呦,这里有两个直线,那他很可能就是7。

神经元也算学到点东西。

当然,大脑其实比这几个神经元复杂得多,所以还有很长的路要走。。。

计算过程

斯坦福提供了一个动图帮助理解卷积的过程

1556161607.png

图像 和 卷积核对应位置相乘,然后加起来。

这里,其实是准备了一个滑动窗口,一个一个的滑动过去, 乘->加->凑矩阵

这个滑动的过程是很慢的,如果我们可以想办法转换成矩阵乘法。

然后就可以用eigen mkl 之类的高性能矩阵运算库,直接矩阵运算。

卷积->矩阵

35050-6utbcv5xo6c.png

这个图其实不准确,但我实在找不到图了。。。

比如待卷积的矩阵为 1 * 7 * 256 * 1,这里乘1是因为NLP跟图像不一样,是没有高度(或者宽度,比如RGB)。

卷积核为 3 * 256 * 1 * 512

所以出来的结果是 7 * 512,这样一个矩阵。

大概重组流程为:

  • 重组输入矩阵
    将 7 * 256 重组成 7 * 768 的形式
行号 内容
1 1
2 2
3 3
4 4
5 5
6 6
7 7

第一行是之前第1行和第2行横坐标拼凑结果,前边补0,这里具体参考CNN SAME格式的要求。
变成这个形式

行号 内容
1 0 1 2
2 1 2 3
3 2 3 4
4 3 4 5
5 4 5 6
6 5 6 7
7 6 7 0
  • 重组卷积矩阵
    3 * 256 * 512 重组成 768 * 512的形式
  • 矩阵相乘即可
    [7,768] * [768,512] —> [7,512]

逻辑上基本是没有问题的,重组的过程会比较麻烦,注意别算错了。

卷积之提前计算

卷积的本质是将 输入内容进行乘法运算,那么就可以设计出一种办法,提前算好乘法结果,用的时候直接命中即可。

思路如下,在NLP中,常用的汉字大概6000左右,我们增加限制到10000个字。

那么1w个字,对应3个卷积核,也就是最多有3w个结果。

将这3w个结果直接保存下来,调用的时候,就不用做卷积了,直接做命中即可。

应用hash结果计算时间

从数据保存说起

一个矩阵保存在内存中的方式,分为以下两种。
70222-z1gtqynnrin.png

所以如果看看下 内存中的数据

妈耶,那么大的矩阵竟然在内存中是 一字长蛇 保存。

这样就会导致比如说我们要找第999行的数据,程序要一行一行的这么找过去。

数据保存为数组格式

把数据保存成数据格式,可以在找数据的时候,hash表直接命中,不需要一行一行的寻找。

根据测试,在某些重要环节上,如果把矩阵换成 数组 或者vector 与矩阵的结合方式,运算速度可以提高10x

作者

mmmwhy

发布于

2018-08-04

更新于

2022-10-30

许可协议

评论