コード例 #1
0
    def __init__(self, num_units, adj_mx, max_diffusion_step, num_nodes, num_proj=None,
                 activation=tf.nn.tanh, reuse=None, filter_type="laplacian", use_gc_for_ru=True):
        """

        :param num_units:
        :param adj_mx:
        :param max_diffusion_step:
        :param num_nodes:
        :param input_size:
        :param num_proj:
        :param activation:
        :param reuse:
        :param filter_type: "laplacian", "random_walk", "dual_random_walk".
        :param use_gc_for_ru: whether to use Graph convolution to calculate the reset and update gates.
        """
        super(DCGRUCell, self).__init__(_reuse=reuse)
        self._activation = activation
        self._num_nodes = num_nodes
        self._num_proj = num_proj
        self._num_units = num_units
        self._max_diffusion_step = max_diffusion_step
        self._supports = []
        self._use_gc_for_ru = use_gc_for_ru
        supports = []
        if filter_type == "laplacian":
            supports.append(utils.calculate_scaled_laplacian(adj_mx, lambda_max=None))
        elif filter_type == "random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
        elif filter_type == "dual_random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
            supports.append(utils.calculate_random_walk_matrix(adj_mx.T).T)
        else:
            supports.append(utils.calculate_scaled_laplacian(adj_mx))
        for support in supports:
            self._supports.append(self._build_sparse_matrix(support))
コード例 #2
0
    def __init__(self,
                 num_units,
                 adj_mx,
                 max_diffusion_step,
                 num_nodes,
                 num_proj=None,
                 activation=tf.nn.tanh,
                 reuse=None,
                 filter_type="laplacian",
                 use_gc_for_ru=True,
                 **kwargs):
        super(DCLSTMCell, self).__init__(**kwargs)

        self._activation = activation
        self._num_nodes = num_nodes
        self._num_proj = num_proj
        self._num_units = num_units
        self._max_diffusion_step = max_diffusion_step
        self._supports = []
        self._use_gc_for_ru = use_gc_for_ru
        supports = []
        if filter_type == "laplacian":
            supports.append(
                utils.calculate_scaled_laplacian(adj_mx, lambda_max=None))
        elif filter_type == "random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
        elif filter_type == "dual_random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
            supports.append(utils.calculate_random_walk_matrix(adj_mx.T).T)
        else:
            supports.append(utils.calculate_scaled_laplacian(adj_mx))
        for support in supports:
            self._supports.append(self._build_sparse_matrix(support))
コード例 #3
0
ファイル: dcrnn_cell.py プロジェクト: xlwang233/pytorch-DCRNN
    def __init__(self,
                 input_dim,
                 num_units,
                 adj_mat,
                 max_diffusion_step,
                 num_nodes,
                 num_proj=None,
                 activation=torch.tanh,
                 use_gc_for_ru=True,
                 filter_type='laplacian'):
        """
        :param num_units: the hidden dim of rnn
        :param adj_mat: the (weighted) adjacency matrix of the graph, in numpy ndarray form
        :param max_diffusion_step: the max diffusion step
        :param num_nodes:
        :param num_proj: num of output dim, defaults to 1 (speed)
        :param activation: if None, don't do activation for cell state
        :param use_gc_for_ru: decide whether to use graph convolution inside rnn
        """
        super(DCGRUCell, self).__init__()
        self._activation = activation
        self._num_nodes = num_nodes
        self._num_units = num_units
        self._max_diffusion_step = max_diffusion_step
        self._num_proj = num_proj
        self._use_gc_for_ru = use_gc_for_ru
        self._supports = []
        supports = []
        if filter_type == "laplacian":
            supports.append(
                utils.calculate_scaled_laplacian(adj_mat, lambda_max=None))
        elif filter_type == "random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mat).T)
        elif filter_type == "dual_random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mat))
            supports.append(utils.calculate_random_walk_matrix(adj_mat.T))
        else:
            supports.append(utils.calculate_scaled_laplacian(adj_mat))
        for support in supports:
            self._supports.append(self._build_sparse_matrix(
                support).cuda())  # to PyTorch sparse tensor
        # supports = utils.calculate_scaled_laplacian(adj_mat, lambda_max=None)  # scipy coo matrix
        # self._supports = self._build_sparse_matrix(supports).cuda()  # to pytorch sparse tensor

        self.dconv_gate = DiffusionGraphConv(
            supports=self._supports,
            input_dim=input_dim,
            hid_dim=num_units,
            num_nodes=num_nodes,
            max_diffusion_step=max_diffusion_step,
            output_dim=num_units * 2)
        self.dconv_candidate = DiffusionGraphConv(
            supports=self._supports,
            input_dim=input_dim,
            hid_dim=num_units,
            num_nodes=num_nodes,
            max_diffusion_step=max_diffusion_step,
            output_dim=num_units)
        if num_proj is not None:
            self.project = nn.Linear(self._num_units, self._num_proj)
コード例 #4
0
    def __init__(self,
                 num_units,
                 adj_mx,
                 max_diffusion_step,
                 num_nodes,
                 batch_size,
                 num_proj=None,
                 activation=tf.nn.tanh,
                 reuse=None,
                 filter_type="laplacian",
                 use_gc_for_ru=True):
        """

        :param num_units:
        :param adj_mx:
        :param max_diffusion_step:
        :param num_nodes:
        :param input_size:
        :param num_proj:
        :param activation:
        :param reuse:
        :param filter_type: "laplacian", "random_walk", "dual_random_walk".
        :param use_gc_for_ru: whether to use Graph convolution to calculate the reset and update gates.
        """
        super(DCLSTMCellAtt, self).__init__(_reuse=reuse)
        self._activation = activation
        self._num_nodes = num_nodes
        self._num_proj = num_proj
        self._num_units = num_units
        self._max_diffusion_step = max_diffusion_step
        self._supports = []
        self._use_gc_for_ru = use_gc_for_ru
        supports = []
        if filter_type == "laplacian":
            supports.append(
                utils.calculate_scaled_laplacian(adj_mx, lambda_max=None))
        elif filter_type == "random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
        elif filter_type == "dual_random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
            supports.append(utils.calculate_random_walk_matrix(adj_mx.T).T)
        else:
            supports.append(utils.calculate_scaled_laplacian(adj_mx))
        for support in supports:
            self._supports.append(self._build_sparse_matrix(support))

        self._bias_mt = tf.convert_to_tensor(utils.adj_to_bias(np.expand_dims(
            adj_mx, axis=0), [self._num_nodes],
                                                               nhood=1),
                                             dtype=tf.float32)
        _adj_mx = tf.convert_to_tensor(adj_mx)
        self._adj_mx_repeat = tf.tile(tf.expand_dims(_adj_mx, axis=0),
                                      [batch_size, 1, 1])
        for support in self._supports:
            self._supports_dense.append(tf.sparse.to_dense(support))
コード例 #5
0
 def __init__(self, input_dim, num_units, adj_mat, max_diffusion_step, num_nodes,
              num_proj=None, activation=torch.tanh, use_gc_for_ru=True):
     """
     :param num_units: the hidden dim of rnn
     :param adj_mat: the (weighted) adjacency matrix of the graph, in numpy ndarray form
     :param max_diffusion_step: the max diffusion step
     :param num_nodes:
     :param num_proj: num of output dim, defaults to 1 (speed)
     :param activation: if None, don't do activation for cell state
     :param use_gc_for_ru: decide whether to use graph convolution inside rnn
     """
     super(DCGRUCell, self).__init__()
     self._activation = activation
     self._num_nodes = num_nodes
     self._num_units = num_units
     self._max_diffusion_step = max_diffusion_step
     self._num_proj = num_proj
     self._use_gc_for_ru = use_gc_for_ru
     supports = utils.calculate_scaled_laplacian(adj_mat, lambda_max=None)  # scipy coo matrix
     self._supports = self._build_sparse_matrix(supports).cuda()  # to pytorch sparse tensor
     # self.register_parameter('weight', None)
     # self.register_parameter('biases', None)
     # temp_inputs = torch.FloatTensor(torch.rand((batch_size, num_nodes * input_dim)))
     # temp_state = torch.FloatTensor(torch.rand((batch_size, num_nodes * num_units)))
     # self.forward(temp_inputs, temp_state)
     self.dconv_gate = DiffusionGraphConv(supports=self._supports, input_dim=input_dim,
                                          hid_dim=num_units, num_nodes=num_nodes,
                                          max_diffusion_step=max_diffusion_step,
                                          output_dim=num_units*2)
     self.dconv_candidate = DiffusionGraphConv(supports=self._supports, input_dim=input_dim,
                                               hid_dim=num_units, num_nodes=num_nodes,
                                               max_diffusion_step=max_diffusion_step,
                                               output_dim=num_units)
     if num_proj is not None:
         self.project = nn.Linear(self._num_units, self._num_proj)
コード例 #6
0
ファイル: dcrnn_cell.py プロジェクト: syin3/cs224w-traffic
 def __init__(self, num_units, adj_mx, max_diffusion_step, num_nodes, network_type, graphEmbedFile, num_proj=None,
              activation=tf.nn.tanh, reuse=None, filter_type="laplacian"):
     """
     :param num_units:
     :param adj_mx:
     :param max_diffusion_step:
     :param num_nodes:
     :param input_size:
     :param num_proj:
     :param activation:
     :param reuse:
     :param filter_type: "laplacian", "random_walk", "dual_random_walk".
     :param use_gc_for_ru: whether to use Graph convolution to calculate the reset and update gates.
     """
     super(DCGRUCell, self).__init__(_reuse=reuse)
     self._activation = activation
     self._num_nodes = num_nodes
     self._num_proj = num_proj
     self._num_units = num_units
     # print(num_nodes, num_proj, num_units)
     # 207 None 64: when creating cell
     # 207 1 64: when creating cell_with_projection
     self._max_diffusion_step = max_diffusion_step
     self._supports = []
     self._use_gc_for_ru = (network_type=='gconv')
     self._graphEmbedFile = graphEmbedFile
     supports = []
     if filter_type == "laplacian":
         supports.append(utils.calculate_scaled_laplacian(adj_mx, lambda_max=None))
     elif filter_type == "random_walk":
         supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
     elif filter_type == "dual_random_walk":
         # supports have now two matrices for the two directions
         # all of them are of form D^{-1}W
         supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
         supports.append(utils.calculate_random_walk_matrix(adj_mx.T).T)
     else:
         supports.append(utils.calculate_scaled_laplacian(adj_mx))
     # print('This is the number of matrices: ', len(supports))
     # 2
     # There are 2 matrices for bi-directional random walk
     # Hence either one or two matrices will be in list of supports
     for support in supports:
         self._supports.append(self._build_sparse_matrix(support))
コード例 #7
0
ファイル: dchyp_cell.py プロジェクト: anupam312nwd/dcgru_hyp
    def __init__(self,
                 num_units,
                 adj_mx,
                 max_diffusion_step,
                 num_nodes,
                 nonlinearity='tanh',
                 filter_type="laplacian",
                 use_gc_for_ru=True):
        """

        :param num_units:
        :param adj_mx:
        :param max_diffusion_step:
        :param num_nodes:
        :param nonlinearity:
        :param filter_type: "laplacian", "random_walk", "dual_random_walk".
        :param use_gc_for_ru: whether to use Graph convolution to calculate the reset and update gates.
        """

        super().__init__()
        self._activation = torch.tanh if nonlinearity == 'tanh' else torch.relu
        # support other nonlinearities up here?
        self._num_nodes = num_nodes
        self._num_units = num_units
        self._max_diffusion_step = max_diffusion_step
        self._supports = []
        self._use_gc_for_ru = use_gc_for_ru
        self._mfd = PoincareManifold()
        supports = []
        if filter_type == "laplacian":
            supports.append(
                utils.calculate_scaled_laplacian(adj_mx, lambda_max=None))
        elif filter_type == "random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
        elif filter_type == "dual_random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
            supports.append(utils.calculate_random_walk_matrix(adj_mx.T).T)
        else:
            supports.append(utils.calculate_scaled_laplacian(adj_mx))
        for support in supports:
            self._supports.append(self._build_sparse_matrix(support))

        self._fc_params = LayerParams(self, 'fc')
        self._gconv_params = LayerParams(self, 'gconv')
コード例 #8
0
ファイル: dcrnn_trainer.py プロジェクト: xlwang233/GCRNN
    def _valid_epoch(self, epoch):
        """
        Validate after training an epoch

        :return: A log that contains information about validation

        Note:
            The validation metrics in log must have the key 'val_metrics'.
        """
        self.model.eval()
        total_val_loss = 0
        total_val_metrics = np.zeros(len(self.metrics))
        with torch.no_grad():
            for batch_idx, (data, target, adj_mat) in enumerate(
                    self.valid_data_loader.get_iterator()):
                data = torch.FloatTensor(data)
                target = torch.FloatTensor(target)
                label = target[
                    ..., :self.model.
                    output_dim]  # (..., 1)  supposed to be numpy array
                data, target = data.to(self.device), target.to(self.device)
                # construct the adj_mat here
                adj_mat = utils.calculate_scaled_laplacian(
                    adj_mat, lambda_max=None)  # scipy coo matrix
                adj_mat = self._build_sparse_matrix(
                    adj_mat)  # to PyTorch sparse tensor
                adj_mat = adj_mat.to(self.device)

                output = self.model(data, target, adj_mat, 0)
                output = torch.transpose(
                    output.view(12, self.model.batch_size,
                                self.model.num_nodes, self.model.output_dim),
                    0, 1)  # back to (50, 12, 207, 1)

                loss = self.loss(output.cpu(), label)

                self.writer.set_step(
                    (epoch - 1) * self.val_len_epoch + batch_idx, 'valid')
                self.writer.add_scalar('loss', loss.item())
                total_val_loss += loss.item()
                total_val_metrics += self._eval_metrics(
                    output.detach().numpy(), label.numpy())
                # self.writer.add_image('input', make_grid(data.cpu(), nrow=8, normalize=True))

        # add histogram of model parameters to the tensorboard
        for name, p in self.model.named_parameters():
            self.writer.add_histogram(name, p, bins='auto')

        return {
            'val_loss': total_val_loss / self.val_len_epoch,
            'val_metrics': (total_val_metrics / self.val_len_epoch).tolist()
        }
コード例 #9
0
ファイル: dcrnn_cell.py プロジェクト: Minyus/DCRNN
    def __init__(self,
                 num_units,
                 adj_mx,
                 max_diffusion_step,
                 num_nodes,
                 num_proj=None,
                 activation=tf.nn.tanh,
                 reuse=None,
                 filter_type="laplacian",
                 use_gc_for_ru=True,
                 output_activation=None,
                 proximity_threshold=None):
        """

        :param num_units:
        :param adj_mx:
        :param max_diffusion_step:
        :param num_nodes:
        :param input_size:
        :param num_proj:
        :param activation:
        :param reuse:
        :param filter_type: "laplacian", "random_walk", "dual_random_walk".
        :param use_gc_for_ru: whether to use Graph convolution to calculate the reset and update gates.
        """
        super(DCGRUCell, self).__init__(_reuse=reuse)
        self._activation = activation
        self._output_activation = output_activation
        self._num_nodes = num_nodes
        self._num_proj = num_proj
        self._num_units = num_units
        self._max_diffusion_step = max_diffusion_step
        self._use_gc_for_ru = use_gc_for_ru

        self.id_mx = utils.calculate_identity(adj_mx)
        self._supports = []
        supports = []

        adj_mx[adj_mx < proximity_threshold] = 0
        # adj_mx[adj_mx < proximity_threshold['end_proximity']] = 0
        # self.proximity_threshold = proximity_threshold
        # self.pct_adj_mx = percentile_nd(adj_mx).astype(np.float32)

        if filter_type == "laplacian":
            supports.append(
                utils.calculate_scaled_laplacian(adj_mx, lambda_max=None))
        elif filter_type == "laplacian_lambda_max_2":
            supports.append(
                utils.calculate_scaled_laplacian(adj_mx, lambda_max=2))
        elif filter_type == "laplacian_lambda_max_1":
            supports.append(
                utils.calculate_scaled_laplacian(adj_mx, lambda_max=1))
        elif filter_type == "random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
        elif filter_type == "dual_random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
            supports.append(utils.calculate_random_walk_matrix(adj_mx.T).T)
        elif filter_type == "ignore_spatial_dependency":
            supports.append(self.id_mx)
        else:
            raise ValueError("Invalid filter_type: {}".format(filter_type))
        for support in supports:

            # support = np.asarray(support.todense())
            # threshold = \
            #     linear_cosine_decay_start_end(start=self.proximity_threshold['start_proximity'],
            #                                   end=self.proximity_threshold['end_proximity'],
            #                                   global_step=tf.train.get_or_create_global_step(),
            #                                   decay_steps=self.proximity_threshold['proximity_decay_steps'],
            #                                   )
            # support = thresholded_dense_to_sparse(support, self.pct_adj_mx, threshold=threshold)
            #
            # self._supports.append(support)

            self._supports.append(self._build_sparse_matrix(support))
コード例 #10
0
ファイル: dcrnn_trainer.py プロジェクト: xlwang233/GCRNN
    def _train_epoch(self, epoch):
        """
        Training logic for an epoch

        :param epoch: Current training epoch.
        :return: A log that contains all information you want to save.

        Note:
            If you have additional information to record, for example:
                > additional_log = {"x": x, "y": y}
            merge it with log before return. i.e.
                > log = {**log, **additional_log}
                > return log

            The metrics in log must have the key 'metrics'.
        """
        self.model.train()

        total_loss = 0
        total_metrics = np.zeros(len(self.metrics))
        for batch_idx, (data, target,
                        adj_mat) in enumerate(self.data_loader.get_iterator()):
            data = torch.FloatTensor(data)
            target = torch.FloatTensor(target)
            label = target[..., :self.model.
                           output_dim]  # (..., 1)  supposed to be numpy array
            data, target = data.to(self.device), target.to(self.device)
            # construct the adj_mat here
            adj_mat = utils.calculate_scaled_laplacian(
                adj_mat, lambda_max=None)  # scipy coo matrix
            adj_mat = self._build_sparse_matrix(
                adj_mat)  # to PyTorch sparse tensor
            adj_mat = adj_mat.to(self.device)

            self.optimizer.zero_grad()

            # compute sampling ratio, which gradually decay to 0 during training
            global_step = (epoch - 1) * self.len_epoch + batch_idx
            teacher_forcing_ratio = self._compute_sampling_threshold(
                global_step, self.cl_decay_steps)

            output = self.model(data, target, adj_mat, teacher_forcing_ratio)
            output = torch.transpose(
                output.view(12, self.model.batch_size, self.model.num_nodes,
                            self.model.output_dim), 0,
                1)  # back to (50, 12, 207, 1)

            loss = self.loss(output.cpu(),
                             label)  # loss is self-defined, need cpu input
            loss.backward()
            # add max grad clipping
            torch.nn.utils.clip_grad_norm_(self.model.parameters(),
                                           self.max_grad_norm)
            self.optimizer.step()

            self.writer.set_step((epoch - 1) * self.len_epoch + batch_idx)
            self.writer.add_scalar('loss', loss.item())
            total_loss += loss.item()
            total_metrics += self._eval_metrics(output.detach().numpy(),
                                                label.numpy())

            if batch_idx % self.log_step == 0:
                self.logger.debug('Train Epoch: {} {} Loss: {:.6f}'.format(
                    epoch, self._progress(batch_idx), loss.item()))

            if batch_idx == self.len_epoch:
                break

        log = {
            'loss': total_loss / self.len_epoch,
            'metrics': (total_metrics / self.len_epoch).tolist()
        }

        if self.do_validation:
            val_log = self._valid_epoch(epoch)
            log.update(val_log)

        if self.lr_scheduler is not None:
            self.lr_scheduler.step()

        return log
コード例 #11
0
    def __init__(self,
                 args,
                 num_units,
                 adj_mx,
                 squeeze_and_excitation,
                 se_activate,
                 excitation_rate,
                 r,
                 diffusion_with_graph_kernel,
                 graph_kernel_mode,
                 cell_forward_mode,
                 max_diffusion_step,
                 num_nodes,
                 num_proj=None,
                 activation=tf.nn.tanh,
                 reuse=None,
                 filter_type="laplacian",
                 use_gc_for_ru=True):
        """

        :param num_units:
        :param adj_mx:
        :param max_diffusion_step:
        :param num_nodes:
        :param input_size:
        :param num_proj:
        :param activation:
        :param reuse:
        :param filter_type: "laplacian", "random_walk", "dual_random_walk".
        :param use_gc_for_ru: whether to use Graph convolution to calculate the reset and update gates.
        """
        super(DCGRUCell, self).__init__(_reuse=reuse)
        self._activation = activation
        self._num_nodes = num_nodes
        #self._num_edges = np.sum(adj_mx!=0)
        self.mask_mx = adj_mx != 0
        self._num_proj = num_proj
        self._num_units = num_units
        self._max_diffusion_step = max_diffusion_step
        self._supports = []
        self._use_gc_for_ru = use_gc_for_ru
        self.squeeze_and_excitation = squeeze_and_excitation
        self.se_activate = se_activate
        self.excitation_rate = excitation_rate
        self.r = r
        self.cell_forward_mode = cell_forward_mode
        self.diffusion_channel_num = args.diffusion_channel_num
        self.diffusion_with_graph_kernel = diffusion_with_graph_kernel
        self.graph_kernel_mode = graph_kernel_mode
        supports = []
        print('adj_mx: ', adj_mx.shape)
        if filter_type == "laplacian":
            supports.append(
                utils.calculate_scaled_laplacian(adj_mx, lambda_max=None))
        elif filter_type == "random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
        elif filter_type == "dual_random_walk":
            supports.append(utils.calculate_random_walk_matrix(adj_mx).T)
            supports.append(utils.calculate_random_walk_matrix(adj_mx.T).T)
        else:
            supports.append(utils.calculate_scaled_laplacian(adj_mx))
        for support in supports:
            self._supports.append(self._build_sparse_matrix(support))
        self._kernel_inds = self.kernel_ind(supports)
        self.mask_mx_ind = self.mask_ind(supports)