/// <summary> /// This is the method to call for assigning labels and node vectors /// to the Tree. /// </summary> /// <remarks> /// This is the method to call for assigning labels and node vectors /// to the Tree. After calling this, each of the non-leaf nodes will /// have the node vector and the predictions of their classes /// assigned to that subtree's node. The annotations filled in are /// the RNNCoreAnnotations.NodeVector, Predictions, and /// PredictedClass. In general, PredictedClass will be the most /// useful annotation except when training. /// </remarks> public virtual void ForwardPropagateTree(Tree tree) { SimpleMatrix nodeVector; // initialized below or Exception thrown // = null; SimpleMatrix classification; // initialized below or Exception thrown // = null; if (tree.IsLeaf()) { // We do nothing for the leaves. The preterminals will // calculate the classification for this word/tag. In fact, the // recursion should not have gotten here (unless there are // degenerate trees of just one leaf) log.Info("SentimentCostAndGradient: warning: We reached leaves in forwardPropagate: " + tree); throw new AssertionError("We should not have reached leaves in forwardPropagate"); } else { if (tree.IsPreTerminal()) { classification = model.GetUnaryClassification(tree.Label().Value()); string word = tree.Children()[0].Label().Value(); SimpleMatrix wordVector = model.GetWordVector(word); nodeVector = NeuralUtils.ElementwiseApplyTanh(wordVector); } else { if (tree.Children().Length == 1) { log.Info("SentimentCostAndGradient: warning: Non-preterminal nodes of size 1: " + tree); throw new AssertionError("Non-preterminal nodes of size 1 should have already been collapsed"); } else { if (tree.Children().Length == 2) { ForwardPropagateTree(tree.Children()[0]); ForwardPropagateTree(tree.Children()[1]); string leftCategory = tree.Children()[0].Label().Value(); string rightCategory = tree.Children()[1].Label().Value(); SimpleMatrix W = model.GetBinaryTransform(leftCategory, rightCategory); classification = model.GetBinaryClassification(leftCategory, rightCategory); SimpleMatrix leftVector = RNNCoreAnnotations.GetNodeVector(tree.Children()[0]); SimpleMatrix rightVector = RNNCoreAnnotations.GetNodeVector(tree.Children()[1]); SimpleMatrix childrenVector = NeuralUtils.ConcatenateWithBias(leftVector, rightVector); if (model.op.useTensors) { SimpleTensor tensor = model.GetBinaryTensor(leftCategory, rightCategory); SimpleMatrix tensorIn = NeuralUtils.Concatenate(leftVector, rightVector); SimpleMatrix tensorOut = tensor.BilinearProducts(tensorIn); nodeVector = NeuralUtils.ElementwiseApplyTanh(W.Mult(childrenVector).Plus(tensorOut)); } else { nodeVector = NeuralUtils.ElementwiseApplyTanh(W.Mult(childrenVector)); } } else { log.Info("SentimentCostAndGradient: warning: Tree not correctly binarized: " + tree); throw new AssertionError("Tree not correctly binarized"); } } } } SimpleMatrix predictions = NeuralUtils.Softmax(classification.Mult(NeuralUtils.ConcatenateWithBias(nodeVector))); int index = GetPredictedClass(predictions); if (!(tree.Label() is CoreLabel)) { log.Info("SentimentCostAndGradient: warning: No CoreLabels in nodes: " + tree); throw new AssertionError("Expected CoreLabels in the nodes"); } CoreLabel label = (CoreLabel)tree.Label(); label.Set(typeof(RNNCoreAnnotations.Predictions), predictions); label.Set(typeof(RNNCoreAnnotations.PredictedClass), index); label.Set(typeof(RNNCoreAnnotations.NodeVector), nodeVector); }
private void ForwardPropagateTree(Tree tree, IList <string> words, IdentityHashMap <Tree, SimpleMatrix> nodeVectors, IdentityHashMap <Tree, double> scores) { if (tree.IsLeaf()) { return; } if (tree.IsPreTerminal()) { Tree wordNode = tree.Children()[0]; string word = wordNode.Label().Value(); SimpleMatrix wordVector = dvModel.GetWordVector(word); wordVector = NeuralUtils.ElementwiseApplyTanh(wordVector); nodeVectors[tree] = wordVector; return; } foreach (Tree child in tree.Children()) { ForwardPropagateTree(child, words, nodeVectors, scores); } // at this point, nodeVectors contains the vectors for all of // the children of tree SimpleMatrix childVec; if (tree.Children().Length == 2) { childVec = NeuralUtils.ConcatenateWithBias(nodeVectors[tree.Children()[0]], nodeVectors[tree.Children()[1]]); } else { childVec = NeuralUtils.ConcatenateWithBias(nodeVectors[tree.Children()[0]]); } if (op.trainOptions.useContextWords) { childVec = ConcatenateContextWords(childVec, tree.GetSpan(), words); } SimpleMatrix W = dvModel.GetWForNode(tree); if (W == null) { string error = "Could not find W for tree " + tree; if (op.testOptions.verbose) { log.Info(error); } throw new NoSuchParseException(error); } SimpleMatrix currentVector = W.Mult(childVec); currentVector = NeuralUtils.ElementwiseApplyTanh(currentVector); nodeVectors[tree] = currentVector; SimpleMatrix scoreW = dvModel.GetScoreWForNode(tree); if (scoreW == null) { string error = "Could not find scoreW for tree " + tree; if (op.testOptions.verbose) { log.Info(error); } throw new NoSuchParseException(error); } double score = scoreW.Dot(currentVector); //score = NeuralUtils.sigmoid(score); scores[tree] = score; }