文章目录
DeepCache:Principled Cache for Mobile Deep Vision (MobiCom2018)
深度学习引擎在移动视频上执行CNN时,可以缓存结果,将输入帧内容作为缓存键,将推理结果作为缓存值。当下一输入帧进入CNN网络时,可以通过查找并匹配输入帧内容,根据相似的输入帧内容,匹配出对应的缓存键,从而根据键直接重用缓存中相应的缓存值,避免该输入帧相似区域的重复计算。(这种方法适用于连续图像帧中相似场景较多的视频流处理应用中,而且其在减少计算的同时也增加了数据移动开销,即将缓存中前一帧可重用的数据移至当前帧对应的缓存存储区域中)。
一、摘要
DeepCache是一种用于连续移动视觉中的深度学习推理的原则性缓存设计。 ,通过利用输入视频流中的时间局部性来提高模型执行效率。 它解决了移动视觉带来的一个关键挑战:缓存必须在视频场景变化的情况下运行,同时在可缓存性、开销和模型准确性损失之间进行权衡。 在模型的输入端,DeepCache 通过利用视频的内部结构来发现视频的时间局部性,为此它借用了视频压缩中经过验证的启发式算法; 在模型中,DeepCache 通过利用模型的内部结构传播可重用结果区域。 值得注意的是,DeepCache 避免将视频启发式应用于模型内部结构,这些内部结构不是像素,而是高维、难以解释的数据。DeepCache 能够与未经修改的深度学习模型一起工作,不需要开发人员的手动工作,因此可以立即部署在现成的移动设备上。 实验表明,DeepCache 平均可节省 18% 的推理执行时间,最高可节省 47%。 DeepCache 平均降低了 20% 的系统能耗。
二、缓存的思想和挑战
1. 缓存思想的引入
1) CNN是视频处理的常用算法,但在资源有限的设备端受限
如今,CNN是用来处理连续移动视觉(即视频流数据)的常用算法,但其存在高时间复杂性和高空间复杂性,在资源受限的移动设备上受限。虽然CNN的执行可以卸载到云端,但是在设备端执行可以得到以下三个优点:快速推断,保护用户隐私,不受互联网连接不良的影响。
2) 如何解决设备端受限这一问题——缓存
为了在资源有限的移动/可穿戴设备上执行CNN,本文拟利用移动视频流的时间局部性,即连续的视频帧之间丰富的信息冗余。深度学习引擎在移动视频上执行CNN时缓存得到的推断结果,将输入帧内容作为缓存键(key),将推断结果作为缓存值(value),并在下一次遇到“相同”(如何定义两个输入帧内容相同是关键问题,也是缓存思想运用时存在的挑战)的输入帧内容时,直接重用缓存的推断结果,而不必再次计算。这种缓存预计将显著减少引擎的资源需求。
2. 挑战
1) 缓存中的可重用结果查找
经典缓存,例如web浏览器缓存,基于键等价性(例如相同的url)查找缓存值(例如web页面)。这并不适用于CNN缓存:它的键,即移动视频内容,通常会随着时间的推移而发生适度的场景变化。这种变化由环境的改变造成,如用户/照相机的运动、对象的外观和光照的变化等。CNN缓存必须系统地容忍这些变化,并评估关键的相似性。在这样做时,引擎必须在可缓存性、开销和模型精度之间进行权衡。
2) CNN中间特征图的细粒度重用
CNN模型的计算是layer-by-layer的。除了缓存CNN的最终推断输出外,引擎还应该缓存由内部层产生的中间结果(即特征图)。此外,引擎应该以精细的空间粒度重用已缓存的特性图。然而,特征图是高容量、高维、几乎无法解释的数据。检查它们可能既要花费昂贵的代价,又难以评估它们的相似性。
3) 平衡可缓存性、模型准确性和高速缓存开销
在使用缓存时,引擎将失去CNN模型的准确性:它将不得不对相似但不相同的图像区域重复使用缓存的值。这需要一个复杂的权衡。首先,在放宽图像相似性标准提高可缓存性的同时,也降低了模型的准确性。其次,虽然更彻底的缓存查找提高了缓存能力,但它的额外开销必须通过足够的性能增益来证明。
4) 对抗缓存侵蚀(cache erosion)
在 CNN 中,可重用性往往会在其更深层次上降低,我们将这种行为称为缓存侵蚀。更具体地说,给定一个被认为与前一帧的现有区域相似(可重用)的输入图像区域,随着执行进入模型,每一层的特征图上可重用结果的数量会减少。图 3 显示了卷积层的示例,其输入是 5x5 像素的缓存区域。但是,输出中的外围像素(灰色)不能像中心像素(绿色)一样从缓存中加载,并且必须进行详尽的计算。这是因为这些外围像素来自输入特征图中的可重用和不可重用结果。 结果,可重复使用的区域被侵蚀了。
三、DeepCache方法
1. DeepCache体系结构
图5显示了DeepCache的体系结构。它通过缓存增强了现有的模型推理,同时保持所有其他引擎组件不变,包括加载CNN模型文件,从摄像机摄取视频,预处理视频帧,在CPU/GPU上执行CNN模型,并发出最终输出。缓存中存储模型输入的最新视频帧,以及内部层的最新特性图(即缓存中只存储一帧图像及其对应的各层特征图,计算第i
帧时缓存中的是第i-1
帧)。缓存键是缓存输入帧上大小相同的区域(如10×10像素值大小的区域)。缓存值是由图层生成的缓存特征映射。当前输入帧进行CNN模型时,先与缓存中存储的前一帧输入帧进行图像匹配(查找cache key,并且对两帧之间相同的keys及其对应的values进行标记),匹配到的区域不用重复计算,直接重用缓存中的结果即可。
如图1所示,DeepCache将输入帧划分为一块块区域作为键(cahce keys),并将CNN模型内部层中该区域对应的特征图作为缓存值(cache values)。这里,DeepCache只将输入帧作为键,而不将内部各层的特征图作为键,是因为输入帧的相同或者相似性很好判断,并且有成熟的diamond search算法可以使用。而特征图的相似性却不好判断,因为它们是几乎无法解释的数据,而且数据量庞大,将其设为键并查找,会花费很多时间。
2. key查找:输入帧区域匹配
1) block-wise or pixel-wise?
有两种方法可以进行匹配:块级(block-wise)匹配和像素级(pixel-wise)匹配。理论上,识别每个像素的匹配级别(像素级匹配)和重用其缓存的结果可以更细粒度,使模型精度损失最小化。然而,即使在两个连续图像中相似的场景也可能具有相对较低的对应像素的匹配分数(像素突变),这是由于几乎不明显的环境变化,例如光线,以及物体的移动造成的。由于缓存侵蚀行为,这些“不匹配”的像素会导致缓存重用的显著减少。因此,DeepCache使用逐块匹配而不是逐像素匹配,将块(例如,10×10像素)作为基本单元来判断它是否成功匹配到先前图像中的相应块。这样,如果块中的其他周围像素被很好地匹配,突变的像素将不会影响逐块匹配决策。
2) 匹配块合并
采用块级匹配时,希望匹配的块能够合并成更大的块。如图6所示,图6(a)中可能有最高的匹配分数块B1和B2,但它不适合在我们的缓存机制,因为这些小可重用块由于缓存侵蚀将很快在后几层消失。假设B1和B2的大小是5x5,卷积内核是3x3。在缓存侵蚀后,可重用区域变成两个3x3矩形,共18个像素。相比之下,图6(b)中会在当前帧中找到两个与前一帧中的块相似的相邻块,这样这两个块就可以合并成一个更大的块,虽然图6(b)中的匹配分数没有(a)中高。在这种情况下,可重用区域在卷积后变成一个3×8的矩形,总共24个像素。
3) 匹配算法步骤
- Step 1:将当前的输入帧(图像)划分为一个个NxN的网格。
- Step 2:对于每个网格块,在缓存的前一帧中找到最匹配的相同大小的块。这里,将当前帧中第
i
个块( i = 1 , . . . , N 2 i=1,...,N^2 i=1,...,N2)的左上角点表示为 ( x i , y i ) (x_i,y_i) (xi,yi),将前一帧中对应的匹配块位置表示为 ( x i ′ , y i ′ ) (x_i',y_i') (xi′,yi′)。DeepCache利用在视频压缩中广泛使用的**金刚石搜索(diamond search)**算法来快速识别最匹配的块。两个图像块之间的匹配级别(相似度)用PSNR度量表示:PSNR越高,表示两个图像块越相似。 - Step 3:计算平均块移动 ( M x , M y ) (M_x,M_y)