【发布时间】:2018-10-15 10:33:51
【问题描述】:
我有一个以下循环,我正在为不同大小的批次计算 softmax 变换,如下所示
import numpy as np
def softmax(Z,arr):
"""
:param Z: numpy array of any shape (output from hidden layer)
:param arr: numpy array of any shape (start, end)
:return A: output of multinum_logit(Z,arr), same shape as Z
:return cache: returns Z as well, useful during back propagation
"""
A = np.zeros(Z.shape)
for i in prange(len(arr)):
shiftx = Z[:,arr[i,1]:arr[i,2]+1] - np.max(Z[:,int(arr[i,1]):int(arr[i,2])+1])
A[:,arr[i,1]:arr[i,2]+1] = np.exp(shiftx)/np.exp(shiftx).sum()
cache = Z
return A,cache
由于这个 for 循环没有向量化,它是我代码中的瓶颈。有什么可能的解决方案使它更快。我尝试过使用@jit 的numba,这使它稍微快一点,但还不够。我想知道是否有另一种方法可以使其更快或矢量化/并行化。
函数的示例输入数据
Z = np.random.random([1,10000])
arr = np.zeros([100,3])
arr[:,0] = 1
temp = int(Z.shape[1]/arr.shape[0])
for i in range(arr.shape[0]):
arr[i,1] = i*temp
arr[i,2] = (i+1)*temp-1
arr = arr.astype(int)
编辑:
我忘了在这里强调我的班级数量是不同的。例如,第 1 批有 10 个类,第 2 批可能有 15 个类。因此,我传递了一个数组 arr 来跟踪哪些行属于 batch1 等等。这些批次不同于传统神经网络框架中的批次
在上面的示例中,arr 跟踪行的起始索引和结束索引。因此,softmax 函数中的分母将仅是索引位于起始索引和结束索引之间的那些观察值的总和。
【问题讨论】:
-
1) 数组顺序对性能有显着影响。在 C 有序数组中,最后一个暗淡变化最快。所以我会推荐 zo exchange(z-Array 中的 dim0 和 dim1)。 2)如果你的 arr 数组真的那么规则,你可以将它集成到 softmax 函数中,只使用循环。这应该会带来另一个加速。
标签: python python-3.x jit numba