code: def make_nn_funs(input_shape, layer_specs, L2_reg):
      parser = WeightsParser()
      cur_shape = input_shape
      for layer in layer_specs:
          N_weights, cur_shape = layer.build_weights_dict(cur_shape)
          parser.add_weights(layer, (N_weights,))
  
      def predictions(W_vect, inputs):
          """Outputs normalized log-probabilities.
          shape of inputs : [data, color, y, x]"""
          cur_units = inputs
          for layer in layer_specs:
              cur_weights = parser.get(W_vect, layer)
              cur_units = layer.forward_pass(cur_units, cur_weights)
          return cur_units
  
      def loss(W_vect, X, T):
          log_prior = -L2_reg * np.dot(W_vect, W_vect)
          log_lik = np.sum(predictions(W_vect, X) * T)
          return -log_prior - log_lik
  
      def frac_err(W_vect, X, T):
          return np.mean(
              np.argmax(T, axis=1)
              != np.argmax(pred_fun(W_vect, X), axis=1)
          )
  
      return parser.N, predictions, loss, frac_err
  
imports: from __future__ import absolute_import
  from __future__ import print_function
  from builtins import range
  import autograd.numpy
  import autograd.numpy.random
  import autograd.scipy.signal
  from autograd import grad
  import data_mnist
label_desc: Use image node_id 3 for calling a global function with example usage: make_nn_funs(input_shape, layer_specs, L2_reg) and returns: parser,  predictions,  loss,  frac_err, cur_units, unknown, np