为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

茅侃侃 2022-10-06 19:20:20
背景:这是 Aurelien Geron 的教科书 Hands on Machine Learning 中的练习题之一。问题是:编写一个函数,可以将 MNIST 图像在任何方向(左、右、上、下)移动一个像素。然后为训练集中的每个图像创建四个移动副本(每个方向一个)并将它们添加到训练集中。我的思考过程:我在 X_train 中有一个大小为 (59500, 784) 的 numpy 数组(每行是一个 (28,28) 图像)。对于 X_train 的每一行:重塑为 784,0写入空数组将行重塑为 28,28对于每个方向(上、下、左、右):将新数组附加到 X_train我的代码:import numpy as npfrom scipy.ndimage.interpolation import shiftdef 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)运行需要很长时间。我觉得这是蛮力的。有没有一种有效的矢量方法来实现这一点?
查看完整描述

1 回答

?
慕标5832272

TA贡献1966条经验 获得超4个赞

3 个嵌套for循环,带有if条件,同时整形和追加显然不是一个好主意;numpy.roll以矢量方式完美地完成了这项工作:


import numpy as np

import 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 image

plt.gray() 

plt.matshow(x_train[0]) 

plt.show() 

//img1.sycdn.imooc.com//633eba1e000145c302580257.jpg

我们先演示一下操作:


# one pixel down:

x_down = np.roll(x_train[0], 1, axis=0)

plt.gray() 

plt.matshow(x_down) 

plt.show() 

//img1.sycdn.imooc.com//633eba2d0001fc6a02560259.jpg

# one pixel up:

x_up = np.roll(x_train[0], -1, axis=0)

plt.gray() 

plt.matshow(x_up) 

plt.show() 

//img1.sycdn.imooc.com//633eba3b00017fd202550256.jpg

# one pixel left:

x_left = np.roll(x_train[0], -1, axis=1)

plt.gray() 

plt.matshow(x_left) 

plt.show() 

//img1.sycdn.imooc.com//633eba4e00018a5a02570255.jpg

# one pixel right:

x_right = np.roll(x_train[0], 1, axis=1)

plt.gray() 

plt.matshow(x_right) 

plt.show() 

//img1.sycdn.imooc.com//633eba5b000107ec02530256.jpg

确定了这一点后,我们可以简单地生成所有训练图像的“正确”版本


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()

//img1.sycdn.imooc.com//633eba670001c2e202560256.jpg

您甚至可以避免最后一个列表理解,而使用纯 Numpy 代码,如

x_all_right = np.roll(x_train, 1, axis=2)

这更有效,虽然稍微不那么直观(只需采用相应的单图像命令版本并增加axis1)。


查看完整回答
反对 回复 2022-10-06
  • 1 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信