深さ学習アルゴリズム実践4---Theano常用テクニック


前の文章では、ニューラルネットワークセンサモデルで使用されているいくつかのアルゴリズムを紹介しました.この文章では、これらの一般的なアルゴリズムを引き続き紹介します.まず、ランダム数の生成です.センサモデルはランダム数で接続権値を初期化しなければならないので、次に導関数を求めます.センサ学習アルゴリズムは、勾配降下アルゴリズムを用い、導関数を求める問題に関連しているからです.
乱数生成アルゴリズムを議論する前に、共有変数について議論します.これはC言語の静的変数に似ています.ウェブサイトのコンテンツの熱を統計的に分析するとします.ホットをhottnessで表し、アクセスの重みをvisitWeightで表します.ユーザーがそのコンテンツにアクセスするたびに、そのコンテンツに対応するhottnessはvisitWeightを増加します.Theanoを使用すると、次のコードで実現できます.
import theano
import theano.tensor as T
from theano import function
from theano import shared

hottness = shared(0)
visitWeight = T.iscalar("visitWeight")
calculateHottness = function([visitWeight], hottness, updates=[(hottness, hottness + visitWeight)])
minusValue = T.iscalar("minusValue")
decreaseHottness = function([minusValue], hottness, updates=[(hottness, hottness - minusValue)])


visitWeight1 = 5
calculateHottness(visitWeight1)
print("hottness=%d" % hottness.get_value())
visitWeight2 = 10
calculateHottness(visitWeight2)
print("hottness=%d" % hottness.get_value())
minusValue1 = 3
decreaseHottness(minusValue1)
print("hottness=%d" % hottness.get_value())

hottness.set_value(0)
print("hottness=%d" % hottness.get_value())

上記のコードを実行すると、5と15の2つの値が得られ、共有変数が機能していることを示します.熱値を繰り返す場合、統計サイクルが終了するとhottnessを呼び出すだけです.set_value(0)は実現できるが,我々のシステムが踏む機能が,踏むたびに熱が一定値低下すると仮定すると,新しいdecreaseHottness関数を定義することができ,2つの関数は同じhottness変数を共有することができる.
いくつかの内容があると仮定して、私たちはユーザー採点システムを採用して、1~5点に分けて、ユーザーは毎回採点して、熱にユーザーの採点値を加えて、上述の論理を再利用するために、hottnessに使う場所を、新しい変数、例えばscoreに変えるだけでいいです.コードは以下のようにします.
newHottness = hottness + visitWeight
score = T.scalar(dtype=hottness.dtype)
calculateScore = function([visitWeight, score], newHottness, givens=[(hottness, score)])
print("score=%d; hottness=%d!" % (calculateScore(5, 100), hottness.get_value()))
ではscoreの値が105であることが正しく計算され、hottnessの値は元の値と変わらない.
明らかに、プロジェクトユーザーのスコアの合計を統計するには、Theanoの関数コピーメカニズムを使用してhottnessを新しいrateScoresに置き換え、visitWeightがユーザーのスコア値に対応する場合、次のコードがこの目的を達成します.
rateScores = shared(0)
calculateRateScores = calculateHottness.copy(swap={hottness: rateScores})
calculateRateScores(5)
print("rateScores=%d" % rateScores.get_value())
では、Theanoでの乱数の使用について説明します.Theanoはまず符号化されたもので式の定義を行い、その後システムはこれらの式を関数としてコンパイルし、最後にこれらの関数を呼び出して対応する機能を実行するので、Theanoでは乱数を使用するのは比較的複雑なプロセスです.この問題に対してTheanoはRandomStreamを用いて解決し,すなわち乱数が必要な場所でRandomStreamを定義し,実際の実行中に乱数が演算に関与する必要がある場合にRandomStreamから乱数を読み出す.
乱数はニューラルネットワークで主に重み値に用いられるため,重み行列を初期化し,Theanoではuniform分布を用いて0~1のランダム重み値を得ることができ,コードは以下のようになる.
from theano.tensor.shared_randomstreams import RandomStreams
from theano import function

randStrm = RandomStreams(seed=299)
uniformValue = randStrm.uniform((2, 2))
normalValue = randStrm.normal((2, 2))
getUniformValue = function([], uniformValue)
getNormalValue = function([], normalValue, no_default_updates=True)
getRandomNumber = function([], uniformValue + uniformValue - 2 * uniformValue)

print(getUniformValue())
print(getNormalValue())
print(getRandomNumber())
上のコードは2*2のランダム重み行列を生成し、上記のコードはnormal分布のランダム数重み行列を得るために使用することができ、no_を使用することによってdefault_updates=Trueは,我々が毎回得た乱数を等しくし,最後の関数はゼロに近い乱数を得る.
なお、上記のコードはCPU上でしか実行することができず、CPUとGPU上でコードを実行可能にするには、上記のコードの第1文をfrom theanoに変更するだけでよい.sandbox.rng_mrg import MRG_RandomStreams as RandomStreamsでいいです.
Theanoでは、関数のデフォルトパラメータの処理もpythonの標準的な方法とは異なります.コードは次のとおりです.
from theano import In
from theano import function
from theano import tensor as T

x, y = T.dscalars("x", "y")
z = x + y
add = function([x, In(y, value=100)], z)

print("add=%d" % add(20))
は、上記のコードに示すように、In構文を用いてyのデフォルト値を100と定義することができる.python標準構文と同様にデフォルト値を持つパラメータは、デフォルト値のないパラメータの後ろに置く必要があることに注意してください.