0
class RNNSLU(object):
''' elman neural net model '''
def __init__(self, nh, nc, ne, de, cs):
    '''
    nh :: dimension of the hidden layer
    nc :: number of classes
    ne :: number of word embeddings in the vocabulary
    de :: dimension of the word embeddings
    cs :: word window context size
    '''
    # parameters of the model
    self.emb = theano.shared(name='embeddings',
                             value=0.2 * numpy.random.uniform(-1.0, 1.0,
                             (ne+1, de))
                             # add one for padding at the end
                             .astype(theano.config.floatX))
    self.wx = theano.shared(name='wx',
                            value=0.2 * numpy.random.uniform(-1.0, 1.0,
                            (de * cs, nh))
                            .astype(theano.config.floatX))
    self.wh = theano.shared(name='wh',
                            value=0.2 * numpy.random.uniform(-1.0, 1.0,
                            (nh, nh))
                            .astype(theano.config.floatX))
    self.w = theano.shared(name='w',
                           value=0.2 * numpy.random.uniform(-1.0, 1.0,
                           (nh, nc))
                           .astype(theano.config.floatX))
    self.bh = theano.shared(name='bh',
                            value=numpy.zeros(nh,
                            dtype=theano.config.floatX))
    self.b = theano.shared(name='b',
                           value=numpy.zeros(nc,
                           dtype=theano.config.floatX))
    self.h0 = theano.shared(name='h0',
                            value=numpy.zeros(nh,
                            dtype=theano.config.floatX))

    # bundle
    self.params = [self.emb, self.wx, self.wh, self.w, self.bh, self.b, self.h0]



def recurrence(x_t, h_tm1):
        h_t = T.nnet.sigmoid(T.dot(x_t, self.wx)
                             + T.dot(h_tm1, self.wh) + self.bh)
        s_t = T.nnet.softmax(T.dot(h_t, self.w) + self.b)
        return [h_t, s_t]

[h, s], = theano.scan(fn=recurrence,
                            sequences=x,
                            outputs_info=[self.h0, None],
                            n_steps=x.shape[0])

RNN に関する Theano チュートリアル ( http://deeplearning.net/tutorial/rnnslu.html ) に従っていますが、それについて 2 つの質問があります。初め。このチュートリアルでは、繰り返しは次のように機能します。

def recurrence(x_t, h_tm1): h_t = T.nnet.sigmoid(T.dot(x_t, self.wx) + T.dot(h_tm1, self.wh) + self.bh) s_t = T.nnet.softmax(T.dot(h_t, self.w) + self.b) return [h_t, s_t]

h_t に h0 を追加しないのはなぜですか?(つまりh_t = T.nnet.sigmoid(T.dot(x_t, self.wx) + T.dot(h_tm1, self.wh) + self.bh + self.h0))

第二に、なぜoutputs_info=[self.h0, None]ですか?outputs_info が初期化結果であることはわかっています。だから私は思うoutputs_info=[self.bh+self.h0, T.nnet.softmax(T.dot(self.bh+self.h0, self.w_h2y) + self.b_h2y)]

4

1 に答える 1

1
def recurrence(x_t, h_tm1):
        h_t = T.nnet.sigmoid(T.dot(x_t, self.wx)
                             + T.dot(h_tm1, self.wh) + self.bh)
        s_t = T.nnet.softmax(T.dot(h_t, self.w) + self.b)
        return [h_t, s_t]

では、まず再帰関数で h0 を使用しない理由を尋ねます。この部分を分解してみましょう。

   h_t = T.nnet.sigmoid(T.dot(x_t, self.wx)+ T.dot(h_tm1, self.wh) + self.bh)

期待されるのは 3 項です。

  1. 最初の項は、入力層に重み付け行列を掛けたものT.dot(x_t, self.wx)です。

  2. 2 番目の項は、隠れ層に別の重み付け行列を乗算したものです (これにより、再帰性が生じます) T.dot(h_tm1, self.wh)self.h0基本的にバイアスとして追加することを提案した、重み付けマトリックスが必要であることに注意してください。

  3. 3 番目の項は、隠れ層のバイアス ですself.bh

ここで、反復ごとに、 に含まれる隠れ層のアクティブ化を追跡したいと考えていself.h0ます。ただし、現在self.h0のアクティベーションを含めることを意図しており、必要なのは以前のアクティベーションです。

[h, s], _ = theano.scan(fn=recurrence,
                            sequences=x,
                            outputs_info=[self.h0, None],
                            n_steps=x.shape[0])

それでは、スキャン機能をもう一度見てみましょう。値を初期化するのは正しいですoutputs_info=[self.h0, None]が、値は出力にもリンクされています。からの 2 つの出力recurrence()、つまりがあり[h_t, s_t]ます。

したがって、outputs_info が同様に行うことは、反復ごとに、の値が(最初に返された値)self.h0の値で上書きされることです。h_toutputs_info の 2 番目の要素はNone、どこにも値を保存または初期化しないためですs_t(outputs_info の 2 番目の引数は、この方法で再帰関数の戻り値にリンクされます)。

次の反復では、 の最初の引数がoutputs_info再び入力として使用されh_tm1、 と同じ値になりself.h0ます。ただし、引数が必要なので、h_tmこの値を初期化する必要があります。の 2 番目の引数を初期化する必要がないためoutputs_info、2 番目の項は のままにしNoneます。

確かに、このtheano.scan()機能は時々非常に紛らわしく、私もそれが初めてです。しかし、これは私がこの同じチュートリアルを行うことで理解したものです.

于 2016-03-29T10:53:40.693 に答える