pylearn2を使ってcsvデータを学習させてみた

August 08, 2015

最近、何かと話題になっているDeep Learningに興味をもち、pylearn2の勉強を始ました。とりあえず、自前で適当に作ったcsv形式の学習データをpylearn2で学習させてみることから始めましたが、いろいろとはまりましたのでメモを残しておきます。

まず、学習データをcsvで作成しました。1列目に分類カテゴリ(クラス)、2列目以降にn次元の特徴ベクトルを記述するようなフォーマットです。テスト用なので、今回は下記のようなスクリプトを作り、機械的にランダムでデータを生成しました。面倒なので、ヘッダ(各カラムの説明)は出力していません。

import numpy as np
import pandas as pd

nsample = 60000
xdim = 10
data = pd.DataFrame(
  np.random.randn(nsample, xdim),
  index = np.random.randint(0,2,nsample))
data.to_csv('train.csv', header=False)

次に、pylearn2をインストールするとついてくる、csvをロードしてくれるCSVDatasetを使ってみたのですが、うまくいきません。いろいろ試してみたのですが、どうしても下記のようなエラーが出てしまいます。

TypeError: Cannot safely cast batch dtype float64 to space's dtype int64.

で、結局CSVDatasetは使わず、自前で下記のようなローダクラスを用意しました(ここを参考にさせていただきました)。

import numpy as np
from pylearn2.datasets import DenseDesignMatrix

class MYCSVDataset(DenseDesignMatrix):
    def __init__(self,
                 path='train.csv',
                 delimiter=',',
                 start=None,
                 stop=None):
        self.path = path
        self.delimiter = delimiter
        self.start = start
        self.stop = stop
        X, y = self._load_data()
        super(MYCSVDataset, self).__init__(X=X, y=y)
        super(MYCSVDataset, self).convert_to_one_hot()

    def _load_data(self):
        data = np.loadtxt(self.path, delimiter=self.delimiter)
        start = 0
        stop = data.shape[0] - 1
        if self.start is not None:
            start = self.start
        if self.stop is not None:
            stop = self.stop
        X = data[start:stop, 1:]
        y = data[start:stop, 0].astype(int)
        return X, y

pylearn2のtrainスクリプトに学習させるため、pylearn2のチュートリアルを参考に下記のようなyamlを作成します。今回はモデルにSoftmax関数を使っています。

!obj:pylearn2.train.Train {
    dataset: &train !obj:mycsv_dataset.MYCSVDataset {
}
,
    model: !obj:pylearn2.models.softmax_regression.SoftmaxRegression {
    n_classes: 2,
    irange: 0.,
    nvis: 10,
}
,
    algorithm: !obj:pylearn2.training_algorithms.bgd.BGD {
        batch_size: 10000,
        line_search_mode: 'exhaustive',
        conjugate: 1,
        monitoring_dataset:
            {
                'train' : *train,
                'valid' : !obj:mycsv_dataset.MYCSVDataset {
                          },
                'test'  : !obj:mycsv_dataset.MYCSVDataset {
                          }
            },
        termination_criterion: !obj:pylearn2.termination_criteria.MonitorBased {
            channel_name: "valid_y_misclass"
        }
    }
,
    extensions: [
        !obj:pylearn2.train_extensions.best_params.MonitorBasedSaveBest {
             channel_name: 'valid_y_misclass',
             save_path: "softmax_regression_best.pkl"
        },
    ],
    save_path: "softmax_regression.pkl",
    save_freq: 1
}

ここまでくればあとはtrainスクリプトにyamlを食わせて実行するだけです。

export PYTHONPATH=.
pylearn2-train train.yaml

エラーが出ずに学習結果のsofmax_regression_best.pklが出力されれば成功です。今回は適当な学習データを用いましたが、例えば分類カテゴリを数字(0〜9)、特徴ベクトルを0〜9の手書き文字の画素値列にして同様の手順を踏めば、文字認識用のモデルを学習させることも可能かと思います。