是否可以使用向量方法来移动存储在 numpy ndarray 中的图像以进行数据增强?

背景:这是 Aurelien Geron 的教科书 Hands on Machine Learning 中的练习题之一。

问题是:编写一个函数,可以将 MNIST 图像在任何方向(左、右、上、下)移动一个像素。然后为训练集中的每个图像创建四个移动副本(每个方向一个)并将它们添加到训练集中。

我的思考过程:

  1. 我在 X_train 中有一个大小为 (59500, 784) 的 numpy 数组(每行是一个 (28,28) 图像)。对于 X_train 的每一行:

    1. 重塑为 784,0

    2. 写入空数组

    3. 将行重塑为 28,28

    4. 对于每个方向(上、下、左、右):

  2. 将新数组附加到 X_train

我的代码:

import numpy as np

from scipy.ndimage.interpolation import shift


def shift_and_append(X, n):

    x_arr = np.zeros((1, 784))

    for i in range(n):

        for j in range(-1,2):

            for k in range(-1,2):

                if j!=k and j!=-k:

                    x_arr = np.append(x_arr, shift(X[i,:].reshape(28,28), [j, k]).reshape(1, 784), axis=0)

    return np.append(X, x_arr[1:,:], axis=0)


X_train_new = shift_and_append(X_train, X_train.shape[0])

y_train_new = np.append(y_train, np.repeat(y_train, 4), axis=0)

运行需要很长时间。我觉得这是蛮力的。有没有一种有效的矢量方法来实现这一点?


茅侃侃
浏览 127回答 1
1回答

慕标5832272

3 个嵌套for循环,带有if条件,同时整形和追加显然不是一个好主意;numpy.roll以矢量方式完美地完成了这项工作:import numpy as npimport matplotlib.pyplot as plt from keras.datasets import mnist(x_train, y_train), (x_test, y_test) = mnist.load_data()x_train.shape# (60000, 28, 28)# plot an original imageplt.gray() plt.matshow(x_train[0]) plt.show() 我们先演示一下操作:# one pixel down:x_down = np.roll(x_train[0], 1, axis=0)plt.gray() plt.matshow(x_down) plt.show() # one pixel up:x_up = np.roll(x_train[0], -1, axis=0)plt.gray() plt.matshow(x_up) plt.show() # one pixel left:x_left = np.roll(x_train[0], -1, axis=1)plt.gray() plt.matshow(x_left) plt.show() # one pixel right:x_right = np.roll(x_train[0], 1, axis=1)plt.gray() plt.matshow(x_right) plt.show() 确定了这一点后,我们可以简单地生成所有训练图像的“正确”版本x_all_right = [np.roll(x, 1, axis=1) for x in x_train]对于其他 3 个方向也是如此。让我们确认第一张图片x_all_right确实是我们想要的:plt.gray() plt.matshow(x_all_right[0]) plt.show()您甚至可以避免最后一个列表理解,而使用纯 Numpy 代码,如x_all_right = np.roll(x_train, 1, axis=2)这更有效,虽然稍微不那么直观(只需采用相应的单图像命令版本并增加axis1)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python