coremltools/converters/keras/_topology.py [506:570]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    def insert_1d_permute_layers(self):
        """
        Insert permutation layers before a 1D start point or after 1D end point
        """
        idx, nb_layers = 0, len(self.layer_list)
        in_edges, out_edges = self._get_1d_interface_edges()

        # Hacky Warning: (1) use a 4-D permute, which is not likely to happen in Keras,
        # to represent actual permutation needed for (seq, c, h, w) in CoreML
        # (2) Assume 2-D input shape has meaning (seq, c), and during CoreML runtime,
        # it is represented as 4D blob, (seq, c, h, w)
        for in_edge in in_edges:
            src, snk = in_edge
            if src is None:
                permute_layer = "_permute_" + snk
            else:
                permute_layer = src + "_permute_" + snk
            keras_permute = _keras.layers.Permute(
                dims=(3, 1, 2, 0)
            )  # assume w = 1, switch seq and w
            self._insert_layer_between(src, snk, permute_layer, keras_permute)
        for out_edge in out_edges:
            src, snk = out_edge
            if snk is None:
                permute_layer = src + "_permute_"
            else:
                permute_layer = src + "_permute_" + snk
            keras_permute = _keras.layers.Permute(
                dims=(3, 1, 2, 0)
            )  # assume w = 1, switch seq and w back
            self._insert_layer_between(src, snk, permute_layer, keras_permute)

    def insert_permute_for_spatial_bn(self):

        # find spatial batchnorm layers
        spatial_bn_layers = []
        for layer in self.layer_list:
            keras_layer = self.keras_layer_map[layer]
            if (
                isinstance(keras_layer, _keras.layers.BatchNormalization)
                and len(keras_layer.input_shape) == 4
            ):
                if keras_layer.axis == 1 or keras_layer.axis == 2:
                    spatial_bn_layers.append(layer)

        for sbn in spatial_bn_layers:
            axis = self.keras_layer_map[sbn].axis
            # axis == 1: swap H axis; axis == 2 : swap W axis
            dims = (0, 2, 1, 3) if axis == 1 else (0, 3, 2, 1)
            # add permutation before spatial batchnorm
            pred = self.get_predecessors(sbn)[0]
            permute_layer = pred + "_permute_" + sbn
            keras_permute = _keras.layers.Permute(dims=dims)
            self._insert_layer_between(pred, sbn, permute_layer, keras_permute)
            # add permutation after spatial batchnorm
            succs = self.get_successors(sbn)
            if len(succs) == 0:
                permute_layer = sbn + "_permute_"
                keras_permute = _keras.layers.Permute(dims=dims)
                self._insert_layer_between(sbn, None, permute_layer, keras_permute)
            else:
                for succ in succs:
                    permute_layer = sbn + "_permute_" + succ
                    keras_permute = _keras.layers.Permute(dims=dims)
                    self._insert_layer_between(sbn, succ, permute_layer, keras_permute)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



coremltools/converters/keras/_topology2.py [620:684]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    def insert_1d_permute_layers(self):
        """
        Insert permutation layers before a 1D start point or after 1D end point
        """
        idx, nb_layers = 0, len(self.layer_list)
        in_edges, out_edges = self._get_1d_interface_edges()

        # Hacky Warning: (1) use a 4-D permute, which is not likely to happen in Keras,
        # to represent actual permutation needed for (seq, c, h, w) in CoreML
        # (2) Assume 2-D input shape has meaning (seq, c), and during CoreML runtime,
        # it is represented as 4D blob, (seq, c, h, w)
        for in_edge in in_edges:
            src, snk = in_edge
            if src is None:
                permute_layer = "_permute_" + snk
            else:
                permute_layer = src + "_permute_" + snk
            keras_permute = _keras.layers.Permute(
                dims=(3, 1, 2, 0)
            )  # assume w = 1, switch seq and w
            self._insert_layer_between(src, snk, permute_layer, keras_permute)
        for out_edge in out_edges:
            src, snk = out_edge
            if snk is None:
                permute_layer = src + "_permute_"
            else:
                permute_layer = src + "_permute_" + snk
            keras_permute = _keras.layers.Permute(
                dims=(3, 1, 2, 0)
            )  # assume w = 1, switch seq and w back
            self._insert_layer_between(src, snk, permute_layer, keras_permute)

    def insert_permute_for_spatial_bn(self):

        # find spatial batchnorm layers
        spatial_bn_layers = []
        for layer in self.layer_list:
            keras_layer = self.keras_layer_map[layer]
            if (
                isinstance(keras_layer, _keras.layers.BatchNormalization)
                and len(keras_layer.input_shape) == 4
            ):
                if keras_layer.axis == 1 or keras_layer.axis == 2:
                    spatial_bn_layers.append(layer)

        for sbn in spatial_bn_layers:
            axis = self.keras_layer_map[sbn].axis
            # axis == 1: swap H axis; axis == 2 : swap W axis
            dims = (0, 2, 1, 3) if axis == 1 else (0, 3, 2, 1)
            # add permutation before spatial batchnorm
            pred = self.get_predecessors(sbn)[0]
            permute_layer = pred + "_permute_" + sbn
            keras_permute = _keras.layers.Permute(dims=dims)
            self._insert_layer_between(pred, sbn, permute_layer, keras_permute)
            # add permutation after spatial batchnorm
            succs = self.get_successors(sbn)
            if len(succs) == 0:
                permute_layer = sbn + "_permute_"
                keras_permute = _keras.layers.Permute(dims=dims)
                self._insert_layer_between(sbn, None, permute_layer, keras_permute)
            else:
                for succ in succs:
                    permute_layer = sbn + "_permute_" + succ
                    keras_permute = _keras.layers.Permute(dims=dims)
                    self._insert_layer_between(sbn, succ, permute_layer, keras_permute)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



