Skip to content

开发者流程

han hui edited this page May 10, 2022 · 17 revisions

访问github建议使用VPN,或者国内镜像。

需要掌握的技能

  • Python编程

  • Conda的简单实用

    • 要求必须使用conda来管理Python(除非你知道自己在做什么,可以不使用conda) 。
    • 遇到装包问题,可以切换channel,具体百度。(例如清华源condapip
  • 深度学习框架的使用

  • 参考资料: 书籍:《机器学习》-周志华,《统计学习方法》-李航,《动手学深度学习》-李沐

    视频资料:李沐, 李宏毅

    必看视频:强推、零基础多图详解图神经网络-李沐

环境安装

  1. 下载安装Python 与 anaconda:https://www.anaconda.com/products/individual 具体百度
  2. 安装环境
  • GammaGL开发者:TensorFlow和TensorLayerX:
   conda create -n ggl python=3.9
   conda activate ggl
   pip install tensorflow
   pip install git+https://github.com/tensorlayer/tensorlayerx.git
   # Note: You may need to install `cv2` with command  `pip install opencv-python`

利用gitee解决安装tlx的网络问题,pip install git+https://gitee.com/clearhanhui/TensorLayerX, 但可能不是最新的。

  1. 开发软件建议pycharm,专业版学生可以免费申请。
  2. 测试环境
  • GammaGL:测试GCN 实例.

项目要求

GammaGL:

  • 阅读论文原文,跑源代码查看论文性能。
  • 基于TensorLayerX,复现图神经网络模型。
  • 要求
    • 达成论文中report的性能,或复现源代码的性能;
    • 代码要求有注释以及docstring;
    • 提供详尽的实现说明(README)。
  • 除作者源码以外,可以参考DGL、PyG的实现,对照性能。
    • GammaGL官方复现GCN参考:

实现参考

项目开发

GammaGL

通常复现模型的核心代码

以GCN的实现为例子:

  • 数据集的实现:
    • 将论文主实验或者作者公布源代码中使用的数据集集成到项目中,参考plaintoid数据集。
  • 卷积层 gammagl/layers/conv 的实现
    • 可以参考下面具体开发流程,具体实现参照GCNConv,通常是基于MessgaePassing类的卷积层.
  • 模型的实现
    • 同上
  • 训练流程
    • 同上
    • 以上四条据需要使用tlx的api,如遇到特殊操作,在群里提出来
  • 超参数调优
    • 达到论文中实验公布或者源码的性能之一
  • 不同框架的测试
    • 优先基于tensorflow后端开发,记录在torch、paddle、mindspore等后端遇到的bug并反馈
  • 文档撰写
    • 使用rst格式注释数据集类、卷积类、模型类等对象,包括论文、参数、样例等信息;
    • readme文档,包含论文、实验结果、实验参数、运行命令等。

gammagl 目录包含模型组件,examples 中包含某个模型的训练流程。需要在gammagl/layers/conv中实现模型单层如 gcn_conv.pygammagl/model/中实现整个模型如gcn.py,在example/中编写训练流程如gcn_trainer.py

MessagePassing类: 所有的卷积类需要继承该类,描述了基本的消息传递过程。类函数包括message、aggregate、update、propagate。 message: 消息发送函数,执行根据edge_index和edge_weight将x中的消息发送到边上的操作。通常需要在继承类中重写,以实现不同的实例,具体实例参考gat_conv.py:

def message(self, x, edge_index, edge_weight=None, num_nodes=None):
    node_src = edge_index[0, :]
    node_dst = edge_index[1, :]
    weight_src = tlx.ops.gather(tlx.ops.reduce_sum(x * self.att_src, -1), node_src)
    weight_dst = tlx.ops.gather(tlx.ops.reduce_sum(x * self.att_dst, -1), node_dst)
    weight = self.leaky_relu(weight_src + weight_dst)
    
    alpha = segment_softmax(weight, node_dst, num_nodes)
    alpha = self.dropout(alpha)
    msg = tlx.ops.gather(x, node_src) * tlx.ops.expand_dims(alpha, -1)
    return msg * edge_weight if edge_weight else msg

aggregate: 消息传播函数,执行根据edge_index将msg中包含的消息聚合到目标节点上的操作。可以需根据需要设置aggr_type [sum(default), mean, max, min],也可以根据需要重写。

update: 消息更新函数,该函数通常在需要残差链接等特殊更新方式时候使用,也可以不使用该函数直接在forward过程中实现。

propagate: 描述的消息传播过程,上述函数会被依次执行。 注意:消息传播过程在概念上来讲不包含神经网络中的参数,有关线性变换的部分计算一般在forward中执行

卷积类: 卷积类实现单层卷积操作,基本结构如下:

class ConvName(MessagePassing): # 继承MessagePassing类
    """
    类注释,rst格式。
    描述卷积功能、计算实例、参数
    """
    def __init__(self, arg1, arg2 ...): # 定义参数
        super().__init__()
        ... # 定义卷积需要的组件如 linear, relu
        
    def forward(self, x, edge_index):
        ... 
        self.propagate() # 前向传播过程
        ...
        return 

Note: 在tensorlayerx中,可学习参数的定义需要用如下方式:

initor = tlx.initializers.truncated_normal()
self.bias = self._get_weights(var_name="bias", 
                              shape=(1,self.out_channels), 
                              init=initor)

模型类: 模型类实现模型的一次完整的前向传播过程,基本结构如下: 参考源代码的实现或DGL、PyG的实现。设计不同layer的堆叠会影响性能

class ModelName(tlx.nn.Module): # 需要继承Module
    """
    类注释,rst格式。
    标明论文、公式、参数
    """
    def __init__(self, arg1, arg2 ...): # 定义参数,可以不用config类
        super().__init__()
        self.conv = Conv() # 定义卷积层
        self.act = ReLU() # 定义激活层
        ... 
        
    def forward(self, x, edge_index):
        x = self.act(self.conv()) # 完成单层卷积
        ...
        return 

Note1:多层卷积可以使用 tlx.layers.SequentialLayer() Note2:上述类需要在各自的包中__init__.py 文件中导入

训练流程: 训练流程的代码结构如下: (示例为基本流程,与具体实现规范有差异)

import os
import tensorlayerx as tlx
...

# parameter configuration
lr = arg.parser()
...

# load dataset 
dataset = Planetoid('./', 'Cora')
graph = dataset[0]
...

# neural network components
loss = tlx.losses.softmax_cross_entropy_with_logits
optimizer = tlx.optimizers.Adam(lr)
net = ModelName()
...

# training
for e in range(n_epoch):
    net.set_train()
    train_loss = train_one_step()
    ...
    
# inference
net.load_weghts(best_model)
logits = net(x, edge_index)
acc = calc_acc(logitx, label)

Note:上述代码根据需要修改,更多细节可以参照已有源码

注意事项

指定不同后端\GPU的方法:

  1. 可以设置环境变量,如下命令:
CUDA_VISIBLE_DEVICES="1" TL_BACKEND="paddle" python gcn_trainer.py
  1. 也可以通过python自带的os.environ接口,如下:
import os
os.environ['TL_BACKEND'] = "torch" # 可选 tensorflow(默认)、 torch、padlle、mindspore
os.environ['CUDA_VISIBLE_DEVICES']="1"
# 注意1:必须在import tensorlayerx之前设置环境变量
# 注意2:torch不是pytorch

在GammaGL.dataset新建数据集时,需要注意processed_file_names函数,添加后端特定的名称。

如Plantoid中
    @property
    def processed_file_names(self) -> str:
        return tlx.BACKEND+'_data.pt'

提交模型

  1. 提交模型之前通过命令更新tensorlayerx和gammagl的代码,测试通过之后提交pr
  2. 建议使用可视化软件使用git,如sourcetree,github desktop,vscode插件等,有关git的原理和操作参考官方文档
  3. fork 本项目到自己的账号下面
  4. 克隆你账号下面的项目,git clone url-to-your-github/GammaGL.git
  5. 在本地新建分支 如gcnappnp
  6. 编写代码,并向新建分支提交commit
  7. 把更改的代码push到自己仓库
  8. 在github上提交pr到上游仓库
    注意:在step 5不要将代码提交到main分支