utsubo’s blog

競技プログラミングとか.

kaggleのDigit Recognizerへ初提出(Chainer)

はじめに

kaggle -Digit Recognizer
Digit Recognizer | Kaggle
kaggle初提出までしたことをとりあえずまとめます.

初提出まで

まずは軽くお勉強

ニューラルネットワークと深層学習
http://nnadl-ja.github.io/nnadl_site_ja/index.html
さすがに何もわかっていない状態でサンプルを動かすだけだと無意味そうだったので少しお勉強.
式は完全には追わずに何故この関数なのかみたいな部分だけ拾い読みしました.今後ちゃんと式も理解したい.

実装

まずは,訓練データ等をkaggleからダウンロードしてくる.
NNのモデルは各層ニューロンの数を以下のように適当に決めて実装.
また,コスト関数はクロスエントロピーコスト関数を導入.

input hidden1 hidden2 output
784 1000 1000 10

modelはこんな感じ.

class MyChain(Chain):
	def __init__(self):
		super(MyChain,self).__init__(
			l1 = L.Linear(784,1000),
			l2 = L.Linear(1000, 1000),
			l3 = L.Linear(1000,10)
		)
	def __call__(self, x):
		h1 = F.sigmoid(self.l1(x))
		h2 = F.sigmoid(self.l2(h1))
		h3 = self.l3(h2)
		return h3
class Classifier(Chain):
	def __init__(self,predictor):
		super(Classifier,self).__init__(predictor=predictor)
	def __call__(self,x,t):
		y = self.predictor(x)
		loss = F.softmax_cross_entropy(y,t)
		return loss,F.accuracy(y,t)

訓練データを読み込んで,実際にモデルを学習させます.
まず,MacBookAirでやるには訓練データのサイズが大きすぎるので,先頭1000行ぐらいを切り分けする.

head -n 1000 train.csv > small_train.csv

訓練データをpandasを使ってpythonに入力.

traindata = pd.read_csv(train_filename).values
x_data = np.array([row[1:] for row in traindata]).astype(np.float32)
y_data = np.array([row[0] for row in traindata]).astype(np.int32)

モデルの定義.

model = Classifier(MyChain())
optimizer = optimizers.SGD()
optimizer.use_cleargrads()
optimizer.setup(model)

学習,バッチサイズは5として,20回回す.(ここはTrainerを使った方が良いのかな)

batchsize = 5
datasize = len(x_data)
for epoch in range(20):
	print "epoch %d" % (epoch)
	indexes = np.random.permutation(datasize)
	for i in range(0,datasize,batchsize):
		x = Variable(x_data[i:i+batchsize])
		t = Variable(y_data[i:i+batchsize])
		optimizer.update(model, x, t)

学習したモデルで提出用ファイルを出力.

def submit(model):
	f = open('submit.csv','w')
	f.write("ImageId,Label\n")
	testdata = pd.read_csv("./csv/test.csv").values
	x_data = np.array(testdata).astype(np.float32)
	datasize = len(x_data)
	for i in range(datasize):
		x =  Variable(x_data[i:i+1], volatile='on')
		y = np.argmax(model.predictor(x).data[:])
		f.write("%d,%d\n" % (i+1,y))
	f.close()

提出

f:id:utsubo_21:20170421161221p:plain
訓練データを全て使わなくても88%とそこそこな値が出て満足しています.

感想

色々なサイトを見た結果公式ドキュメントが一番わかりやすくまとまっているのかなと思いました.
サンプルを見ないでやると割りとハマりポイントがあってちゃんと動いた時に達成感があったので,こんな感じで勉強を進めて行きたいです.

実装に参照した本とリンク