class_docstr: DeepWalk module from `DeepWalk: Online Learning of Social Representations
  <https://arxiv.org/abs/1403.6652>`__
  
  For a graph, it learns the node representations from scratch by maximizing the similarity of
  node pairs that are nearby (positive node pairs) and minimizing the similarity of other
  random node pairs (negative node pairs).
  
  Parameters
  ----------
  g : DGLGraph
      Graph for learning node embeddings
  emb_dim : int, optional
      Size of each embedding vector. Default: 128
  walk_length : int, optional
      Number of nodes in a random walk sequence. Default: 40
  window_size : int, optional
      In a random walk :attr:`w`, a node :attr:`w[j]` is considered close to a node
      :attr:`w[i]` if :attr:`i - window_size <= j <= i + window_size`. Default: 5
  neg_weight : float, optional
      Weight of the loss term for negative samples in the total loss. Default: 1.0
  negative_size : int, optional
      Number of negative samples to use for each positive sample. Default: 5
  fast_neg : bool, optional
      If True, it samples negative node pairs within a batch of random walks. Default: True
  sparse : bool, optional
      If True, gradients with respect to the learnable weights will be sparse.
      Default: True
  
  Attributes
  ----------
  node_embed : nn.Embedding
      Embedding table of the nodes
  
  Examples
  --------
  
  >>> import torch
  >>> from dgl.data import CoraGraphDataset
  >>> from dgl.nn import DeepWalk
  >>> from torch.optim import SparseAdam
  >>> from torch.utils.data import DataLoader
  >>> from sklearn.linear_model import LogisticRegression
  
  >>> dataset = CoraGraphDataset()
  >>> g = dataset[0]
  >>> model = DeepWalk(g)
  >>> dataloader = DataLoader(torch.arange(g.num_nodes()), batch_size=128,
  ...                         shuffle=True, collate_fn=model.sample)
  >>> optimizer = SparseAdam(model.parameters(), lr=0.01)
  >>> num_epochs = 5
  
  >>> for epoch in range(num_epochs):
  ...     for batch_walk in dataloader:
  ...         loss = model(batch_walk)
  ...         optimizer.zero_grad()
  ...         loss.backward()
  ...         optimizer.step()
  
  >>> train_mask = g.ndata['train_mask']
  >>> test_mask = g.ndata['test_mask']
  >>> X = model.node_embed.weight.detach()
  >>> y = g.ndata['label']
  >>> clf = LogisticRegression().fit(X[train_mask].numpy(), y[train_mask].numpy())
  >>> clf.score(X[test_mask].numpy(), y[test_mask].numpy())
class_docstr_tok: ["DeepWalk","module","from","`","DeepWalk",":","Online","Learning","of","Social","Representations","<","https",":","\/\/arxiv.org\/abs\/1403.6652",">","`","__","For","a","graph",",","it","learns","the","node","representations","from","scratch","by","maximizing","the","similarity","of","node","pairs","that","are","nearby","(","positive","node","pairs",")","and","minimizing","the","similarity","of","other","random","node","pairs","(","negative","node","pairs",")",".","Parameters","--","--","--","--","--","g",":","DGLGraph","Graph","for","learning","node","embeddings","emb_dim",":","int",",","optional","Size","of","each","embedding","vector",".","Default",":","128","walk_length",":","int",",","optional","Number","of","nodes","in","a","random","walk","sequence",".","Default",":","40","window_size",":","int",",","optional","In","a","random","walk",":","attr",":","`","w","`",",","a","node",":","attr",":","`","w","[","j","]","`","is","considered","close","to","a","node",":","attr",":","`","w","[","i","]","`","if",":","attr",":","`","i","-","window_size","<","=","j","<","=","i","+","window_size","`",".","Default",":","5","neg_weight",":","float",",","optional","Weight","of","the","loss","term","for","negative","samples","in","the","total","loss",".","Default",":","1.0","negative_size",":","int",",","optional","Number","of","negative","samples","to","use","for","each","positive","sample",".","Default",":","5","fast_neg",":","bool",",","optional","If","True",",","it","samples","negative","node","pairs","within","a","batch","of","random","walks",".","Default",":","True","sparse",":","bool",",","optional","If","True",",","gradients","with","respect","to","the","learnable","weights","will","be","sparse",".","Default",":","True","Attributes","--","--","--","--","--","node_embed",":","nn.Embedding","Embedding","table","of","the","nodes","Examples","--","--","--","--",">",">",">","import","torch",">",">",">","from","dgl.data","import","CoraGraphDataset",">",">",">","from","dgl.nn","import","DeepWalk",">",">",">","from","torch.optim","import","SparseAdam",">",">",">","from","torch.utils.data","import","DataLoader",">",">",">","from","sklearn.linear_model","import","LogisticRegression",">",">",">","dataset","=","CoraGraphDataset","(",")",">",">",">","g","=","dataset","[","0","]",">",">",">","model","=","DeepWalk","(","g",")",">",">",">","dataloader","=","DataLoader","(","torch.arange","(","g.num_nodes","(",")",")",",","batch_size=128",",","...","shuffle=True",",","collate_fn=model.sample",")",">",">",">","optimizer","=","SparseAdam","(","model.parameters","(",")",",","lr=0.01",")",">",">",">","num_epochs","=","5",">",">",">","for","epoch","in","range","(","num_epochs",")",":","...","for","batch_walk","in","dataloader",":","...","loss","=","model","(","batch_walk",")","...","optimizer.zero_grad","(",")","...","loss.backward","(",")","...","optimizer.step","(",")",">",">",">","train_mask","=","g.ndata","[","'train_mask","'","]",">",">",">","test_mask","=","g.ndata","[","'test_mask","'","]",">",">",">","X","=","model.node_embed.weight.detach","(",")",">",">",">","y","=","g.ndata","[","'label","'","]",">",">",">","clf","=","LogisticRegression","(",")",".fit","(","X","[","train_mask","]",".numpy","(",")",",","y","[","train_mask","]",".numpy","(",")",")",">",">",">","clf.score","(","X","[","test_mask","]",".numpy","(",")",",","y","[","test_mask","]",".numpy","(",")",")"]
docstr: Compute the loss for the batch of random walks
  
  Parameters
  ----------
  batch_walk : torch.Tensor
      Random walks in the form of node ID sequences. The Tensor
      is of shape :attr:`(batch_size, walk_length)`.
  
  Returns
  -------
  torch.Tensor
      Loss value
docstr_tok: ["Compute","the","loss","for","the","batch","of","random","walks","Parameters","--","--","--","--","--","batch_walk",":","torch.Tensor","Random","walks","in","the","form","of","node","ID","sequences",".","The","Tensor","is","of","shape",":","attr",":","`","(","batch_size",",","walk_length",")","`",".","Returns","--","--","--","-","torch.Tensor","Loss","value"]
code: def forward(self, batch_walk):
      """Compute the loss for the batch of random walks
  
      Parameters
      ----------
      batch_walk : torch.Tensor
          Random walks in the form of node ID sequences. The Tensor
          is of shape :attr:`(batch_size, walk_length)`.
  
      Returns
      -------
      torch.Tensor
          Loss value
      """
      batch_size = len(batch_walk)
      device = batch_walk.device
  
      batch_node_embed = self.node_embed(batch_walk).view(
          -1, self.emb_dim
      )
      batch_context_embed = self.context_embed(batch_walk).view(
          -1, self.emb_dim
      )
  
      batch_idx_list_offset = (
          torch.arange(batch_size) * self.walk_length
      )
      batch_idx_list_offset = batch_idx_list_offset.unsqueeze(1)
      idx_list_src = (
          batch_idx_list_offset + self.idx_list_src.unsqueeze(0)
      )
      idx_list_dst = (
          batch_idx_list_offset + self.idx_list_dst.unsqueeze(0)
      )
      idx_list_src = idx_list_src.view(-1).to(device)
      idx_list_dst = idx_list_dst.view(-1).to(device)
  
      pos_src_emb = batch_node_embed[idx_list_src]
      pos_dst_emb = batch_context_embed[idx_list_dst]
  
      neg_idx_list_src = idx_list_dst.unsqueeze(1) + torch.zeros(
          self.negative_size
      ).unsqueeze(0).to(device)
      neg_idx_list_src = neg_idx_list_src.view(-1)
      neg_src_emb = batch_node_embed[neg_idx_list_src.long()]
  
      if self.fast_neg:
          neg_idx_list_dst = list(
              range(batch_size * self.walk_length)
          ) * (self.negative_size * self.window_size * 2)
          random.shuffle(neg_idx_list_dst)
          neg_idx_list_dst = neg_idx_list_dst[: len(neg_idx_list_src)]
          neg_idx_list_dst = torch.LongTensor(neg_idx_list_dst).to(
              device
          )
          neg_dst_emb = batch_context_embed[neg_idx_list_dst]
      else:
          neg_dst = choice(
              self.g.num_nodes(),
              size=len(neg_src_emb),
              prob=self.neg_prob,
          )
          neg_dst_emb = self.context_embed(neg_dst.to(device))
  
      pos_score = torch.sum(torch.mul(pos_src_emb, pos_dst_emb), dim=1)
      pos_score = torch.clamp(pos_score, max=6, min=-6)
      pos_score = torch.mean(-F.logsigmoid(pos_score))
  
      neg_score = torch.sum(torch.mul(neg_src_emb, neg_dst_emb), dim=1)
      neg_score = torch.clamp(neg_score, max=6, min=-6)
      neg_score = (
          torch.mean(-F.logsigmoid(-neg_score))
          * self.negative_size
          * self.neg_weight
      )
  
      return torch.mean(pos_score + neg_score)
  
imports: import random
  import torch
  import torch.nn.functional
  import tqdm
  from torch import nn
  from torch.nn import init
  from ...base import NID
  from ...convert import to_heterogeneous, to_homogeneous
  from ...random import choice
  from ...sampling import random_walk
label_desc: Use image node_id 4 for calling the DeepWalk obj's underlying member method code with example usage: obj.forward(batch_walk) and returns: torch