import numpy as np
import theano
import theano.tensor as T
import treeano
import treeano.nodes as tn


fX = theano.config.floatX


@treeano.register_node("concatenate_negation")
class ConcatenateNegationNode(treeano.NodeImpl):

    """
    concatenates a negated copy of the actviations on a specified axis
    """

    hyperparameter_names = ("axis",)

    def compute_output(self, network, in_vw):
        axis = network.find_hyperparameter(["axis"], 1)

        in_var = in_vw.variable
        out_var = T.concatenate([in_var, -in_var], axis=axis)

        out_shape = list(in_vw.shape)
        if out_shape[axis] is not None:
            out_shape[axis] *= 2
        out_shape = tuple(out_shape)

        network.create_vw(
            "default",
            variable=out_var,
            shape=out_shape,
            tags={"output"},
        )

@@ -842,8 +842,1162 @@
       )%0A
+%0A%0Aclass NegatedInit(treeano.inits.WeightInit):%0A%0A    %22%22%22%0A    init specifically for units after ConcatenateNegationNode%0A%0A    takes in a different init, and initializes the first half of with that%0A    init, and the second half with the negated version of that tensor%0A%0A    rationale: ConcatenateNegationNode + this init + ReLU will initialize%0A    the network to be linear%0A    %22%22%22%0A%0A    def __init__(self, init, axis=1):%0A        self.init = init%0A        self.axis = axis%0A%0A    def initialize_value(self, vw):%0A        # temporary variable wrapper with fake shape%0A        tmp_vw_shape = list(vw.shape)%0A        if tmp_vw_shape%5Bself.axis%5D %25 2 != 0:%0A            # this weight is probably not after a ConcatenateNegationNode,%0A            # so instead revert to initial init%0A            return self.init.initialize_value(vw)%0A        tmp_vw_shape%5Bself.axis%5D /= 2%0A        tmp_vw_shape = tuple(tmp_vw_shape)%0A        tmp_vw = treeano.VariableWrapper(%0A            %22tmp%22,%0A            shape=tmp_vw_shape,%0A            is_shared=True,%0A            inits=%5B%5D,%0A        )%0A%0A        val = self.init.initialize_value(tmp_vw)%0A%0A        return np.concatenate(%5Bval, -val%5D, axis=self.axis)%0A

add init for concatenate negation