मैं थोड़ी देर के लिए इसके खिलाफ अपने सिर को टक्कर लगी हूं और यह पता नहीं लगा सकता कि मैंने इन्हें लागू करने में क्या गलत किया है (अगर कुछ भी) RNNs। आपको आगे के चरण को आगे बढ़ाने के लिए, मैं आपको बता सकता हूं कि दो कार्यान्वयन समान आउटपुट की गणना करते हैं, इसलिए आगे का चरण सही है। समस्या पीछे की तरफ है।शुद्ध-पायथन आरएनएन और थेनो आरएनएन विभिन्न ग्रेडियेंट कंप्यूटिंग - कोड और परिणाम प्रदान किए गए
यहां मेरा पायथन पीछे कोड है। यह karpathy के neuraltalk की शैली काफी बारीकी लेकिन वास्तव में नहीं इस प्रकार है:। यहाँ
def backward(self, cache, target,c=leastsquares_cost, dc=leastsquares_dcost):
'''
cache is from forward pass
c is a cost function
dc is a function used as dc(output, target) which gives the gradient dc/doutput
'''
XdotW = cache['XdotW'] #num_time_steps x hidden_size
Hin = cache['Hin'] # num_time_steps x hidden_size
T = Hin.shape[0]
Hout = cache['Hout']
Xin = cache['Xin']
Xout = cache['Xout']
Oin = cache['Oin'] # num_time_steps x output_size
Oout=cache['Oout']
dcdOin = dc(Oout, target) # this will be num_time_steps x num_outputs. these are dc/dO_j
dcdWho = np.dot(Hout.transpose(), dcdOin) # this is the sum of outer products for all time
# bias term is added at the end with coefficient 1 hence the dot product is just the sum
dcdbho = np.sum(dcdOin, axis=0, keepdims=True) #this sums all the time steps
dcdHout = np.dot(dcdOin, self.Who.transpose()) #reflects dcdHout_ij should be the dot product of dcdoin and the i'th row of Who; this is only for the outputs
# now go back in time
dcdHin = np.zeros(dcdHout.shape)
# for t=T we can ignore the other term (error from the next timestep). self.df is derivative of activation function (here, tanh):
dcdHin[T-1] = self.df(Hin[T-1]) * dcdHout[T-1] # because we don't need to worry about the next timestep, dcdHout is already corrent for t=T
for t in reversed(xrange(T-1)):
# we need to add to dcdHout[t] the error from the next timestep
dcdHout[t] += np.dot(dcdHin[t], self.Whh.transpose())
# now we have the correct form for dcdHout[t]
dcdHin[t] = self.df(Hin[t]) * dcdHout[t]
# now we've gone through all t, and we can continue
dcdWhh = np.zeros(self.Whh.shape)
for t in range(T-1): #skip T bc dHdin[T+1] doesn't exist
dcdWhh += np.outer(Hout[t], dcdHin[t+1])
# and we can do bias as well
dcdbhh = np.sum(dcdHin,axis=0, keepdims=True)
# now we need to go back to the embeddings
dcdWxh = np.dot(Xout.transpose(), dcdHin)
return {'dcdOout': dcdOout, 'dcdWxh': dcdWxh, 'dcdWhh': dcdWhh, 'dcdWho': dcdWho, 'dcdbhh': dcdbhh, 'dcdbho': dcdbho, 'cost':c(Oout, target)}
और थेनो कोड (मुख्य रूप से एक और कार्यान्वयन मैं ऑनलाइन पाया से नकल है मैं अपने शुद्ध अजगर rnn के बेतरतीब वजन करने के लिए वजन को प्रारंभ ताकि सब कुछ वही है।):
# input (where first dimension is time)
u = TT.matrix()
# target (where first dimension is time)
t = TT.matrix()
# initial hidden state of the RNN
h0 = TT.vector()
# learning rate
lr = TT.scalar()
# recurrent weights as a shared variable
W = theano.shared(rnn.Whh)
# input to hidden layer weights
W_in = theano.shared(rnn.Wxh)
# hidden to output layer weights
W_out = theano.shared(rnn.Who)
# bias 1
b_h = theano.shared(rnn.bhh[0])
# bias 2
b_o = theano.shared(rnn.bho[0])
# recurrent function (using tanh activation function) and linear output
# activation function
def step(u_t, h_tm1, W, W_in, W_out):
h_t = TT.tanh(TT.dot(u_t, W_in) + TT.dot(h_tm1, W) + b_h)
y_t = TT.dot(h_t, W_out) + b_o
return h_t, y_t
# the hidden state `h` for the entire sequence, and the output for the
# entrie sequence `y` (first dimension is always time)
[h, y], _ = theano.scan(step,
sequences=u,
outputs_info=[h0, None],
non_sequences=[W, W_in, W_out])
# error between output and target
error = (.5*(y - t) ** 2).sum()
# gradients on the weights using BPTT
gW, gW_in, gW_out, gb_h, gb_o = TT.grad(error, [W, W_in, W_out, b_h, b_o])
# training function, that computes the error and updates the weights using
# SGD.
अब पागल चीज़ है।
निम्नलिखित उत्पादनfn = theano.function([h0, u, t, lr],
[error, y, h, gW, gW_in, gW_out, gb_h, gb_o],
updates={W: W - lr * gW,
W_in: W_in - lr * gW_in,
W_out: W_out - lr * gW_out})
er, yout, hout, gWhh, gWhx, gWho, gbh, gbo =fn(numpy.zeros((n,)), numpy.eye(5), numpy.eye(5),.01)
cache = rnn.forward(np.eye(5))
bc = rnn.backward(cache, np.eye(5))
print "sum difference between gWho (theano) and bc['dcdWho'] (pure python):"
print np.sum(gWho - bc['dcdWho'])
print "sum differnce between gWhh(theano) and bc['dcdWho'] (pure python):"
print np.sum(gWhh - bc['dcdWhh'])
print "sum difference between gWhx (theano) and bc['dcdWxh'] (pure pyython):"
print np.sum(gWhx - bc['dcdWxh'])
print "sum different between the last row of gWhx (theano) and the last row of bc['dcdWxh'] (pure python):"
print np.sum(gWhx[-1] - bc['dcdWxh'][-1])
मैं:
sum difference between gWho (theano) and bc['dcdWho'] (pure python):
-4.59268040265e-16
sum differnce between gWhh(theano) and bc['dcdWhh'] (pure python):
0.120527063611
sum difference between gWhx (theano) and bc['dcdWxh'] (pure pyython):
-0.332613468652
sum different between the last row of gWhx (theano) and the last row of bc['dcdWxh'] (pure python):
4.33680868994e-18
तो, मैं छिपी परत और आउटपुट सही के बीच वजन मैट्रिक्स के डेरिवेटिव हो रही है, लेकिन नहीं डेरिवेटिव मैं निम्नलिखित चलाते हैं वजन मैट्रिक्स छुपा -> छुपा या इनपुट -> छुपा। लेकिन यह पागल बात यह है कि मुझे हमेशा वजन मैट्रिक्स इनपुट की अंतिम पंक्ति मिलती है -> सही छिपा हुआ। यह मेरे लिए पागलपन है। मुझे नहीं पता कि यहां क्या हो रहा है। ध्यान दें कि वजन मैट्रिक्स इनपुट की अंतिम पंक्ति -> छुपा अंतिम समय या कुछ भी नहीं है (उदाहरण के लिए, मुझे अंतिम समय के लिए सही ढंग से डेरिवेटिव की गणना करके समझाया जाएगा, लेकिन समय के साथ सही ढंग से प्रचार नहीं कर रहा है)। dcdWxh dcdWxh के सभी समय चरणों पर योग है - तो मैं इस सही की एक पंक्ति कैसे प्राप्त कर सकता हूं लेकिन दूसरों में से कोई भी नहीं ???
क्या कोई मदद कर सकता है? मैं यहाँ विचारों से बाहर हूं।