| 32 | |
| 33 | |
| 34 | class RecursiveNN: |
| 35 | def __init__(self, V, D, K): |
| 36 | self.V = V |
| 37 | self.D = D |
| 38 | self.K = K |
| 39 | |
| 40 | def fit(self, trees, learning_rate=3*1e-3, mu=0.99, reg=1e-4, epochs=15, activation=T.nnet.relu, train_inner_nodes=False): |
| 41 | D = self.D |
| 42 | V = self.V |
| 43 | K = self.K |
| 44 | self.f = activation |
| 45 | N = len(trees) |
| 46 | |
| 47 | We = init_weight(V, D) |
| 48 | Wh = np.random.randn(2, D, D) / np.sqrt(2 + D + D) |
| 49 | bh = np.zeros(D) |
| 50 | Wo = init_weight(D, K) |
| 51 | bo = np.zeros(K) |
| 52 | |
| 53 | self.We = theano.shared(We) |
| 54 | self.Wh = theano.shared(Wh) |
| 55 | self.bh = theano.shared(bh) |
| 56 | self.Wo = theano.shared(Wo) |
| 57 | self.bo = theano.shared(bo) |
| 58 | self.params = [self.We, self.Wh, self.bh, self.Wo, self.bo] |
| 59 | |
| 60 | words = T.ivector('words') |
| 61 | parents = T.ivector('parents') |
| 62 | relations = T.ivector('relations') |
| 63 | labels = T.ivector('labels') |
| 64 | |
| 65 | def recurrence(n, hiddens, words, parents, relations): |
| 66 | w = words[n] |
| 67 | # any non-word will have index -1 |
| 68 | # if T.ge(w, 0): |
| 69 | # hiddens = T.set_subtensor(hiddens[n], self.We[w]) |
| 70 | # else: |
| 71 | # hiddens = T.set_subtensor(hiddens[n], self.f(hiddens[n] + self.bh)) |
| 72 | hiddens = T.switch( |
| 73 | T.ge(w, 0), |
| 74 | T.set_subtensor(hiddens[n], self.We[w]), |
| 75 | T.set_subtensor(hiddens[n], self.f(hiddens[n] + self.bh)) |
| 76 | ) |
| 77 | |
| 78 | r = relations[n] # 0 = is_left, 1 = is_right |
| 79 | p = parents[n] # parent idx |
| 80 | # if T.ge(p, 0): |
| 81 | # # root will have parent -1 |
| 82 | # hiddens = T.set_subtensor(hiddens[p], hiddens[p] + hiddens[n].dot(self.Wh[r])) |
| 83 | hiddens = T.switch( |
| 84 | T.ge(p, 0), |
| 85 | T.set_subtensor(hiddens[p], hiddens[p] + hiddens[n].dot(self.Wh[r])), |
| 86 | hiddens |
| 87 | ) |
| 88 | return hiddens |
| 89 | |
| 90 | hiddens = T.zeros((words.shape[0], D)) |
| 91 | |