本文主要是介绍Mxnet (27): 小批量随机梯度下降(Minibatch-SGD),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目前为止,梯度学习的方法中有两个极端: 一次使用所有的数据计算梯度和更新参数;一次计算一次梯度。
1 向量化和缓存
决定使用小批量的主要原因是计算效率。当考虑并行化到多个GPU和多个服务器时很好解释。我们需要向每一个GPU至少发送一个图像,假设每个服务器8个GPU一共16个服务器,那么我们的最小批次已经达到了128。
在单个GPU甚至CPU来看,情况更加微妙。设备的内存类型千奇百怪,用于计算的单元也不尽相同,而且服务器之间的带宽限制也是不同的。例如,CPU的寄存器数量比较少,之后是L1,L2高速缓存,某些情况下还有L3(内核间的共享缓存)。处理器能够处理比主存储器接口提供的更多的任务:
- 具有16个内核和AVX-512矢量化功能的2GHz CPU最多可以处理 2 ⋅ 1 0 9 ⋅ 16 ⋅ 32 = 1 0 12 2⋅10^9⋅16⋅32=10^{12} 2⋅109⋅16⋅32=1012 字节数每秒。GPU的功能很容易超过这个100倍。但是,中端服务器处理器的带宽可能不会超过100 GB / s,即不到保持处理器所需带宽的十分之一。
- 随机开始访问的时候开销很大,而顺序一直访问则相对开销较小。
减轻这个约束的方法是使用CPU缓存的层次结构。层次结构够快能够应付处理器的数据需求。这是深度学习中批处理的底层驱动力。简单举例,矩阵相乘 A = B C \mathbf{A} = \mathbf{B}\mathbf{C} A=BC。我们有许多方法计算获得 A \mathbf{A} A:
1.可以通过 A i j = B i , : C : , j ⊤ \mathbf{A}_{ij} = \mathbf{B}_{i,:} \mathbf{C}_{:,j}^\top Aij=Bi,:C:,j⊤, 即:通过点积的方式逐个元素计算。
- 可以通过 A : , j = B C : , j ⊤ \mathbf{A}_{:,j} = \mathbf{B} \mathbf{C}_{:,j}^\top A:,j=BC:,j⊤, 即,可以一次计算一列,同样也可以一次计算一排。
- 可以简单的通过 A = B C \mathbf{A} = \mathbf{B} \mathbf{C} A=BC计算
- 我们可以讲 B \mathbf{B} B 和 C \mathbf{C} C 拆分成较小的矩阵然后一次一块的计算 A \mathbf{A} A
按照第一个方法,我们每次计算元素的时候,每一次我们计算 A i j \mathbf{A}_{ij} Aij时,都需要将一行和一列向量复制到CPU中。由于矩阵元素是按顺序排列的,我们从内存中两个向量时,需要访问他们不行相交的位置,造成读取上的浪费。 第二种方式更加合理,我们可以在遍历 B B B进行计算时保留列向量 C : , j \mathbf{C}_{:,j} <
这篇关于Mxnet (27): 小批量随机梯度下降(Minibatch-SGD)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!