Python 区域规范化的最快算法
为了规范化区域建议算法(即,对图像的每个X×Y区域应用回归),我需要在对每个建议的激活进行求和时创建区域建议规范化。目前,对于一个128x128补丁的图像,我在Python中运行这段代码Python 区域规范化的最快算法,python,performance,numpy,vectorization,normalization,Python,Performance,Numpy,Vectorization,Normalization,为了规范化区域建议算法(即,对图像的每个X×Y区域应用回归),我需要在对每个建议的激活进行求和时创建区域建议规范化。目前,对于一个128x128补丁的图像,我在Python中运行这段代码 region_normalization = np.zeros(image.shape) for x in range(0,image.shape[0]-128): for y in range(0,image.shape[0]-128): region_normalization[x:
region_normalization = np.zeros(image.shape)
for x in range(0,image.shape[0]-128):
for y in range(0,image.shape[0]-128):
region_normalization[x:x+128,y:y+128] =
np.add(region_normalization[x:x+128,y:y+128],1)`
但这尤其低效。该算法的更快和/或更具python风格的实现是什么
谢谢 对其进行反向工程强>
好,让我们看看小图像的输出和更小的<代码> N< /Calp>Case>>,因为我们将尝试反向设计这个Loopy代码。因此,使用
N=4
(其中N
在原始情况下为128
)和image.shape=(10,10)
,我们将:
In [106]: region_normalization
Out[106]:
array([[ 1, 2, 3, 4, 4, 4, 3, 2, 1, 0],
[ 2, 4, 6, 8, 8, 8, 6, 4, 2, 0],
[ 3, 6, 9, 12, 12, 12, 9, 6, 3, 0],
[ 4, 8, 12, 16, 16, 16, 12, 8, 4, 0],
[ 4, 8, 12, 16, 16, 16, 12, 8, 4, 0],
[ 4, 8, 12, 16, 16, 16, 12, 8, 4, 0],
[ 3, 6, 9, 12, 12, 12, 9, 6, 3, 0],
[ 2, 4, 6, 8, 8, 8, 6, 4, 2, 0],
[ 1, 2, 3, 4, 4, 4, 3, 2, 1, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
我们确实看到了对称性,这种对称性恰好横跨X
和Y
两个轴。另外一件让我们吃惊的事情是,每个元素都是其起始行和列元素的乘积。因此,我们的想法是获得第一行和第一列,并在它们的元素之间执行元素级乘法。因为第一行和第一列是相同的,所以我们只需要获得一次,并将其与其他轴一起使用,然后让我们处理这些乘法。因此,执行工作将是非常重要的-
N = 128
a1D = np.hstack((np.arange(N)+1,np.full(image.shape[0]-2*N-1,N,dtype=int),\
np.arange(N,-1,-1)))
out = a1D[:,None]*a1D
运行时测试
In [137]: def original_app(image):
...: region_normalization = np.zeros(image.shape,dtype=int)
...: for x in range(0,image.shape[0]-128):
...: for y in range(0,image.shape[0]-128):
...: region_normalization[x:x+128,y:y+128] = \
...: np.add(region_normalization[x:x+128,y:y+128],1)
...: return region_normalization
...:
...: def vectorized_app(image):
...: N = 128
...: a1D = np.hstack((np.arange(N)+1,np.full(image.shape[0]-2*N-1,N,\
...: dtype=int),np.arange(N,-1,-1)))
...:
...: return a1D[:,None]*a1D
...:
In [138]: # Input
...: image = np.random.randint(0,255,(512,512))
In [139]: np.allclose(original_app(image),vectorized_app(image)) #Verify
Out[139]: True
In [140]: %timeit original_app(image)
1 loops, best of 3: 13 s per loop
In [141]: %timeit vectorized_app(image)
1000 loops, best of 3: 1.4 ms per loop
超级加速 重整化中任何给定点i,j的值等于包含它的128x128个窗口的数量。请注意,这是x轴和y轴自由度的乘积。所以我们所要做的就是计算出每个可能的x和y的自由度,然后使用广播或np.outer得到结果
import numpy as np
image = np.zeros((200,200))
window=128
region_normalization = np.zeros(image.shape)
for x in range(0,image.shape[0]-window):
for y in range(0,image.shape[0]-window):
region_normalization[x:x+window,y:y+window] = np.add(region_normalization[x:x+window,y:y+window],1)
def sliding(n, window=128):
arr = np.zeros(n)
for i in xrange(n):
#want to find all s such that 0<=s<=i<s+128<n
#thus, s < min(i+1, n-128), s >= max(0, i-window+1)
arr[i] = min(i+1, n-window) - max(0,i-window+1)
return arr
def normalizer(image, window = 128):
m,n = image.shape
res = np.zeros(shape)
if m < window or n < window: return res
x_sliding = sliding(m, window)
y_sliding = sliding(n, window)
print x_sliding
res = np.outer(x_sliding,y_sliding)
return res
print np.allclose(normalizer(image, window=128),region_normalization)
将numpy导入为np
图像=np.零((200200))
窗口=128
区域规格化=np.零(图像.形状)
对于范围内的x(0,image.shape[0]-窗口):
对于范围内的y(0,image.shape[0]-窗口):
区域_归一化[x:x+窗口,y:y+窗口]=np.add(区域_归一化[x:x+窗口,y:y+窗口],1)
def滑动(n,窗口=128):
arr=np.零(n)
对于x范围内的i(n):
#是否希望找到所有的s,以便0需要这些是重叠的窗口,而不是平铺原始图形?另外,这是用于某种卷积运算(CNN)吗?是的,这些需要重叠窗口以保证鲁棒性。这是用于图像的区域二值分类(用于分割)。很好。你有没有考虑过在这个设计中使用一些卷积神经网络?根据您对输出所做的操作,您可能完全可以绕过这一级别的编程,让框架(Torch、Theano、Caffe、CNTK、TensorFlow等)为您进行矩阵优化。@Prune是的,我知道使用CNN将是最先进(以及更快)的解决方案,但这是针对一个不熟悉机器学习状态的社区。我正在回顾经典的CV/ML方法以及最先进的技术。我发现了这一点,但实现得更糟(使用了一些for循环来实现这一点)。谢谢你用一个很好的解释给出了很好的pythonic答案!