def _sign_recovery(self, unit_vector_scale: int, ftol: float) -> None:
        """
        Recover the sign of weights in the first layer.

        :param unit_vector_scale: Multiplicative scale of the unit vector e_j.
        :param ftol: Tolerance for termination by the change of the cost function.
        """
        logger.info("Recover sign of the weights of the first layer.")

        if self.num_neurons is None:
            raise ValueError("The value of `num_neurons` is required for critical point search.")

        a0_pairwise_ratios_inverse = 1.0 / self.a0_pairwise_ratios
        self.b_0 = np.zeros((self.num_neurons, 1), dtype=NUMPY_DTYPE)

        for i in range(self.num_neurons):
            x_i = self.critical_points[i].flatten()
            self.b_0[i] = -np.matmul(a0_pairwise_ratios_inverse[:, i], x_i)

        z_0 = np.random.normal(0, 1, (self.num_features,)).astype(dtype=NUMPY_DTYPE)

        def f_z(z_i):
            return np.squeeze(np.matmul(a0_pairwise_ratios_inverse.T, np.expand_dims(z_i, axis=0).T) + self.b_0)

        result_z = least_squares(f_z, z_0, ftol=ftol)

        for i in range(self.num_neurons):
            e_i = np.zeros((self.num_neurons, 1), dtype=NUMPY_DTYPE)
            e_i[i, 0] = unit_vector_scale

            def f_v(v_i):
                # pylint: disable=cell-var-from-loop
                return np.squeeze(np.matmul(-a0_pairwise_ratios_inverse.T, np.expand_dims(v_i, axis=0).T) - e_i)

            v_0 = np.random.normal(0, 1, self.num_features)
            result_v_i = least_squares(f_v, v_0, ftol=ftol)
            value_p = np.sum(
                np.abs(
                    self._o_l(np.expand_dims(result_z.x, axis=0))
                    - (self._o_l(np.expand_dims(result_z.x + result_v_i.x, axis=0)))
                )
            )
            value_m = np.sum(
                np.abs(
                    self._o_l(np.expand_dims(result_z.x, axis=0))
                    - (self._o_l(np.expand_dims(result_z.x - result_v_i.x, axis=0)))
                )
            )

            if value_m < value_p:
                a0_pairwise_ratios_inverse[:, i] *= -1
                self.b_0[i, 0] *= -1

        self.w_0 = a0_pairwise_ratios_inverse

        Recover the sign of weights in the first layer.

        :param unit_vector_scale: Multiplicative scale of the unit vector e_j.
        :param ftol: Tolerance for termination by the change of the cost function.
        
art/attacks/extraction/functionally_equivalent_extraction.py