Programming lab

PytorchのDatasetを徹底解説(自作データセットも作れる)

PytorchのDatasetを徹底解説(自作データセットも作れる)

 

 

  • DatasetとDataLoaderあたりから理解できていない…
  • Pandas, NumpyのデータセットからDatasetをどうやって作成するの?

本記事では、その疑問を解決していきます。

PytorchのDatasetとDataLoaderを使用することでミニバッチ勾配降下法(深層学習の学習に必要不可欠)をめちゃくちゃ簡単に実装できます。

そのため、一度DatasetとDataLoaderの使い方に慣れてしまうとなくてはならない存在になります笑笑

本記事では、DatasetとDataLoaderのうちDatasetについて詳しく解説します。

『Dataset, DataLoaderなんて全くわからん…』という方でも理解できるように基本的なところから解説していきます。

 

DataLoaderの基本知識

 

深層学習(Deep Learning)の場合、データが大きくなると計算のコストが大きくなるためデータの一部を使ってパラメータを更新するミニバッチ勾配降下法という手法を使用します。

実際、ミニバッチ勾配法をNumpy等で実装すると結構大変だったりします。

そこで便利なのが、PyTorchのDataLoaderとDatasetです!

簡単に解説していきます。

pytorchのDatasetについて

 

Pytorchのデータセットは、特徴量行列(ラベル以外のデータ)\(\mathbf{X}\)とラベル\(y\)をTensorDatasetというクラスに渡して、特徴量行列とラベルを一つのデータベース的なものにまとめる働きをします。

また、前処理も同時に設定することができます。

このDatasetをDataLoaderに渡すことでDataLoaderを使用することができます。

 

pytorchのDataLoaderについて

 

PytorchのDataLoaderを使うことで、データの一部(ミニバッチ)をランダムに取り出すことができます。

DataLoaderは、配列ではなくイテラブルとなり、For文等でデータを取り出すことができます。

今回は、Datasetに関して詳しく説明していきます。

 

pytochのDatasetを使用するためのライブラリをインポート

 

まずは、PyTorchのDatasetを使用するためのライブラリをインポートしましょう。

下記のコードを実行してください。

import torch
import torchvision
import torchvision.transforms as transforms
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

 

matplotlibとnumpyは、Datasetを作成するために必要不可欠なライブラリではありませんが、本記事では適宜利用するのでインポートしました。

『numpy, matplotlibがよくわからない…』という方は下記を参考にしてください。

 

 

pytochのサンプルデータセットを使用する方法

 

PyTochのサンプルデータを使用する場合は、最初からTensorDatasetとなって出力されます。

今回は、具体例としてMNISTデータセットをインポートしていきます。

下記のコードを入力することでMNISTデータがインポートされます。

<Input>

MNIST = torchvision.datasets.MNIST(root='./data',
                                        train=True,
                                        transform=transforms.ToTensor(),
                                        download=True)

 

具体的な引数について説明していきます。

MNIST Dataset  
root データをインポートするディレクトリを指定
train Trueにすると訓練データ、Falseにするとテストデータとしてインポート
transform 使用する前処理を指定する
download Trueにするとデータをダウンロードして『root』で指定したディレクトリに保存する

 

実際に、『MNIST』みてみましょう。

<Input>

print(MNIST)

 

<output>

Dataset MNIST
    Number of datapoints: 60000
    Root location: ./data
    Split: Train
    StandardTransform
Transform: ToTensor()

 

このようにデータの情報がDatasetには格納されています。

あとは、このDatasetをDataLoaderに渡して完了です。

pandas, numpyのデータからpytorchのDatasetを作成する

 

本章では、Pandas, Numpyからデータセットを作成する方法を紹介していきます。

以下の順番で説明していきます。

  1. NumpyのデータをPytorchのDatasetへ
  2. PandasのデータをPytorchのDatasetへ

 

NumpyのデータをPytorchのDatasetへ

 

本節では、NumpyのデータをPytorchのDatasetへ変換する方法を紹介していきます。

 

Numpyサンプルデータのロード

 

今回は、サンプルとして手描き文字データを使用するので下記のコードでロードしてください。

from sklearn.datasets import load_digits
digits=load_digits()

 

ロードしたデータを特徴量とラベルに分けます。

# 特徴量
X = digits.data
# ラベル
y = digits.target

 

実際にXとyの値をみてみましょう。

<Input>

# 特徴量
fig, ax = plt.subplots()
ax.imshow(X[0].reshape(8,8), cmap='gray')
ax.axis('off')
plt.show()

 

<Output>

numpyのサンプルデータ

ラベルも見てみましょう。

<Input>

y[0]

 

<output>

0

 

PytochのDatasetに変換

 

PytorchのDataset型に変更するためには、Numpyの配列をTensorに変換します。

ここで注意するポイントがあります。

変換をする際は、小数は『torch.float32型』、整数は『torch.int64型』にしてください(予期しないバグに繋がります)

下記のコードで型を指定してTensorに変換することができます。

# Tensorに変更
X = torch.tensor(X, dtype=torch.float32)
y = torch.tensor(y, dtype=torch.int64) 

 

今回、Xは小数、yは整数なので上記のように変換しました。

また、FloatTensorとLongTensorを使用して以下のように変換することもできます。

X = torch.FloatTensor(X)
y = torch.LongTensor(y)

 

FloatTensor、LongTensorを使用することで、適切な型でTensorに変換できます。

どちらを使用しても良いです。

次に、DatasetをTensorDatasetを使用して作成します。

# Datasetを作成
Dataset = torch.utils.data.TensorDataset(X, y)

 

次に、Pandasのデータセットを変換する方法を紹介します。

 

PandasのデータをPytorchのDatasetへ

 

本節では、PandasのデータをPytorchのDatasetへ変換する方法を説明します。

まずは、サンプルデータをロードします。

import seaborn as sns
iris = sns.load_dataset('iris')

 

今回は、seabornというライブラリからirisデータセットをロードしました。

『seaborn?』という方は下記の記事を参考にしてください。

 

【15分で習得】seabornの使い方を徹底解説seabornを使用することで、簡単に高度なグラフを描画することができます。また、使用方法もmatplotlibと変わらず簡単に行うことができます。...

 

実際にデータを見てみましょう。

<Input>

iris.head()

 

<Output>

 

カテゴリ変数があるので、数値に変化する前処理を行います。

<Input>

# カテゴリ変数を変換
iris.loc[:, 'species'] = iris.loc[:, 'species'].map({'setosa':0, 'versicolor':1, 'virginica':2})
iris.head()

 

<output>

pandasのサンプルデータ前処理後

これで、『species』を数値にすることができました。

今回は、特徴量を『sepal_length, sepal_width, petal_length, petal_width』とし、ラベルを『species』としてDatasetを作成していきます。

 

Pytorchのデータセットに変換

 

Pandasデータセットは、直接データセットに変更できないので、PandasをNumpy配列に変換してからDataset型に変換します。

PandasのDataFrameをNumpy配列に変換するには、『values』というメソッドを使用します。

それ以外は、変更点はなく以下のようにTensorに変更できます。

# valueでnumpy配列として取り出せる
y = torch.FloatTensor(iris['species'].values)
X = torch.LongTensor(iris.drop('species', axis=1).values)

 

あとは、TensorDatasetを使用すれば、Datasetの完成です。

# Datasetを作成
Dataset = torch.utils.data.TensorDataset(X, y)

 

ここまでが、基本的なDatasetの作成方法です。

しかし、機械学習のコンペ等のコードを見ると、上述のような記述法はほとんど使われていません。

一般的には、もっと便利な自作Datasetというものを作成します。

次章で、『自作Dataset』と呼ばれる独自でDatasetを作成してモジュール化します。

とりあえず、Pytorchを入門したばかりという方は、ここまでで一度休憩し、DataLoaderやネットワークの作成方法を学んでから次章を読み直すことをお勧めします。

 

Pytorchの独自Datasetを作成する

 

本章では、簡単な独自Datasetを作成する方法を説明します。

自作Datasetを使用することで、前処理(Transformer)等を細かくカスタマイズすることができます。

では、実際に作成していきましょう。

 

自作Datasetを作成する方法

 

自作データセットを作成するには、PytorchのDatasetクラスを継承する必要があります。

さらに、独自データセットを作成する際には、『__len__(), __getitem__()』を必ず作成します。

  • __len__() : len()を使った時に呼ばれる関数
  • __getitem__() : 要素を参照するときに呼ばれる関数

 

実際にコードをみてみないとわからないと思うので先ほど使用したIrisiデータセットをDataset化する独自Datasetを作成してみましょう。

class MyDataset(torch.utils.data.Dataset):
    def __init__(self, df, features, labels):
        self.features_values = df[features].values
        self.labels = df[labels].values

    # len()を使用すると呼ばれる
    def __len__(self):
        return len(self.features_values)

    # 要素を参照すると呼ばれる関数    
    def __getitem__(self, idx):
        features_x = torch.FloatTensor(self.features_values[idx])
        labels = torch.LongTensor(self.labels[idx])
        return features_x, labels

 

これは私が作成したデータセットで、コンストラクタ引数としては以下を設定しました。

MyDataset ここに説明文を入力してください。
df 使用するDataframe
features 特徴量の名前
labels ラベルの名前

 

実際にインスタンス化しましょう。

# 特徴量の名前
features = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']
# ラベルの名前
label = ['species']

Dataset = MyDataset(iris, features, label)

 

これでDatasetが作成できます。

実際に、『__len__(), __getitem__()』の挙動を見てみましょう。

まずは、len()を使用してみます。

<Input>

len(Dataset)

 

<output>

150

 

次に、要素を参照してみます。

<Input>

Dataset[0]

 

<output>

(tensor([5.1000, 3.5000, 1.4000, 0.2000]), tensor([0]))

 

最初のデータが参照されましたね。

 

自作データセットに前処理を設定できる

 

適当な前処理を自作データに設定することができます。

今回は、簡単な『transformer』を作成して、そのtransformerが、データが参照されたときに機能するようなDatasetを作成してみます。

まずは、自作のtransformerを作成します。

今回は、簡単のため入力した値を二乗するようなtransformerを作成します。

# 自作transformer
class Square(object):
    def __init__(self):
        pass
    def __call__(self, x):
        x = x**2 
        return x

 

この前処理を先ほどのirisデータセットを読み込むためのMyDatasetに加えます。

class MyDataset(torch.utils.data.Dataset):
    def __init__(self, df, features, labels, transform=None):
        self.features_values = df[features].values
        self.labels = df[labels].values
        self.transform = transformer

    # len()を使用すると呼ばれる
    def __len__(self):
        return len(self.features_values)

    # 要素を参照すると呼ばれる関数    
    def __getitem__(self, idx):
        features_x = torch.FloatTensor(self.features_values[idx])
        labels = torch.LongTensor(self.labels[idx])

        # 前処理を施す
        if self.transform:
            features_x = self.transform(features_x)
        
        return features_x, labels

 

では、自作transformerと自作Datasetをインスタンス化してみましょう。

# 特徴量の名前
features = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width']

# ラベルの名前
label = ['species']

# transformer(Square)のインスタン化
transformer = Square()

Dataset = MyDataset(iris, features, label, transform=transformer)

 

実際にTransformerが機能したのかを確認してみましょう。

<Input>

Dataset[0]

 

<output>

(tensor([26.0100, 12.2500,  1.9600,  0.0400]), tensor([0]))

 

このようにしっかり2乗されています!

このような処理は、画像処理の時は頻繁に行うため覚えておくと良いです。

お疲れ様です。これで、自由自在にDatasetが使えるようになりますね。

 

参考文献・参考URL

 

本章では、参考文献と参考URLを紹介してきます。

 

参考文献

 

参考文献を紹介します。

 

PyTorchニューラルネットワーク 実装ハンドブック

 

Pytorchのバイブルです。買っておいて損はないです。

 

現場で使える!PyTorch開発入門 深層学習モデルの作成とアプリケーションへの実装

 

Tensorの基本から高度な技術まで学べます。

 

参考URL

 

 

それ以外にも、Udemyによるコースも参考にさせていただきました。

PytorchのためのUdemyコースに関しては下記を参考にしてください。

【東大生が厳選】UdemyでおすすめのPythonコース10万を超える講座があるUdemyの中でPythonに関係する講座を厳選してみました。また、本記事では、Udemyを使用しながらPythonをどのような順番で勉強するべきかを紹介しました。ぜひ参考にしてください。...

 

まとめ

 

今回は、PytorchのDatasetを作成する方法を徹底的に説明しました。

Datasetは意外と複雑ですが、一度理解してしまうと便利すぎて手放せない存在になります。

おそらく、自作Dataset作成まで理解した方は、何となく便利さに気がつきましたかね?

この記事が皆様にとって有益であることを願います…

 

ABOUT ME
努力のガリレオ
【運営者】 : 東大で理論物理を研究中(経歴)東京大学, TOEIC950点, NASA留学, カナダ滞在経験有り, 最優秀塾講師賞, オンライン英会話講師試験合格, ブログと独自コンテンツで収益6桁達成 【編集者】: イングリッシュアドバイザーとして勤務中(経歴)中学校教諭一種免許取得[英語],カナダ留学経験あり, TOEIC650点