def __init__(self, autoencoders, preact_cors=None, postact_cors=None,
                 layer_samplers=None):
        super(GSN, self).__init__(autoencoders)

        # only for convenience
        self.aes = self._layers

        # easy way to turn off corruption (True => corrupt, False => don't)
        self._corrupt_switch = True

        # easy way to turn off sampling
        self._sample_switch = True

        # easy way to not use bias (True => use bias, False => don't)
        self._bias_switch = True

        # check that autoencoders are the correct sizes by looking at previous
        # layer. We can't do this for the first ae, so we skip it.
        for i in xrange(1, len(self.aes)):
            assert (self.aes[i].weights.get_value().shape[0] ==
                    self.aes[i - 1].nhid)


        # do some type checking and convert None's to identity function
        def _make_callable_list(previous):
            """
            .. todo::

                WRITEME
            """
            if len(previous) != self.nlayers:
                raise ValueError("Need same number of corruptors/samplers as layers")

            if not all(map(lambda x: callable(x) or x is None, previous)):
                raise ValueError("All elements must either be None or be a callable")

            return map(lambda x: identity if x is None else x, previous)

        self._preact_cors = _make_callable_list(preact_cors)
        self._postact_cors = _make_callable_list(postact_cors)
        self._layer_samplers = _make_callable_list(layer_samplers)