備忘録とか日常とか

機械学習を勉強中。ベース日々練習中。

theanoに使う自前データセットの準備

DeepLearningTutorialで勉強中。
このチュートリアルではMNISTのデータセットで実験を行っているが、自前のデータセットを使うときに自分でcPickleする必要があるのでメモ。

このページがtheanoの使い方をわかりやすく書いている。
Theano 入門


普段pythonで画像を読み込むときはPILを使っているが、PIL->numpyとして行列にすると(row,column,channel)の形になっている。
データセットとして読み込むには(channel,row,column)にする必要があるので変換する。

import numpy as np
from PIL import Image
img = np.array(Image.open("path/to/img"),"f")
out_img = img.transpose(2,0,1)
out_img = out_img.flatten()

numpyのtranspose()で次元を入れ替えれるのを最近知って驚いた。それまでわざわざnp.zeros()で別の行列定義して一個ずつ代入してたので・・・


その後numpy.ndarrayに格納してcPickleする。
チュートリアルでは画像とラベルをndarrayに入れてから、(画像データ, ラベル)としたタプルに格納していた。
画像データのndarrayには1行ごとに1枚の画像が入り、 row=画像数、column=画像の次元数 となる。ラベルはint型で。

data = ...    # dataに保存するobjectを入れとく
import cPickle
save_file = open("path", "wb")
cPickle.dump(data, savefile, -1)
save_file.close()

読み込むときは

save_file = open("path")
data = cPickle.load(save_file)

でおけ


そうして読み込んだ画像データをndarray、asarrayで成形してからsharedVariable(共有変数)で保存する。

shared_x = theano.shared(np.asarray(data,dtype=theano.config.floatX), name="shared_x", borrow="True") 
shared_y = theano.shared(np.asarray(label,dtype=theano.config.floatX), name="shared_y", borrow="True") 

共有変数は必ずfloatX型にしなければいけないらしい。
ラベルはint型のほうが都合がよいので、値を取り出して扱うときは別な方法で行う。

import theano.tensor as T
x = shared_x.getvalue()
y = T.cast(label,"int32")

castするとtensorVariableというのに変わってしまう。get_value()で値を取得できなくなるので注意。