cs224w_colab2.py这个图属性预测到底咋预测的
- dataset.meta_info.T
- Out[2]:
- num tasks 1
- eval metric rocauc
- download_name hiv
- version 1
- url http://snap.stanford.edu/ogb/data/graphproppre...
- add_inverse_edge True
- data type mol
- has_node_attr True
- has_edge_attr True
- task type binary classification
- num classes 2
- split scaffold
- additional node files None
- additional edge files None
- binary False
- Name: ogbg-molhiv, dtype: object

参照上面 这里的num tasks 仅适用于图属性预测? num tasks = 1
- model = GCN_Graph(args['hidden_dim'],
- dataset.num_tasks, args['num_layers'],
- args['dropout']).to(device)
-
-
- train_loader.dataset.data.edge_index.shape
- Out[10]: torch.Size([2, 2259376])
-
- train_loader.dataset.data.edge_attr.shape
- Out[12]: torch.Size([2259376, 3])
-
-
-
- type(train_loader.dataset.data.node_stores)
- Out[26]: list
-
-
-
- train_loader.dataset.data.node_stores[0]['y'].shape
- Out[46]: torch.Size([41127, 1])
- train_loader.dataset.data.node_stores[0]['y'].sum()
- Out[47]: tensor(1443) y 中的数值求和值
-
- torch.unique(train_loader.dataset.data.node_stores[0]['y'],return_counts=True)
- Out[58]: (tensor([0, 1]), tensor([39684, 1443])) 仅0,1两类
-
-
- self.node_encoder.atom_embedding_list
- Out[62]:
- ModuleList(
- (0): Embedding(119, 256)
- (1): Embedding(5, 256)
- (2): Embedding(12, 256)
- (3): Embedding(12, 256)
- (4): Embedding(10, 256)
- (5): Embedding(6, 256)
- (6): Embedding(6, 256)
- (7): Embedding(2, 256)
- (8): Embedding(2, 256)
- )
-
-
-
- list(enumerate(data_loader))
- Out[82]:
- [(0,
- DataBatch(edge_index=[2, 1734], edge_attr=[1734, 3], x=[807, 9], y=[32, 1], num_nodes=807, batch=[807], ptr=[33])),
- 若干组 很多
- x, edge_index, batch = batched_data.x, batched_data.edge_index, batched_data.batch
- embed = self.node_encoder(x) #使用编码器 将原先9维的编码为256维 self.node_encoder = AtomEncoder(hidden_dim)
-
- out = self.gnn_node(embed, edge_index) #使用gcn得到节点嵌入 embed=X edge_index 连边/节点对
- out = self.pool(out, batch)
-
-
- batch.unique(return_counts = True)
- Out[94]:
- (tensor([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31],
- device='cuda:0'), 这里说明有31个待训练子图(化学分子) 下图api说明了聚合过程
- tensor([30, 18, 21, 26, 12, 20, 17, 18, 36, 11, 31, 22, 21, 26, 22, 21, 21, 63,
- 15, 18, 18, 29, 18, 40, 41, 19, 19, 30, 12, 21, 19, 23], 每个分子中所含有的节点(原子)数量
- device='cuda:0'))
- batch.shape
- Out[95]: torch.Size([758])

- def global_mean_pool(x: Tensor, batch: Optional[Tensor],
- size: Optional[int] = None) -> Tensor:
-
- dim = -1 if x.dim() == 1 else -2 #这里的x.dim() = 2
- # dim() → int Returns the number of dimensions of self tensor.
-
- if batch is None:
- return x.mean(dim=dim, keepdim=x.dim() <= 2) #keepdim=x.dim() <= 2 ??啥玩意<=
- size = int(batch.max().item() + 1) if size is None else size
- return scatter(x, batch, dim=dim, dim_size=size, reduce='mean')

This package consists of a small extension library of highly optimized sparse update (scatter and segment) operations for the use in PyTorch, which are missing in the main package. Scatter and segment operations can be roughly described as reduce operations based on a given "group-index" tensor. Segment operations require the "group-index" tensor to be sorted, whereas scatter operations are not subject to these requirements.该包由一个小型扩展库组成,该库包含用于PyTorch的高度优化的稀疏更新(分散和分段)操作,这些操作在主包中丢失。散射和分段运算可以粗略地描述为基于给定“群索引”张量的归约运算。分段运算需要对“组索引”张量进行排序,而分散运算则不受这些要求的约束。
由此(scatter)由多个节点的嵌入值最终得到这部分节点所在的子图嵌入(化学分子)。
- def forward(self, batched_data):
- # TODO: Implement a function that takes as input a
- # mini-batch of graphs (torch_geometric.data.Batch) and
- # returns the predicted graph property for each graph.
- #
- # NOTE: Since we are predicting graph level properties,
- # your output will be a tensor with dimension equaling
- # the number of graphs in the mini-batch
-
- x, edge_index, batch = batched_data.x, batched_data.edge_index, batched_data.batch
- embed = self.node_encoder(x) #使用编码器 将原先9维的编码为256维 self.node_encoder = AtomEncoder(hidden_dim)
-
- out = self.gnn_node(embed, edge_index) #使用gcn得到节点嵌入 embed=X edge_index 连边/节点对
- out = self.pool(out, batch)
- out = self.linear(out)
-
- ############# Your code here ############
- ## Note:
- ## 1. Construct node embeddings using existing GCN model
- ## 2. Use the global pooling layer to aggregate features for each individual graph
- ## For more information please refer to the documentation:
- ## https://pytorch-geometric.readthedocs.io/en/latest/modules/nn.html#global-pooling-layers
- ## 3. Use a linear layer to predict each graph's property
- ## (~3 lines of code)
-
- #########################################
-
- return out
-
- out.shape
- Out[122]: torch.Size([32, 1])
- out
- Out[121]:
- tensor([[-0.4690],
- [-1.0285],
- [-0.4614],
- 最后经过线性层 返回得到所属类别概率 运行到如下部分结束反向传播forward() (op = model(batch)# 先进入model函数 然后运行 反向传播)
-
-
-
- def train(model, device, data_loader, optimizer, loss_fn):
- # TODO: Implement a function that trains your model by
- # using the given optimizer and loss_fn.
- model.train() #Sets the module in training mode. data_loader.dataset.data Data(num_nodes=1049163, edge_index=[2, 2259376], edge_attr=[2259376, 3], x=[1049163, 9], y=[41127, 1])
- loss = 0
-
- for step, batch in enumerate(tqdm(data_loader, desc="Iteration")): #,total= data_loader.batch_sampler
- # for step, batch in tqdm(enumerate(data_loader), desc="Iteration"): #,total= data_loader.batch_sampler
- batch = batch.to(device)
-
- if batch.x.shape[0] == 1 or batch.batch[-1] == 0:
- pass
- else:
- ## ignore nan targets (unlabeled) when computing training loss.
- is_labeled = batch.y == batch.y # 0/1转化为Ture/False
-
- ############# Your code here ############
- ## Note:
- ## 1. Zero grad the optimizer
- ## 2. Feed the data into the model
- ## 3. Use `is_labeled` mask to filter output and labels
- ## 4. You may need to change the type of label to torch.float32
- ## 5. Feed the output and label to the loss_fn
- ## (~3 lines of code)
-
- optimizer.zero_grad()
- # print('optimizer.zero_grad()')
- op = model(batch)# 先进入model函数 然后运行 反向传播
-
-
-
- 。。。。。。。。。。。。。。。后面计算损失 更新梯度等等
存在错误等欢迎指正! 附件为整个作业的.py文件