new_contents: from __future__ import division, absolute_import
  from __future__ import print_function, unicode_literals
  
  import itertools
  import numpy as np
  import sklearn.datasets
  import sklearn.cross_validation
  import sklearn.metrics
  import theano
  import theano.tensor as T
  import treeano
  import treeano.nodes as tn
  from treeano.sandbox.nodes import recurrent_convolution as rcl
  import canopy
  
  fX = theano.config.floatX
  
  # ############################### prepare data ###############################
  
  mnist = sklearn.datasets.fetch_mldata('MNIST original')
  # theano has a constant float type that it uses (float32 for GPU)
  # also rescaling to [0, 1] instead of [0, 255]
  X = mnist['data'].reshape(-1, 1, 28, 28).astype(fX) / 255.0
  y = mnist['target'].astype("int32")
  X_train, X_valid, y_train, y_valid = sklearn.cross_validation.train_test_split(
      X, y, random_state=42)
  in_train = {"x": X_train, "y": y_train}
  in_valid = {"x": X_valid, "y": y_valid}
  
  # ############################## prepare model ##############################
  # - the batch size can be provided as `None` to make the network
  #   work for multiple different batch sizes
  model = tn.HyperparameterNode(
      "model",
      tn.SequentialNode(
          "seq",
          [tn.InputNode("x", shape=(None, 1, 28, 28)),
           rcl.DefaultRecurrentConv2DNode("conv1"),
           tn.ReLUNode("relu1"),
           tn.MaxPool2DNode("mp1"),
           rcl.DefaultRecurrentConv2DNode("conv2"),
           tn.ReLUNode("relu2"),
           tn.MaxPool2DNode("mp2"),
           tn.DenseNode("fc1"),
           tn.ReLUNode("relu3"),
           tn.DropoutNode("do1"),
           tn.DenseNode("fc2", num_units=10),
           tn.SoftmaxNode("pred"),
           ]),
      num_filters=32,
      filter_size=(3, 3),
      pool_size=(2, 2),
      num_units=256,
      dropout_probability=0.5,
      inits=[treeano.inits.XavierNormalInit()],
  )
  
  with_updates = tn.HyperparameterNode(
      "with_updates",
      tn.AdamNode(
          "adam",
          {"subtree": model,
           "cost": tn.TotalCostNode("cost", {
               "pred": tn.ReferenceNode("pred_ref", reference="model"),
               "target": tn.InputNode("y", shape=(None,), dtype="int32")},
           )}),
      cost_function=treeano.utils.categorical_crossentropy_i32,
  )
  network = with_updates.network()
  network.build()  # build eagerly to share weights
  
  BATCH_SIZE = 500
  
  valid_fn = canopy.handled_fn(
      network,
      [canopy.handlers.time_call(key="valid_time"),
       canopy.handlers.override_hyperparameters(dropout_probability=0),
       canopy.handlers.chunk_variables(batch_size=BATCH_SIZE,
                                       variables=["x", "y"])],
      {"x": "x", "y": "y"},
      {"cost": "cost", "pred": "pred"})
  
  
  def validate(in_dict, results_dict):
      valid_out = valid_fn(in_valid)
      probabilities = valid_out["pred"]
      predicted_classes = np.argmax(probabilities, axis=1)
      results_dict["valid_cost"] = valid_out["cost"]
      results_dict["valid_time"] = valid_out["valid_time"]
      results_dict["valid_accuracy"] = sklearn.metrics.accuracy_score(
          y_valid, predicted_classes)
  
  train_fn = canopy.handled_fn(
      network,
      [canopy.handlers.time_call(key="total_time"),
       canopy.handlers.call_after_every(1, validate),
       canopy.handlers.time_call(key="train_time"),
       canopy.handlers.chunk_variables(batch_size=BATCH_SIZE,
                                       variables=["x", "y"])],
      {"x": "x", "y": "y"},
      {"train_cost": "cost"},
      include_updates=True)
  
  
  # ################################# training #################################
  
  print("Starting training...")
  canopy.evaluate_until(fn=train_fn,
                        gen=itertools.repeat(in_train),
                        max_iters=25)
  
subject: add mnist example for recurrent conv node