sam_yusukeの日記

機械学習について書きます。

データセットのロードや前処理まとめ

自分で収集したデータを使いSkorchやPytorchで学習や評価をさせるのに必要な知識をまとめます。

 

データセットを扱う際の機械学習の基本的な知識

データセット強化の意味と注意点

 機械学習では、テストセットと学習セットがi.i.dに生成されていると仮定されています。となると、データセット強化の意味は学習セットの標本では表現しきれない本来の分布を表現できるように既存の標本から新しい標本を作ることです。図の誤差1を減らす作業に相当すると思います。なので、本来の分布を意識してデータセット強化を考えるべきです。また、誤差2に関しては何度か実行した結果の平均をとったりなどして減らせるのではないかと思います。(数学的にどうなのか調べる。)

 また、データセット強化が正しく元の分布を表現できてることを性能指標の計算に反映するために、テストセットにはデータセット強化を適用しないほうが良いことも想像出来ます。

f:id:sam_yusuke:20181212125531p:plain

 

データの標準化・中心化

基本的に入力データには何らかの処理をします。

画像の場合は中心化すれば十分なようですが、それぞれの特徴量の分散が大きく異なる場合は標準化する必要もありそうです。

標準化・中心化する際の統計量はテストセットや学習セットを生成する本来の分布であるべきなので(数学的に)訓練データと評価データに対して計算するべきかと想います。(できる限り本来の分布の統計量を再現できるように)

 

データセットを扱う際の実装上の基本的な知識

データセットを扱う場合、Linux上かつ大きいメモリ上であればページングがうまく行って、大体データセットはキャッシュされている。心配ならvmtouchなどのツールを使って調べたりキャッシュさせればよいです。

また、Pythonでデータセットに対する処理を並列化する場合、結果が大きいとpickle+unpickleのオーバーヘッドが大きくなって、より多くの時間がかかることがあります。分散化させたい処理の入出力を小さくしたり、分散化されている処理にできるだけ処理を詰め込む工夫が必要になります。

 

データセットに関するライブラリの機能

クラスや関数をざっと説明します。

Pytorch/Torchvision

DataSetクラス

データセットを表すクラスです。独自データセットを扱う場合は、

画像の多クラス分類ならImageFolder、任意のデータの多クラス分類ならDatasetFolder、他クラス多ラベル問題ならなどその他の問題の場合はDatasetクラスを継承して、__len__, __getitem__メソッドを実装すれば良さそうです。

また、Datasetをtorch.util.data.Subsetで部分集合をとったり、, torch.util.data.ConcatDatasetで結合したりも可能です。

(このあたりはもう少し今後便利になることを期待したいです。)

DataLoaderクラス

データセットをシャフルしたりしてバッチにしてくれるクラスです。

ただ、並列ロードは曲者で、TensorDatasetに使うと、pickle/unpickleが遅くなるという問題などもあり、自前で実装したり、並列化をしないほうが早いこともあると思います。

Skorch

PytorchのDatasetクラスをImageClassifierなどに渡してそのまま使えます。

データセットのロード部分はPytorchとSkorchでうまく共通化できそうで、

さすが親和性も高そうです。