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

Давайте сначала продемонстрируем операции:
# 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)
, который более эффективен, хотя и немного менее интуитивен (просто возьмите соответствующие версии команд с одним изображением и увеличьте axis
на 1).