最近、何かと話題になっている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の手書き文字の画素値列にして同様の手順を踏めば、文字認識用のモデルを学習させることも可能かと思います。