Skip to content

Instantly share code, notes, and snippets.

@peace098beat
Created October 22, 2015 04:26
Show Gist options
  • Save peace098beat/a0cd1235c757e63d7869 to your computer and use it in GitHub Desktop.
Save peace098beat/a0cd1235c757e63d7869 to your computer and use it in GitHub Desktop.
[Theano] はじめてのTheano
#! coding:utf-8
"""
Theanoの使い方
Theano で Deep Learning <1> : MNIST データをロジスティック回帰で判別する
http://sinhrks.hatenablog.com/entry/2014/11/26/002818
"""
import numpy as np
import theano
import theano.tensor as T
from LogisticRegression import LogisticRegression
n_in, n_out = 3, 1
## Theanoのメモリ空間
# ==================
# Theanoメモリ空間に共有変数Wを定義
W = theano.shared(
value=np.zeros(
(n_in, n_out),
dtype=theano.config.floatX
),
name='W',
borrow=True
)
# print W
# W
# もしnumpyだとこう記述する
W = np.zeros((n_in, n_out), dtype=np.float64)
# print W
# [[ 0.]
# [ 0.]
# [ 0.]]
# ====================================
## theano.shared による共有変数の定義
# ====================================
# 上でも指定されている引数 borrow は
# Python 空間上で定義されたデータの実体を 共有変数でも共有するかどうかを決める。
# Python空間で変数定義
x = np.array([1, 1, 1])
# theano.sharedで共有変数化
# 返り血は int32/vectorのTensorSharedVariable型
xs = theano.shared(x)
print xs
# <TensorType(int32, vector)>
print type(xs)
# <class 'theano.tensor.sharedvar.TensorSharedVariable'>
# 内部の値を得るためにはget_value
print xs.get_value()
# array([1, 1, 1])
# デフォルトでは、対象オブジェクトの"コピー"が、共有変数の実体になるので、
# Python空間の変数を変更しても共有変数の実態には影響しない
x[1] = 2
print x
print xs.get_value()
# 同じ実体を共有したい場合はborrow=True
xs = theano.shared(x, borrow=True)
print xs.get_value()
x[1] = 3
print x
print xs.get_value()
# ================================
# theano.tensor 上の関数の呼び出し
# ================================
# -----------
# Softmax関数
# -----------
d = theano.shared(
value=np.matrix([[0.1, 0.2, 0.3],
[0.3, 0.2, 0.1],
[0.1, 0.2, 0.3]],
dtype=theano.config.floatX),
name='d',
borrow=True)
sm = T.nnet.softmax(d)
print sm
print type(sm)
# 関数を評価するには
print sm.eval()
# --------------------------------
# argmax : 値が最大となる"ラベル"を返す関数
# --------------------------------
am = T.argmax(np.array([1, 2, 3, 2, 1]))
print type(am)
print am.eval()
# ==============================
# LogisticRegressionクラスの作成
# ==============================
# double型のスカラー値
x = T.dscalar('x')
# y = x ** 2という関数を宣言
y = x ** 2
# yをxについて微分
gy = T.grad(y, x)
print gy
# gyの導関数を確認
print theano.pp(gy)
# ((fill((x ** TensorConstant{2}), TensorConstant{1.0}) * TensorConstant{2}) * (x ** (TensorConstant{2} - TensorConstant{1})))
# ((fill((x ** {2}), {1.0}) * {2}) * (x ** ({2} - {1})))
# fillは第一引数に第二引数を代入する
# {1}**{2})*{2}) * (x ** {1})
# {2} * x
# = 2x !!!
# 関数を使う
f = theano.function([x], gy)
print f(4)
# ロジスティック回帰の定義/学習をテンソルで書きなおす
# ミニバッチ確率降下法で指定するindex(スカラー)を入れるシンボル
index = T.lscalar()
# 入力データの行列を示すシンボル
x = T.matrix('x')
# ラベルのベクトルを示すシンボル
y = T.ivector('y')
# ロジスティック回帰の処理もtheano.tensorの関数で定義されているため、シンボルxが実データ無しで渡せる
classifier = LogisticRegression(input=x, n_in=28 * 28, n_out=10)
# 引数yもシンボル。返値costでは負の対数尤度を計算する式が返ってくる
cost = classifier.negative_log_likelihood(y)
# w, bの勾配を計算する式
g_W = T.grad(cost=cost, wrt=classifier.W)
g_b = T.grad(cost=cost, wrt=classifier.b)
# w,bの更新を定義する式
updates = [(classifier.W, classifier.W - learning_rate * g_W),
(classifier.b, classifier.b - learning_rate * g_b)]
# 学習器
# :inputs:
train_model = theano.function(
inputs=[index],
outputs=cost,
updates=updates,
givens={
x:train_set_x[index*batch_size : (index+1)*batch_size],
y:train_set_y[index*batch_size : (index+1)*batch_size]
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment