Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 区域规范化的最快算法_Python_Performance_Numpy_Vectorization_Normalization - Fatal编程技术网

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:

为了规范化区域建议算法(即,对图像的每个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: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答案!