首页 文章

矢量化与numpy

提问于
浏览
0

我试图创建一个高斯模糊矩阵 . 我正在修改http://www.labri.fr/perso/nrougier/teaching/numpy/numpy.html的代码

dev_data有784个像素特征的行,我想与所讨论的像素周围的邻居以及像素本身模糊 . 当我们沿着外边缘(行1,-1,列1,-1)时,丢弃任何越界邻居 . 我不太清楚怎么做这个丢弃 .

码:

# Initialize a new feature array with the same shape as the original data.
blurred_dev_data = np.zeros(dev_data.shape)

#we will reshape the 784 feature-long rows into 28x28 matrices
for i in range(dev_data.shape[0]):
    reshaped_dev_data = np.reshape(dev_data[i], (28,28))
    #the purpose of the reshape is to use the average of the 8 pixels + the pixel itself to blur
    for idx, pixel in enumerate(reshaped_dev_data):
        pixel = np.mean(reshaped_dev_data[idx-1:idx-1,idx-1:idx-1] + reshaped_dev_data[idx-1:idx-1,idx:idx] + reshaped_dev_data[idx-1:idx-1,idx+1:] +
             reshaped_dev_data[idx:idx,idx-1:idx-1] + reshaped_dev_data[idx:idx,idx:idx] + reshaped_dev_data[idx:idx,idx+1:] +
             reshaped_dev_data[idx+1:  ,idx-1:idx-1] + reshaped_dev_data[idx+1:  ,idx:idx] + reshaped_dev_data[idx+1:  ,idx+1:])
    blurred_dev_data[i,:] = reshaped_dev_data.ravel()

我的索引出错了:

ValueError: operands could not be broadcast together with shapes (0,0) (0,27)

它不是一个indexerror,所以我不太清楚我在这里做错了什么/如何修复它 .

1 回答

  • 1

    试试这个:

    pixel = np.mean(reshaped_dev_data[idx-1:idx+1, idx-1:idx+1])
    

    另外,请阅读slicing .


    所以我进一步研究了你的代码,你做了一些错误:

    • 这不是高斯内核 .

    • 循环中多次重新计算 reshaped_dev_data .

    • 循环错误的事情 .

    • 试图在第9行变异 pixel . 这很糟糕,因为:

    • 您正在循环的对象的突变通常很糟糕

    • 反正不会改变! pixel 就像一个"value"持有人 . 更改它不会更改正在循环的阵列 .

    • Not writing vectorized code!


    这是一种天真的,非矢量化的方式:

    def conv(arr, i, j):
        return np.mean(arr[i-1:i+1, j-1:j+1])
    
    blurred_dev_data = np.zeros_like(dev_data)
    reshaped_dev_data = dev_data.reshape(28, 28)
    
    for i, row in enumerate(reshaped_dev_data):
        for j, pixel in enumerate(row):
            blurred_dev_data[i, j] = conv(reshaped_dev_data, i, j)
    

    请注意,我们正在进行卷积 . 所以我们可以简单地使用内置库在平均内核上执行卷积 .


    关于你的意见,

    def conv(arr, i, j):
        # Ensure the boundaries are not exceeded
        a = max(i-1, 0)
        b = min(i+1, 28)
        c = min(j-1, 0)
        d = max(i+1, 28)
    
        return np.mean(arr[a:b, c:d])
    
    blurred_dev_data = np.zeros_like(dev_data)
    
    for n, data in enumerate(dev_data):
        reshaped = data.reshape(28, 28)
        blurred = np.zeros_like(reshaped)
    
        for i, row in enumerate(reshaped):
            for j, pixel in enumerate(row):
                blurred[i, j] = conv(reshaped, i, j)
    
        blurred_dev_data[n] = blurred.ravel()
    

    注意我修改了 conv 因为我忘了确保没有超出边界 .

    Note: 使用现有的库(如SciPy或OpenCV)来执行2D卷积要快得多,或者在这种情况下,使用均值平均滤波器 .

相关问题