def build_model(self, n_hidden_units, n_hidden_layers, old_params = None):
        # Model definition.
        x = T.fmatrix('X')
        y = x

        # Keep model params here.
        self.params = []

        # Build the layered neural network.
        if not old_params:
            self.n_hidden = [n_hidden_units,]*n_hidden_layers
        else:
            self.n_hidden = self.n_hidden + [n_hidden_units,]*n_hidden_layers

        activations = [self.hidden_activation,]*len(self.n_hidden)
        activations.extend([T.nnet.softmax,]) # NOTE: The last function goes to the output layer.

        assert len(self.n_hidden) + 1 == len(activations)

        layers = [self.n_inputs] + self.n_hidden + [self.n_outputs]

        # Iterate over pairs of adjacent layers.
        for i, (n1, n2, act) in enumerate(zip(layers[:-1], layers[1:], activations)):
            if old_params and (2*i < len(old_params)):
                # print "using old params"
                # init an existing layer
                w = theano.shared(old_params[2*i], 'W%d' % i, borrow=True)
                b = theano.shared(old_params[2*i+1], 'b%d' % (i + 1))
            else:
                # print "sampling new params"
                w = theano.shared(
                                   np.asarray(rng.uniform(
                                                          low=-np.sqrt(6. / (n1 + n2)),
                                                          high=np.sqrt(6. / (n1 + n2)),
                                                          size=(n1, n2)),
                                              dtype=np.float32),
                                   'W%d' % i, borrow=True)
                b = theano.shared(np.zeros(n2, dtype=np.float32), 'b%d' % (i - 1))
            self.params.append(w)
            self.params.append(b)

            y = act(T.dot(y, w) + b)

        self.f_y = function([x], y) # PREDICTION FUNCTION

        # Define the loss function.
        true_y = T.ivector('true_Y')  # The desired output vector.
        loss = T.log(y[T.arange(y.shape[0]), true_y])  # log-likelihood.
        loss = T.mean(loss)                            # SUM log-likelihood.

        # Add regularization.
        l2 = 0
        for p in self.params:
            l2 += (p**2).sum()
        loss -= self.weight_l2 * l2

        self.f_loss = function([x, true_y], loss, allow_input_downcast=True)

        # Derive the gradients for the parameters.
        g_loss = T.grad(loss, wrt=self.params)
        self.f_g_loss = function([x, true_y], g_loss)

        # Create a training function for maximization
        updates = []
        learning_rate = T.fscalar()
        for p, g in zip(self.params, g_loss):
            updates.append((p, p + learning_rate * g))

        self.f_train_ret_loss = function([x, true_y, learning_rate], loss, updates = updates)

        # GPU data multiplications, it appears that this version is not faster compared to the CPU version
#        self.shared_training_set_x = theano.shared(training_set_x, 'training_set_x')
#        self.shared_training_set_y = theano.shared(training_set_y, 'training_set_y')
#        xlr = [(c, c + self.batch_size - (self.prev_frames + self.next_frames)) for c in range(self.prev_frames + self.next_frames, -1, -1)]
#        ylr = (self.prev_frames, self.batch_size - self.next_frames)

#        print >> sys.stderr, xlr
#        print >> sys.stderr, ylr
#        print >> sys.stderr, [self.shared_training_set_x.get_value()[0*self.batch_size+l:0*self.batch_size+r].shape for l, r in xlr]

#        m = T.lscalar()
#        self.f_train2 = function(inputs = [m, learning_rate],
#                                outputs = loss,
#                                updates = updates,
#                                givens = {
#                                    x: T.concatenate([self.shared_training_set_x[m*self.batch_size+l:m*self.batch_size+r] for l, r in xlr],
#                                                     axis = 1),
#                                    true_y: self.shared_training_set_y[m*self.batch_size + ylr[0]:m*self.batch_size + ylr[1]]

                                    #x: self.shared_training_set_x[m*self.batch_size:(m+1)*self.batch_size],
                                    #true_y: self.shared_training_set_y[m*self.batch_size: (m+1)*self.batch_size]
#                                })
dataset/ETHPy150Open UFAL-DSG/cloud-asr/cloudasr/worker/vad/tffnn.py/TheanoFFNN.build_model/operator `+` -> `-`