機械学習・ニューラルネットワークにおいて、データを用意・ロードすることは簡単そうに見えて難しい。
- corpusのダウンロード・展開
- データの前処理・保存
- データセット(processed corpusの部分集合)のセットアップ
- datumのロード
- アクセス順・バッチ化
- 分散dataset
考えることいっぱい。
fileSystemからデータをメモリ上に展開 (ロード) しまくるとメモリ弾けるし、毎回のんびり前処理かけてたら日が暮れる。
並行して学習をする際に適切にデータを配分する必要もある。
コーパス ~ バッチの定義
コーパスを前処理してデータセットとし、データセットを変換してバッチテンソルとする.
Preprocess Transform Corpus -----------> Dataset -----------> Batch
Corpus :: [any] = {i0, i1, ...}
Preprocess :: (i ∈ C' ⊂ Corpus) -> (x: any)
Dataset :: [any] = {Preprocess(i) | i ∈ C' ⊂ Corpus}
Transform :: (x ∈ Dataset) -> (x' :: T)
Batch :: [T] = {Transform(x) | x ∈ D' ⊂ Dataset}
分割の意義
(配布される)データ源としてのCorpus.
データを様々な特徴量へ事前変換 (preprocessing) したDataset.
Transformによる逐次変換とデータ型統一(テンソル化)、ここから得られるBatch.
変換: 事前 (preprocess) / 逐次 (transform)
逐次変換で都度異なるデータを生成可能 (例: clipping)
事前変換で生成したデータの型が異なっていても、逐次変換でテンソル化が可能 (T=100とT=120のデータを、length=40のランダム区間に逐次clip).
PyTorch
- DataSet: datumの取り出しが可能なオブジェクト
- DataLoader: Datasetから様々な設定でデータを取り出すようにできるiterable
Dataset
Dataset
をベースクラスとする薄いデータwrapper。
- Map-style datasets
Dataset
: Python シークエンス/マッピング(__getitem__
) - Iterable-style datasets
IterableDataset
: Python イテレータ(__next__
)
のいずれかでデータ集合を表現する。
Dataset
は抽象クラスになっており、実装者がデータセットごとに読み込み等を実装する。
Utilityとしてデータセットの結合(ConcatDataset for dataset / ChainDataset for iterSet)と分割(Subset / random_split)が提供されている。
corpusのダウンロードや前処理(preprocessing, データセット化と私は呼んでいる)をdatasetのinitに書くのがベストプラクティス.
new dataset()するだけでデータが手に入り、再利用性が高い.
augmentationを始めとする「feed時に逐次実行してほしい関数」はdataset内にtransformとして実装.
データロードのタイミングは実装次第。
__init__
でon-memoryに置いて高速アクセスを可能にしてもいいし、__getitem__
で逐次datumを読み込んでメモリ節約してもいい.
実装
torch.utils.data.Dataset
Dataset
は __add__
がmixed inされたMapping型。
なので利用時は Dataset
を継承してdatumを吐き出す __getitem__
と全長を返す __len__
を実装する。
__add__
は Dataset
の合体を定義しており、暗示的に ConcatDataset
を実行する。
DataLoader
index setの供給 (sampler) と、index setに基づくdatumのset化 (collate_fn).
samplerをいじれば同じindexを出したり、indexの出る順番にバイアス (weight random sample的な) をかけたりできる.
collate_fnをいじればバッチ化をやめたり、バッチの形を任意にいじったり、データ自体に手を入れたりできる.
デフォルトではshuffleフラグに基づいたランダムサンプル、データTensor化&バッチ化のcollate_fn.
デフォルトcollate_fnは自動Tensor化をしてくれるので便利だが、謎挙動に見えなくもないので頭の片隅に.
It automatically converts NumPy arrays and Python numerical values into PyTorch Tensors.