Background: This is one of the exercise problems in the text book Hands on Machine Learning by Aurelien Geron.
The question is: Write a function that can shift an MNIST image in any direction (left, right, up, down) by one pixel. Then for each image in the training set, create four shifted copies (one per direction) and add them to the training set.
My thought process:
- I have a numpy array of size (59500, 784) in X_train (Each row is a (28,28) image). For each row of X_train:
- Reshape row to 28,28
- For each direction (up, down, left, right):
- Reshape to 784,0
- Write to empty array
- Append the new array to X_train
My code:
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)
It takes a long time to run. I feel this is brute forcing it. Is there an efficient vector like method to achieve this?