예제 #1
0
def asarray(x: Any, dtype: Optional[str] = None) -> np.ndarray:
    """Convert `x` to interger Numpy array.

    Parameters:
    ----------
    x: Tensor, Scipy sparse matrix,
        Numpy array-like, etc.

    Returns:
    ----------
    Integer Numpy array with dtype or `'int64'`

    """
    if dtype is None:
        dtype = 'int64'

    if torch.is_tensor(x):
        if x.dtype != dtype:
            return x.to(getattr(torch, dtype))
        else:
            return x

    if gg.is_intscalar(x):
        x = np.asarray([x], dtype=dtype)
    elif gg.is_listlike(x) or (isinstance(x, np.ndarray) and x.dtype != "O"):
        x = np.asarray(x, dtype=dtype)
    else:
        raise ValueError(
            f"Invalid input which should be either array-like or integer scalar, but got {type(x)}."
        )
    return x
예제 #2
0
    def attack(self, target, num_budgets, direct_attack, structure_attack,
               feature_attack):

        if not self.is_reseted:
            raise RuntimeError(
                'Before calling attack, you must reset your attacker. Use `attacker.reset()`.'
            )

        if not gg.is_intscalar(target):
            raise ValueError(target)

        if not (structure_attack or feature_attack):
            raise RuntimeError(
                'Either `structure_attack` or `feature_attack` must be True.')

        if feature_attack and not self.allow_feature_attack:
            raise RuntimeError(
                f"{self.name} does NOT support attacking features."
                " If the model can conduct feature attack, please call `attacker.allow_feature_attack=True`."
            )

        if structure_attack and not self.allow_structure_attack:
            raise RuntimeError(
                f"{self.name} does NOT support attacking structures."
                " If the model can conduct structure attack, please call `attacker.allow_structure_attack=True`."
            )

        if num_budgets is None:
            num_budgets = int(self.graph.degree[target])
        else:
            num_budgets = self.budget_as_int(
                num_budgets, max_perturbations=self.graph.degree[target])

        self.target = target
        self.target_label = self.graph.node_label[
            target] if self.graph.node_label is not None else None
        self.num_budgets = num_budgets
        self.direct_attack = direct_attack
        self.structure_attack = structure_attack
        self.feature_attack = feature_attack
        self.is_reseted = False
예제 #3
0
    def __init__(self,
                 target,
                 width=30,
                 verbose=1,
                 interval=0.05,
                 unit_name='step'):

        assert gg.is_intscalar(target), target
        self.target = target
        self.width = width
        self.verbose = verbose
        self.interval = interval
        self.unit_name = unit_name

        self._dynamic_display = ((hasattr(sys.stdout, 'isatty')
                                  and sys.stdout.isatty())
                                 or 'ipykernel' in sys.modules
                                 or 'posix' in sys.modules
                                 or 'PYCHARM_HOSTED' in os.environ)
        self._total_width = 0
        self._seen_so_far = 0
        self._start = time.perf_counter()
        self._last_update = 0
예제 #4
0
def augment_edge(edge_index: np.ndarray,
                 nodes: np.ndarray,
                 edge_weight: np.ndarray = None,
                 *,
                 nbrs_to_link: Optional[np.ndarray] = None,
                 common_nbrs: Optional[np.ndarray] = None,
                 fill_weight: float = 1.0) -> tuple:
    """Augment a set of edges by connecting nodes to
        element in ``nbrs_to_link``.


    Parameters
    ----------
    edge_index: shape [M, 2] or [2, M]
        edge indices of a Scipy sparse adjacency matrix.
    nodes: the nodes that will be linked to the graph.
        list or np.array: the nodes connected to `nbrs_to_link`
        int: new added nodes connected to ``nbrs_to_link``, 
            node ids [num_nodes, ..., num_nodes+nodes-1].            
    edge_weight: shape [M,]
        edge weights of a Scipy sparse adjacency matrix.
    nbrs_to_link: a list of N elements,
        where N is the length of 'nodes'.
        the specified neighbor(s) for each added node.
        if `None`, it will be set to `[0, ..., N-1]`.
    common_nbrs: shape [None,].
        specified common neighbors for each added node.
    fill_weight: edge weight for the augmented edges.

    NOTE:
    -----
    Both ``nbrs_to_link`` and ``common_nbrs`` should NOT be specified together.

    See Also
    --------
    graphgallery.functional.augment_adj

    """

    if nbrs_to_link is not None and common_nbrs is not None:
        raise RuntimeError("Only one of them should be specified.")

    edge_index = asedge(edge_index)

    if edge_weight is None:
        edge_weight = np.ones(edge_index.shape[1], dtype=gg.floatx())

    num_nodes = edge_index.max() + 1

    if gg.is_intscalar(nodes):
        # int, add nodes to the graph
        nodes = np.arange(num_nodes, num_nodes + nodes, dtype=edge_index.dtype)
    else:
        # array-like, link nodes to the graph
        nodes = np.asarray(nodes, dtype=edge_index.dtype)

    if common_nbrs is None and nbrs_to_link is None:
        nbrs_to_link = np.arange(nodes.size, dtype=edge_index.dtype)

    if not nodes.size == len(nbrs_to_link):
        raise ValueError(
            "The length of 'nbrs_to_link' should equal to 'nodes'.")

    if nbrs_to_link is not None:
        edges_to_link = np.hstack([
            np.vstack([np.tile(node, get_length(nbr)), nbr])
            for node, nbr in zip(nodes, nbrs_to_link)
        ])
    else:
        n_repeat = len(common_nbrs)
        edges_to_link = np.hstack([
            np.vstack([np.tile(node, n_repeat), common_nbrs]) for node in nodes
        ])

    edges_to_link = np.hstack([edges_to_link, edges_to_link[[1, 0]]])
    added_edge_weight = np.zeros(edges_to_link.shape[1],
                                 dtype=edge_weight.dtype) + fill_weight

    augmented_edge_index = np.hstack([edge_index, edges_to_link])
    augmented_edge_weight = np.hstack([edge_weight, added_edge_weight])

    return augmented_edge_index, augmented_edge_weight