Ejemplo n.º 1
0
    def create_variables(self, input_spaces, action_space=None):
        in_space = input_spaces["inputs[0]"]
        assert in_space.rank > 0, "ERROR: Must have input Space ({}) with rank larger 0!".format(
            in_space)

        # Create weights matrix and (maybe) biases vector.
        weights_shape = (in_space.shape[0], self.units)
        self.weights_init = Initializer.from_spec(
            shape=weights_shape, specification=self.weights_spec)
        biases_shape = (self.units, )
        self.biases_init = Initializer.from_spec(
            shape=biases_shape, specification=self.biases_spec)

        # Wrapper for backend.
        if get_backend() == "tf":
            self.layer = tf.layers.Dense(
                units=self.units,
                activation=get_activation_function(self.activation,
                                                   *self.activation_params),
                kernel_initializer=self.weights_init.initializer,
                use_bias=(self.biases_spec is not False),
                bias_initializer=(self.biases_init.initializer
                                  or tf.zeros_initializer()),
                trainable=(False if self.trainable is False else True),
                _reuse=tf.AUTO_REUSE)

            # Now build the layer so that its variables get created.
            self.layer.build(in_space.get_shape(with_batch_rank=True))
            # Register the generated variables with our registry.
            self.register_variables(*self.layer.variables)
        elif get_backend() == "pytorch":
            # N.b. activation must be added as a separate 'layer' when assembling a network.
            # In features is the num of input channels.
            apply_bias = (self.biases_spec is not False)
            in_features = in_space.shape[1] if in_space.shape[
                0] == 1 else in_space.shape[0]
            # print("name = {}, ndim = {}, in space.shape = {}, in_features = {}, units = {}".format(
            #     self.name, ndim, in_space.shape, in_features, self.units))
            self.layer = nn.Linear(
                # In case there is a batch dim here due to missing preprocessing.
                in_features=in_features,
                out_features=self.units,
                bias=apply_bias)
            # Apply weight initializer
            if self.weights_init.initializer is not None:
                # Must be a callable in PyTorch
                self.weights_init.initializer(self.layer.weight)
            if apply_bias:
                if self.biases_spec is not None and self.biases_init.initializer is not None:
                    self.biases_init.initializer(self.layer.bias)
                else:
                    # Fill with zeros.
                    self.layer.bias.data.fill_(0)
            if self.activation is not None:
                # Activation function will be used in apply.
                self.activation_fn = get_activation_function(
                    self.activation, *self.activation_params)
            # Use unique scope as name.
            self.register_variables(
                PyTorchVariable(name=self.global_scope, ref=self.layer))
Ejemplo n.º 2
0
    def _graph_fn_apply(self, inputs):
        """
        Args:
            inputs (SingleDataOp): The flattened inputs to this layer.

        Returns:
            SingleDataOp: The output after passing the input through n times the residual function, then the
                activation function.
        """
        if get_backend() == "tf":
            results = inputs
            # Apply the residual unit n times to the input.
            for i in range(self.repeats):
                results = self.residual_units[i].apply(results)

            # Then activate and add up.
            result = results + inputs
            activation_function = get_activation_function(
                self.activation, self.activation_params)
            if activation_function is not None:
                result = activation_function(added_with_input)
            # TODO: Move into util function.
            if hasattr(inputs, "_batch_rank"):
                result._batch_rank = inputs._batch_rank
            if hasattr(inputs, "_time_rank"):
                result._time_rank = inputs._time_rank
            return result
Ejemplo n.º 3
0
    def _graph_fn_apply(self, *inputs):
        """
        The actual calculation on one or more input Ops.

        Args:
            inputs (SingleDataOp): The single (non-container) input(s) to the layer.

        Returns:
            The output(s) after having pushed input(s) through the layer.
        """
        # `self.layer` is not given: Only apply the activation function.
        if self.layer is None:
            # No activation function.
            if self.activation is None:
                return tuple(inputs)
            # Pass inputs through activation function.
            else:
                activation_function = get_activation_function(
                    self.activation, self.activation_params)
                output = activation_function(*inputs)
                # TODO: Move into util function.
                # Add batch-/time-rank flags.
                output._batch_rank = 0 if self.time_major is False else 1
                if self.in_space_0 and self.in_space_0.has_time_rank:
                    output._time_rank = 0 if self.in_space_0.time_major is True else 1
                return output
        # `self.layer` already includes activation function details.
        else:
            if get_backend() == "tf":
                output = self.layer.apply(*inputs)
                # Add batch-/time-rank flags.
                output._batch_rank = 0 if self.time_major is False else 1
                if self.in_space_0 and self.in_space_0.has_time_rank:
                    output._time_rank = 0 if self.in_space_0.time_major is True else 1
                return output
            elif get_backend() == "pytorch":
                # Strip empty internal states:
                inputs = [v for v in inputs if v is not None]

                # PyTorch layers are called, not `applied`.
                # print("in net work layer: ", self.name)
                # print("network inputs type", type(inputs))
                # import torch
                # for inp in inputs:
                #     print("per input type = {} ".format(type(inp) ))
                #     if isinstance(inp, torch.Tensor):
                #         print("input shape = ", inp.shape)
                out = self.layer(*inputs)
                # print("layer output shape = ", out.shape)
                if self.activation_fn is None:
                    return out
                else:
                    # Apply activation fn.
                    return self.activation_fn(out)
Ejemplo n.º 4
0
    def _graph_fn_apply(self, *inputs):
        """
        The actual calculation on one or more input Ops.

        Args:
            inputs (SingleDataOp): The single (non-container) input(s) to the layer.

        Returns:
            The output(s) after having pushed input(s) through the layer.
        """
        # `self.layer` is not given: Only apply the activation function.
        if self.layer is None:
            # No activation function.
            if self.activation is None:
                return tuple(inputs)
            # Pass inputs through activation function.
            else:
                activation_function = get_activation_function(
                    self.activation, self.activation_params)
                output = activation_function(*inputs)
                # TODO: Move into util function.
                # Add batch-/time-rank flags.
                output._batch_rank = 0 if self.time_major is False else 1
                if self.in_space_0 and self.in_space_0.has_time_rank:
                    output._time_rank = 0 if self.in_space_0.time_major is True else 1
                return output
        # `self.layer` already includes activation function details.
        else:
            if get_backend() == "tf":
                output = self.layer.apply(*inputs)
                # Add batch-/time-rank flags.
                output._batch_rank = 0 if self.time_major is False else 1
                if self.in_space_0 and self.in_space_0.has_time_rank:
                    output._time_rank = 0 if self.in_space_0.time_major is True else 1
                return output
            elif get_backend() == "pytorch":
                # Strip empty internal states:
                # Ensure inputs are float tensors.
                input_tensors = []
                for value in inputs:
                    if value is not None and hasattr(value, "float"):
                        input_tensors.append(value.float())
                if not input_tensors:
                    return None

                # Common debug print:
                # print("in net work layer: ", self.name)
                # import torch
                # shapes = []
                # for inp in inputs:
                #     if hasattr(inp, "shape"):
                #         shapes.append(inp.shape)
                #     else:
                #         shapes.append(type(inp))
                # print("input shapes = ", shapes)
                # PyTorch layers are called, not `applied`.
                out = self.layer(*input_tensors)
                # print("layer output shape = ", out.shape)
                if self.activation_fn is None:
                    return out
                else:
                    # Apply activation fn.
                    return self.activation_fn(out)
Ejemplo n.º 5
0
    def create_variables(self, input_spaces, action_space=None):
        in_space = input_spaces["inputs[0]"]

        # Create kernel and biases initializers.
        self.kernel_init = Initializer.from_spec(
            shape=self.kernel_size, specification=self.kernel_spec)
        self.biases_init = Initializer.from_spec(
            shape=self.kernel_size, specification=self.biases_spec)

        # Wrapper for backend.
        if get_backend() == "tf":
            self.layer = tf.layers.Conv2D(
                filters=self.filters,
                kernel_size=self.kernel_size,
                strides=self.strides,
                padding=self.padding,
                data_format=self.data_format,
                activation=get_activation_function(self.activation,
                                                   *self.activation_params),
                use_bias=(self.biases_spec is not False),
                kernel_initializer=self.kernel_init.initializer,
                bias_initializer=(self.biases_init.initializer
                                  or tf.zeros_initializer()),
                trainable=(False if self.trainable is False else True),
                _reuse=tf.AUTO_REUSE)

            # Now build the layer so that its variables get created.
            self.layer.build(in_space.get_shape(with_batch_rank=True))
            # Register the generated variables with our registry.
            self.register_variables(*self.layer.variables)
        elif get_backend() == "pytorch":
            shape = in_space.shape
            num_channels = get_input_channels(shape)
            apply_bias = (self.biases_spec is not False)

            # print("Defining conv2d layer with shape = {} and channels {}".format(
            #     shape, num_channels
            # ))
            if self.padding == "same":
                # N.b. there is no 'same' or 'valid' padding for PyTorch so need custom layer.
                self.layer = SamePaddedConv2d(
                    in_channels=num_channels,
                    out_channels=self.filters,
                    # Only support square kernels.
                    kernel_size=self.kernel_size[0],
                    stride=self.strides,
                    bias=apply_bias)
            else:
                self.layer = nn.Conv2d(in_channels=num_channels,
                                       out_channels=self.filters,
                                       kernel_size=self.kernel_size,
                                       stride=self.strides,
                                       padding=0,
                                       bias=apply_bias)
            # Apply weight initializer
            if self.kernel_init.initializer is not None:
                # Must be a callable in PyTorch
                self.kernel_init.initializer(self.layer.weight)
            if apply_bias:
                if self.biases_spec is not None and self.biases_init.initializer is not None:
                    self.biases_init.initializer(self.layer.bias)
                else:
                    # Fill with zeros.
                    self.layer.bias.data.fill_(0)
            if self.activation is not None:
                # Activation function will be used in `call`.
                self.activation_fn = get_activation_function(
                    self.activation, *self.activation_params)
            self.register_variables(
                PyTorchVariable(name=self.global_scope, ref=self.layer))