Exemple #1
0
    def call(self, inputs):
        # Channels first arrangement: (batch_size, num_input_channels, width, height)
        # Channels last arrangement: (batch_size, width, height, num_input_channels)

        # If activation quantisation is enabled
        if self.binarise_input:

            # Compute the axis ID of the channels.  Use tensorflow channels last arrangement as standard
            channels_axis = 3

            if self.data_format == 'channels_first':
                channels_axis = 1

            # Compute A, which is the average across channels.
            # The input will thus reduce to a single-channel image
            # In Keras, (minibatch_size, 1, height, width)
            A = K.mean(K.abs(inputs), axis=channels_axis, keepdims=True)

            # k filter should be of shape (filter_size, filter_size, 1, 1) as per keras 2 notation
            # K is of shape (batch_size, 1, width, height) (using channels first data format)
            K_variable = K.conv2d(A,
                                  self.k_filter,
                                  strides=self.strides,
                                  padding=self.padding,
                                  data_format=self.data_format,
                                  dilation_rate=self.dilation_rate)

            # Binarise the input
            binarisedInput = passthroughSign(inputs)

            # Call the base convolution operation
            # Convolution output will be of shape (batch_size, width, height, num_output_channels) (channels first)
            convolutionOutput = K.conv2d(binarisedInput,
                                         self.kernel,
                                         strides=self.strides,
                                         padding=self.padding,
                                         data_format=self.data_format,
                                         dilation_rate=self.dilation_rate)

            # Copy K for each output channel
            # K will thus go from shape (batch_size, 1, width, height) to (batch_size, 1, width, height)
            # (with channels_first data format)
            if K.backend() == 'tensorflow':
                K_variable = K.repeat_elements(
                    K_variable,
                    K.int_shape(convolutionOutput)[channels_axis],
                    axis=channels_axis)
            else:
                K_variable = K.repeat_elements(
                    K_variable,
                    K.shape(convolutionOutput)[channels_axis],
                    axis=channels_axis)

            outputs = K_variable * convolutionOutput

            return outputs

        else:
            # Call the base convolution operation.  Only the weights are quantised in this case
            return super(XNORNetConv2D, self).call(inputs)
Exemple #2
0
    def call(self, inputs):

        # For theano, binarisation is done as a seperate layer
        if K.backend() == 'tensorflow':
            binarisedInput = passthroughSign(inputs)
        else:
            binarisedInput = inputs

        return super().call(binarisedInput)
Exemple #3
0
 def call(self, inputs):
     # In BinaryNet, the output activation is binarised (normally done at the input to each layer in our implementation)
     return passthroughSign(inputs)