[小ネタ]同じMNISTでもデータの型が違う?

同じMNISTのデータセットでも、データの型は使用したライブラリで違います。それらのライブラリの差異があってもデータが使えるように変換方法をお伝えします。
2022.08.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

皆さん、こんにちは。hotoke_nekoです。

今回はMNISTのloadメソッドで取得したデータセットに関する記事です。

きっかけ

Kerasを使用している公式サイトのサンプルを動かしていました。

その際に、KerasのモデルだけでなくPytorchのモデルでもKeras側のloadメソッドで手に入れたデータを使ってtrainingできるのか試したところエラーが発生しました。

同じデータセットでも、どうやら何か違うようです。

何が違うの?

早速コードで確かめてみましょう。

まずは必要なライブラリをimportしましょう。

import tensorflow as tf
from tensorflow import keras
print(tf.__version__)

import torch
from torch.utils.data import Dataset, DataLoader
from torchvision import datasets, transforms
print(torch.__version__)

次にデータの準備です。

# Pytorchでデータを取得
pytorch_mnist_train = datasets.MNIST("../data", train=True, download=True, transform=transforms.ToTensor())

# Kerasでデータを取得
keras_mnist = keras.datasets.mnist
(keras_mnist_train, keras_mnist_train_labels), (keras_mnist_test, keras_mnist_test_labels) = keras_mnist.load_data()

そして準備したデータをprintメソッドとtypeメソッドを使ってデータの型を確認してみます。

## Pytorch
print("Pytorchの型と内容を確認")
print(type(pytorch_mnist_train))
print(pytorch_mnist_train)

print('-----------------------------------')

## Keras
print("Kerasの型とshapeを確認")
print(type(keras_mnist_train))
print(keras_mnist_train.shape)

保存されているファイル数は同じ60000でした。MNISTクラスという型とndarray型というように異なっている事が確認できました。

変換方法

上述した通り、データの型が異なります。そのため、最初からPytorchやKerasにあった型のデータが用意できる場合は、そちらを使うようにすれば良いです。ただ、実装途中で使用するライブラリを変更すると、データを新しく用意する事が大変な場合もあるかと思います。そういった場合は、型を変換していく事が必要となります。

今回は実験として、MNISTクラスからndarray型へ変換してみます。

より一般的には、Pytorchではtorch.Tensor型のデータを使いますので、そちらに関連する変換方法もお伝えします。

MNISTクラスからndarray型の変換方法

MNISTクラスからndarray型への変換方法は次のようにすると可能でした。

# DataLoaderを準備
pytorch_train_loader = DataLoader(pytorch_mnist_train, batch_size = 100, shuffle=True)
pytorch_test_loader = DataLoader(pytorch_mnist_test, batch_size = 100, shuffle=False)

import numpy as np

for x in pytorch_train_loader:
  print(type(x))
  print(type(np.array(x)))

変数pytorch_mnist_trainはDataLoader型に変換されます。次に、for文で取り出すとlist型のデータが取得できます。

list型はnp.arrayメソッドを用いるとndarray型へ変換が可能です。

したがって、for文内でndarray型に変換したものを格納する変数を用意すれば、全データをndarray型に変換したものが取得可能です。

Tensor型とndarray型の変換方法

まずndarray型からTensor型への変換方法を紹介します。

import torch
import numpy as np
to_tensor = torch.from_numpy(keras_mnist_train).clone()
print(type(to_tensor))
print(to_tensor)

最後に、Tensor型からndarray型への変換方法を紹介します。

import torch

# Tensor型のデータが無いので用意
tensor_val = torch.randn(10)
print(type(tensor_val))
print(tensor_val)

print("numpy.ndarrayへ変換")
to_numpy = tensor_val.to('cpu').detach().numpy().copy()
print(type(to_numpy))
print(to_numpy)

どのデータ型への変換も、Pytorchに関係するメソッドなどを使うと目的の型へ変換できました。

終わりに

今回は、実験としてMNISTクラスからndarray型へ変換してみました。また、より一般的なTensor型に関わる変換についてもご紹介しました。

学習させるためのデータの型が違う時に、この記事が参考になれば幸いです。

今回はここまで。

それでは、また!