     S.emplace_back(tanh(dot(Y[t], Wxh_d) + dot(S[t-1], Whh_d) + bh_d));
   }
 
-  Expr Why = named(g.param(shape={hidden_size, output_size}, init=uniform()), "Why");
-  Expr by = named(g.param(shape={1, output_size}, init=uniform()), "by");
+  // Output linear layer before softmax.
+  Expr Why = named(g.param(shape={hidden_size, output_size},
+                           init=uniform()), "Why");
+  Expr by = named(g.param(shape={1, output_size},
+                          init=uniform()), "by");
 
   std::cerr << "Building output layer..." << std::endl;
+
+  // Softmax layer and cost function.
   std::vector<Expr> Yp;
-
   Yp.emplace_back(named(softmax_fast(dot(h0_d, Why) + by), "pred"));
   Expr cross_entropy = sum(Y[0] * log(Yp[0]), axis=1);
   for (int t = 1; t <= num_outputs; ++t) {

  std::cerr << "Target vocabulary size: " << targetVocab.Size() << std::endl;
#endif

  ExpressionGraph g = build_graph(0);

  // For the stop symbol.
  for (int t = 0; t <= num_inputs; ++t) {
    Tensor Xt({batch_size, input_size});

    float max = 1.;
    std::vector<float> values(batch_size * input_size);
    std::vector<float> classes(batch_size * output_size, 0.0);


  return g;
}

int main(int argc, char** argv) {
#if 1
