def _try_match_and_transform_pattern_3(self, reduce_op, block) -> bool:
        """
        Detect ``InstanceNorm`` pattern in TensorFlow-Addons.

        This pattern corresponds to, and should be fused as, ``instance_norm``.

        All of the following conditions must be satisfied:

        1. ``input`` is rank 4 tensor.
        2. ``reduce`` operates on spatial dimensions ``axes=[-2, -1]``, or ``axes=[-3, -2]`` (a
           channel first to channel last transpose would be inserted in such cases).
        3. ``gamma`` and ``beta`` are absent. Default values for ``gamma`` and ``beta`` would be used.

        .. code-block::

                   |-------------------------------------------------|
                   |                                                 |
                   |                                                 V
            x --> mean   square --> mean1 --> add_eps --> rsqrt --> mul2 --> mul_sub
            |      |       ^                                |                   |
            |      V       |                                |                   |
            | --> sub -----|                                |                   |
            |                                               V                   V
            |--------------------------------------------> mul1 -------------> add --> ...
        """
        ops_to_remove = []
        root_var = reduce_op.x

        if root_var.shape is None:
            return False

        # check that root_var feeds into exactly 3 ops
        if len(root_var.child_ops) != 3:
            return False
        if root_var.op is not None and not self._check_child_op_types(
            root_var.op, ["sub", "mul", "reduce_mean"]
        ):
            return False

        # check 1st reduce_mean op
        if not self._check_reduce_op(reduce_op):
            return False
        ops_to_remove.append(reduce_op)

        # check 1st sub op
        if not self._check_child_op_types(reduce_op, ["sub", "mul"], check_order=False):
            return False
        child_ops_reduce_mean = list(reduce_op.outputs[0].child_ops)
        reduce_mean_child_op_a = child_ops_reduce_mean[0]
        reduce_mean_child_op_b = child_ops_reduce_mean[1]
        sub_op1 = (
            reduce_mean_child_op_a
            if reduce_mean_child_op_a.op_type == "sub"
            else reduce_mean_child_op_b
        )
        if not (sub_op1.x == root_var and sub_op1.y == reduce_op.outputs[0]):
            return False
        ops_to_remove.append(sub_op1)

        # check square op
        square_op = self._try_get_child_op_type(sub_op1, "square")
        if square_op is None:
            return False
        ops_to_remove.append(square_op)

        # check second reduce mean
        reduce_op2 = self._try_get_child_op_type(square_op, "reduce_mean")
        if reduce_op2 is None or not self._check_reduce_op(reduce_op2):
            return False
        ops_to_remove.append(reduce_op2)

        # check add op (with epsilon)
        add_eps_op = self._try_get_child_op_type(reduce_op2, "add")
        if add_eps_op is None:
            return False
        epsilon_var = add_eps_op.y if add_eps_op.x == reduce_op2.outputs[0] else add_eps_op.x
        if epsilon_var.val is None or len(epsilon_var.val.shape) != 0:
            return False  # must be scalar
        ops_to_remove.append(add_eps_op)

        # check rsqrt
        rsqrt_op = self._try_get_child_op_type(add_eps_op, "rsqrt")
        if rsqrt_op is None:
            return False
        ops_to_remove.append(rsqrt_op)

        # check mul 1
        mul_op1 = self._try_get_child_op_type(rsqrt_op, "mul")
        if mul_op1 is None:
            return False
        if not (
            (mul_op1.x == root_var and mul_op1.y == rsqrt_op.outputs[0])
            or (mul_op1.x == rsqrt_op.outputs[0] and mul_op1.y == root_var)
        ):
            return False
        ops_to_remove.append(mul_op1)

        # check mul 2
        mul_op2 = self._try_get_child_op_type(rsqrt_op, "mul", index=1)
        if mul_op2 is None:
            return False
        if not (
            (mul_op2.x == reduce_op.outputs[0] and mul_op2.y == rsqrt_op.outputs[0])
            or (mul_op2.x == rsqrt_op.outputs[0] and mul_op2.y == reduce_op.outputs[0])
        ):
            return False
        ops_to_remove.append(mul_op2)

        # check mul (sub)
        mul_sub_op = self._try_get_child_op_type(mul_op2, "mul")
        if mul_sub_op is None:
            return False
        if mul_sub_op.y.val is None or mul_sub_op.y.val != -1:
            return False
        ops_to_remove.append(mul_sub_op)

        # check last add op
        add_op = self._try_get_child_op_type(mul_sub_op, "add")
        if add_op is None:
            return False
        if not (
            (add_op.x == mul_op1.outputs[0] and add_op.y == mul_sub_op.outputs[0])
            or (add_op.x == mul_sub_op.outputs[0] and add_op.y == mul_op1.outputs[0])
        ):
            return False
        ops_to_remove.append(add_op)

        gamma_var = mb.const(
            val=np.ones(shape=(1, root_var.shape[1], 1, 1)),
            name="_fuse_layernorm_or_instancenorm_gamma",
        )
        beta_var = mb.const(
            val=np.zeros(shape=(1, root_var.shape[1], 1, 1)),
            name="_fuse_layernorm_or_instancenorm_beta",
        )

        return self._try_apply_transform(
            reduce_op, block, gamma_var, beta_var, epsilon_var, add_op, ops_to_remove
        )

        Detect ``InstanceNorm`` pattern in TensorFlow-Addons.

        This pattern corresponds to, and should be fused as, ``instance_norm``.

        All of the following conditions must be satisfied:

        1. ``input`` is rank 4 tensor.
        2. ``reduce`` operates on spatial dimensions ``axes=[-2, -1]``, or ``axes=[-3, -2]`` (a
           channel first to channel last transpose would be inserted in such cases).
        3. ``gamma`` and ``beta`` are absent. Default values for ``gamma`` and ``beta`` would be used.

        .. code-block::

                   |-------------------------------------------------|
                   |                                                 |
                   |                                                 V
            x --> mean   square --> mean1 --> add_eps --> rsqrt --> mul2 --> mul_sub
            |      |       ^                                |                   |
            |      V       |                                |                   |
            | --> sub -----|                                |                   |
            |                                               V                   V
            |--------------------------------------------> mul1 -------------> add --> ...
        
coremltools/converters/mil/mil/passes/defs/optimize_normalization.py