Theano教程中RNN的参数
the parameter of RNN in Theano tutorial
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) 但我有两个问题。
第一的。在本教程中,递归函数如下:
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)]
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 个学期。
第一项是输入层乘以权重矩阵T.dot(x_t, self.wx)
.
第二项是隐藏层与另一个加权矩阵相乘(这就是它经常出现的原因)T.dot(h_tm1, self.wh)
。请注意,您必须有一个加权矩阵,您建议基本上添加 self.h0
作为偏差。
第三项是隐藏层的bias,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]
初始化值是对的,但这些值也链接到输出。 recurrence()
有两个输出,即[h_t, s_t]
.
所以 outputs_info 的作用是在每次迭代后,self.h0
的值被 h_t
的值(第一个返回值)覆盖。 outputs_info 的第二个元素是 None
,因为我们没有在任何地方保存或初始化 s_t
的值(outputs_info 的第二个参数链接到这样的递归函数。)
在下一次迭代中,outputs_info
的第一个参数再次用作输入,这样 h_tm1
与 self.h0
的值相同。但是,由于我们必须有一个 h_tm
的参数,所以我们必须初始化这个值。由于我们不需要在 outputs_info
中初始化第二个参数,我们将第二项保留为 None
.
诚然,theano.scan()
函数有时非常令人困惑,我也是新手。但是,这就是我在做同样的教程时所理解的。
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) 但我有两个问题。 第一的。在本教程中,递归函数如下:
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)]
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 个学期。
第一项是输入层乘以权重矩阵
T.dot(x_t, self.wx)
.第二项是隐藏层与另一个加权矩阵相乘(这就是它经常出现的原因)
T.dot(h_tm1, self.wh)
。请注意,您必须有一个加权矩阵,您建议基本上添加self.h0
作为偏差。第三项是隐藏层的bias,
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]
初始化值是对的,但这些值也链接到输出。 recurrence()
有两个输出,即[h_t, s_t]
.
所以 outputs_info 的作用是在每次迭代后,self.h0
的值被 h_t
的值(第一个返回值)覆盖。 outputs_info 的第二个元素是 None
,因为我们没有在任何地方保存或初始化 s_t
的值(outputs_info 的第二个参数链接到这样的递归函数。)
在下一次迭代中,outputs_info
的第一个参数再次用作输入,这样 h_tm1
与 self.h0
的值相同。但是,由于我们必须有一个 h_tm
的参数,所以我们必须初始化这个值。由于我们不需要在 outputs_info
中初始化第二个参数,我们将第二项保留为 None
.
诚然,theano.scan()
函数有时非常令人困惑,我也是新手。但是,这就是我在做同样的教程时所理解的。