[DL]theanoに基づく.tensor.dotの論理回帰コードの中のSGD部分の疑問の探求

9056 ワード

Hintonのチュートリアルでは、Pythonのtheanoライブラリを使用して構築されたCNNが重要な一環であり、その中のいわゆるSGD-stochastic gradient descendアルゴリズムはどのように実現されているのだろうか.ソースを見て
(紙面はテストモデル関数のみを考慮し、訓練関数はupdatesパラメータが1つ増えただけで、一部のパラメータが変更された):
 3     classifier = LogisticRegression(input=x, n_in=24 * 48, n_out=32)



 7     cost = classifier.negative_log_likelihood(y)



11     test_model = theano.function(inputs=[index],

12             outputs=classifier.errors(y),

13             givens={

14                 x: test_set_x[index * batch_size: (index + 1) * batch_size],

15                 y: test_set_y[index * batch_size: (index + 1) * batch_size]})

行3は、入力がシンボルx、サイズが24*48、出力長が32のオブジェクトclassiferを宣言する.
行11はtheanoの関数オブジェクトを定義し、下付きindexを受信し、入力データのindex*batch_を使用するsize~第(index+1)*batch_size個のデータは関数の入力として誤差として出力.
行12のerrors関数の定義を見てみましょう.
    def errors(self, y):

        # check if y has same dimension of y_pred

        if y.ndim != self.y_pred.ndim:

            raise TypeError('y should have the same shape as self.y_pred',

                ('y', target.type, 'y_pred', self.y_pred.type))

        # check if y is of the correct datatype

        if y.dtype.startswith('int'):

            # the T.neq operator returns a vector of 0s and 1s, where 1

            # represents a mistake in prediction

            return T.mean(T.neq(self.y_pred, y))

        else:

            raise NotImplementedError()

 self.y_predはbatch_の大きさですsizeのベクトル、各要素はbatch_を表すsizeにおける入力に対応するネットワーク判定の結果、errors関数は1つの同大の所望の出力yを受け取る、両者を比較して差を求める平均値として返す、これが誤差の定義である.
問題が来たy_predはどのように計算されますか?ここではLogisticRegressionのコンストラクション関数を見てみましょう.
 1     def __init__(self, input, n_in, n_out):

 2 

 3         # initialize with 0 the weights W as a matrix of shape (n_in, n_out)

 4         self.W = theano.shared(value=numpy.zeros((n_in, n_out),

 5                                                  dtype=theano.config.floatX),

 6                                 name='W', borrow=True)

 7         # initialize the baises b as a vector of n_out 0s

 8         self.b = theano.shared(value=numpy.zeros((n_out,),

 9                                                  dtype=theano.config.floatX),

10                                name='b', borrow=True)

11 

12         # compute vector of class-membership probabilities in symbolic form

13         self.p_y_given_x = T.nnet.softmax(T.dot(input, self.W) + self.b)

14 

15         # compute prediction as class whose probability is maximal in

16         # symbolic form

17         self.y_pred = T.argmax(self.p_y_given_x, axis=1)

18 

19         # parameters of the model

20         self.params = [self.W, self.b]

行13にはinputとselfが用いる.W, self.bソフトmaxのマッピングを行う.ソフトウェアmax自体は1つ1つのマッピングなので、ここでは詳しくは言わないで、詳細はエンジンを検索することができます.ここではT.dot(input,self.W)についてお話しします.
ここでdotはtheanoのtensor変数の点乗操作であり、T.dotは2つのマトリクス(ベクトル)入力を受け入れ、それらの点積を計算し、点乗情報を保存したノードオブジェクトを返し、返されたオブジェクト呼び出しeval()メソッドを使用して実際の数値結果を得ることができる.
1 >>> a = numpy.asarray([1,2,3])

2 >>> b = numpy.asarray([[3],[2],[1]])

3 >>> T.dot(a,b).eval()

4 array([10])

上記コードは、abサイズが一致する場合、すなわちaの第2次元がbの第1次元に等しい.従って、本例では通常(SGD以外)の場合、inputは1行1152列、Wは1152行32列、bの長いは1行32列である.
ここでのT.dot計算の結果は(input*W)、次のコードを参照してください.
1 >>> a = numpy.ones((1, 1152))

2 >>> W.shape

3 (1152, 32)

4 >>> dotaW = T.dot(a, W)

5 >>> dotaW = dotaW.eval()
1 >>> dotaW.shape

2 (1, 32)

なお、aとWの位置を逆にすると、サイズの不一致のエラーが報告する.
ではSGDアルゴリズムでは、行13のコードのinputのサイズは実際にはbatch_であるsize行1152(24*48)列なので、aとbの大きさが合わなかったら?合理的な推定では、T.dotはinputを自動的に遮断する.次のコードを参照してください.
1 >>> a = numpy.ones((10, 1152))

2 >>> dotaW = T.dot(a, W)

3 >>> dotaW = dotaW.eval()

4 >>> dotaW.shape

5 (10, 32)

やはり、T.dotはinputを自動的に遮断する、それをマッチングWのサイズ(1行1152列)で順次Wと乗算して返すので、サイズは(10,32)、バイアスbのサイズは(1,32)なので、bは列ごとに加算.
 
T.dotの問題を解決して、冒頭の疑問は比較的に解答しやすくて、SGDはT.dotのこのような特性に基づいて、一度にbatch_を入力しますsize行1152列サンプル、T.dotはsoftmaxに合わせてbatch_を生成するsize行32列出力、さらにT.argmax(self.p_y_given_x,axis=1)に基づいて、各行(サンプル)の最大値を所望の出力y_として算出するpred(サイズはbatch_size行1列).
ボリュームニューラルネットワークにおけるconv 2 dも同様のメカニズムであり、一定数の入力、例えば20個の48行24列の大きさの画像に対して、入力サンプル毎に対応するN枚の特徴図->ダウンサンプリング->第2層ボリューム層->MLPを生成し、MLPにおいて、上述のT.dotの特性を配合することで、SGDにおけるバッチトレーニングの目的を達成すると予測する.