MNISTのresize

MNSITの次元を落とす時

落とし方には2つあります。

  1. 周辺のあたいの平均をとる
  2. どのデータでも変化しない必要のないあたいを落とす

ここでは、1つ目を考えます。openCVでresizeしてしまいます。 まずはimport しておく。

from tensorflow.python.keras.datasets import mnist
import cv2

全てのデータ(train, test)をまとめて扱います。

(X_train, y_train), (X_test, y_test) = mnist.load_data()
y_train = to_categorical(y_train,10)
y_test = to_categorical(y_test, 10)
X_ori = np.vstack([X_train.reshape(X_train.shape[0], 28*28), X_test.reshape(X_test.shape[0],28*28)])    #convert to binary
y_ori = np.vstack([y_train, y_test])

これでデータを全て取れました。 次に1つ1つのデータをresizeする関数を作っておきます。

def resize(dataset, i, scale):
    X = dataset[i]
    width = int(np.sqrt(len(X)))
    X = X.reshape(width, width)
    assert int(width*scale) == width*scale, "the size of rescale, width*scale is not int"
    newScale = int(width*scale)
    scaled = cv2.resize(X, dsize=(newScale, newScale))
    return np.ravel(scaled)

これを利用してまとめてやるときはfor で回します。あまり時間はかかりません。

def allResize(dataset, scale=0.5):
    assert len(dataset.shape) == 2, "this dataset doesn't have 2 dimansion"
    new_feature = dataset.shape[1]*scale*scale
    assert int(new_feature) == new_feature, "the shape of dataset is not int"
    scaled_dataset = np.empty([dataset.shape[0], int(new_feature)])
    for i in range(len(dataset)):
        scaled_dataset[i] = resize(dataset, i, scale)
        
    return scaled_dataset

if __name__ == "__main__":
    new_mnist = allResize(X_ori, 0.5)
    # show
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.imshow(new_mnist[0].reshape(14, 14), cmap="gray")
    plt.show()

実際の結果

変更前

f:id:endosan:20190625174816p:plain

変更後

f:id:endosan:20190625174837p:plain