2014-12-18 5 views
5

मैं थोड़ी देर के लिए इसके खिलाफ अपने सिर को टक्कर लगी हूं और यह पता नहीं लगा सकता कि मैंने इन्हें लागू करने में क्या गलत किया है (अगर कुछ भी) 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 के सभी समय चरणों पर योग है - तो मैं इस सही की एक पंक्ति कैसे प्राप्त कर सकता हूं लेकिन दूसरों में से कोई भी नहीं ???

क्या कोई मदद कर सकता है? मैं यहाँ विचारों से बाहर हूं।

उत्तर

0

आपको दो matrices के अंतर के बिंदुवार पूर्ण मूल्य के योग की गणना करनी चाहिए। विशिष्ट सीखने के कार्यों के कारण सादा योग शून्य के करीब हो सकता है (क्या आप शून्य फ़ंक्शन का अनुकरण करते हैं? :), जो भी हो।

आखिरी पंक्ति संभावित रूप से स्थिर-पर-न्यूरॉन से वजन को लागू करती है, यानी - ऐसा लगता है - हमेशा पूर्वाग्रह प्राप्त करें (हालांकि, पूर्ण मानों का योग देखें)।

यह भी तरह रो-प्रमुख और मैट्रिक्स के कॉलम-प्रमुख अंकन भ्रमित कर रहे हैं की तरह

gWhx - bc['dcdWxh'] 

जो करने के लिए "एक्स छिपा करने के लिए" विपरीत में "एक्स को छिपा" से वजन की तरह पढ़ता है, लग रहा है।

मैं इसे एक टिप्पणी के रूप में पोस्ट करना चाहता हूं, लेकिन मुझे ऐसा करने में प्रतिष्ठा नहीं है। माफ़ कीजिये!

संबंधित मुद्दे