Python Scipy卷积2D与子采样,如Theano#x27;那是什么?

Python Scipy卷积2D与子采样,如Theano#x27;那是什么?,python,numpy,scipy,theano,Python,Numpy,Scipy,Theano,我希望使用10 X 10滤波器对大小为600 X 400的图像执行2D卷积。过滤器是不可分离的scipy.signal.convolve2d目前对我来说效果很好,但我希望很快能看到更大的图像 对此,我有两个想法 调整图像大小 二次采样(或跨步) 专注于子采样部分,theano有一个函数,其卷积方式与scipy卷积2D相同,请参阅 它也有子采样选项。但是,在windows上安装theano对我来说很痛苦。如何使用scipy.signal.convalve2d进行子采样?任何其他替代方案(不需要我安

我希望使用10 X 10滤波器对大小为600 X 400的图像执行2D卷积。过滤器是不可分离的
scipy.signal.convolve2d
目前对我来说效果很好,但我希望很快能看到更大的图像

对此,我有两个想法

  • 调整图像大小
  • 二次采样(或跨步)
  • 专注于子采样部分,theano有一个函数,其卷积方式与scipy卷积2D相同,请参阅


    它也有子采样选项。但是,在windows上安装theano对我来说很痛苦。如何使用
    scipy.signal.convalve2d
    进行子采样?任何其他替代方案(不需要我安装一些重量级库)?

    您可以手动实现子采样,为了简单起见,我只绘制1d。假设要在间距为k的规则子网格上采样s=d*f。那么你的第n个样本是s_nk=sum_i=0^10 f_i d_nk-i。这里要观察的是,f和d的指数总是等于k的倍数。这建议将其拆分为子和s_nk=sum_j=0^k-1 sum_i=0^10/k f_j+ik d_-j+(n-i)k。所以你需要做的是:网格上的子样本d和f,所有偏移量为0,…,k-1时的间距为k。卷积偏移量总和为0或k的所有子采样d和f对,并将结果相加

    这里有一些1d的代码。它大致实现了上述功能,只是网格的放置略有不同,以使索引管理更容易。第二个函数以愚蠢的方式执行,即计算完全卷积,然后进行抽取。它是用来测试第一个函数的

    import numpy as np
    from scipy import signal
    
    def ss_conv(d1, d2, decimate):
        n = (len(d1) + len(d2) - 1) // decimate
        out = np.zeros((n,))
        for i in range(decimate):
            d1d = d1[i::decimate]
            d2d = d2[decimate-i-1::decimate]
            cv = signal.convolve(d1d, d2d, 'full')
            out[:len(cv)] += cv
        return out
    
    def conv_ss(d1, d2, decimate):
        return signal.convolve(d1, d2, 'full')[decimate-1::decimate]
    
    编辑:二维版本:

    import numpy as np
    from scipy import signal
    
    def ss_conv_2d(d1, d2, decy, decx):
        ny = (d1.shape[0] + d2.shape[0] - 1) // decy
        nx = (d1.shape[1] + d2.shape[1] - 1) // decx
        out = np.zeros((ny, nx))
        for i in range(decy):
            for j in range(decx):
                d1d = d1[i::decy, j::decx]
                d2d = d2[decy-i-1::decy, decx-j-1::decx]
                cv = signal.convolve2d(d1d, d2d, 'full')
                out[:cv.shape[0], :cv.shape[1]] += cv
        return out
    
    def conv_ss_2d(d1, d2, decy, decx):
        return signal.convolve2d(d1, d2, 'full')[decy-1::decy, decx-1::decx]
    

    你的过滤器会随着图像的增长而增长吗?在这种情况下,您可以尝试研究,因为IIRC与许多其他数值计算软件不同,scipy默认情况下不使用fft。当然,如果你的过滤器保持在10x10,这将不会给你带来任何好处。我的过滤器将保持不变。我实际上搬到了fftconvolve。它确实很快(就我而言是2倍)。然而,它也没有任何子采样选项。我已经在A中添加了一些代码。恐怕只有1d,但应该可以直接推广。看一看。同样,你可以尝试使用优化的卷积、relu和其他原语在CPU中运行得非常快。@Patric这确实是个好主意。但是,我与一些在不同系统上工作的人共享这段代码,因此我不喜欢这段代码。这很有趣。让我试试这个。我仍然不确定我是否能得到2D版本的答案。我确实让2D工作了,但是你的快一点。我会将此标记为已接受。但是,我不知道哪一个更快,为什么?对不起,我不明白。哪一个?你是说
    ss_conv_2d
    conv_ss_2d
    ?其中第一个更快,主要是因为它只计算绝对必要的内容,而第二个计算完全卷积,然后丢弃大部分卷积。使用
    convolve2d
    时,加速比应大致为decy x decx,由于循环的开销,可能会稍微小一些。使用
    fftconvolve
    时,加速比应该更小,因为
    fftconvolve
    在大操作数上节省了更多(与
    convalve2d
    相比)。有趣。但是这两个嵌套的for循环不会降低ss_conv2d的速度吗?我对你的方法进行了计时,ss_conv2d稍微快一点。