《GATED GRAPH SEQUENCE NEURAL NETWORKS》结合代码的论文阅读笔记

通过这篇文章,学习GNN实现细节,确定用在手部图像上的可行性,初步确定实现方案。

文章及代码链接:https://github.com/Microsoft/gated-graph-neural-network-samples

论文初步阅读

1:GG-NNs计算过程

2:GGS-NNs计算流程

结合代码深入理解

1:加载数据

2:创建计算图

2.1:prepare_specific_graph_model

2.2:final_node_representations

        2.2.1:获取图

        2.2.2:对于每个时间步长,更新cur_node_states

2.3:计算loss:

       2.3.1:对每个task,计算gated_regression

       2.3.2:把每个图中所有的点求个和得到一个图的输出结果——computed_values(float)

       2.3.3:Mask out unused values

论文初步阅读

这是Microsoft Research2016年发表于ICLR的文章,作者是Yujia Li

图的特征学习包括两个步骤:输入图的表达和中间环节的特征聚合。在图的表达上,本文沿用2009年的 Scarselli的工作,我们在它上面融入了RNN的思想。 后续特征聚合十分重要我们引入了GGS-NNs。

1:GG-NNs计算过程

可以用6个公式表达

  1. initialization

  2. imformation pass

  3. update gate

  4. reset gate

  5. activate

  6. activate

  7. output

2:GGS-NNs计算流程

用了两个 GG-NNs: Fo(k) 和 FX(k)。 Fo(k) for predicting o(k) from X(k), and FX(k) forpredicting X(k+1) from X(k). when training GGS-NN,there are two setting:specifying all intermediate annotations or only the first one.

结合代码深入理解

1:加载数据

训练数据12083张图,测试数据13082张图。图是稀疏图用邻接矩阵表达,节点数量不大于30,边有权重大概40到50条边,每个节点有5种取值(onehot编码),整个图有一个label(大概是-4到4之间的一个浮点数)。

2:创建计算图

所有操作记录在self.ops['final_node_representations']中

网络输入有4个,暂时不知道怎么用

创建计算图的核心代码:

with tf.variable_scope("graph_model"):
     self.prepare_specific_graph_model()
     # This does the actual graph work:
     if self.params['use_graph']:
          self.ops['final_node_representations'] = self.compute_final_node_representations()
     else:
          self.ops['final_node_representations'] = tf.zeros_like(self.placeholders['initial_node_representation'])

2.1:prepare_specific_graph_model

首先增加了5个网络输入,按照字面意义理解:点的初始化参数,邻接矩阵,邻接矩阵权重,点集合,图状态保持概率

增加网络权重,每个时间步骤一个,总共4个时间步所以是4个,每个与邻接矩阵大小相同

2.2:final_node_representations

计算每个点的结果,应该跟上面的6个公式相关。

2.2.1:获取图

根据placeholders中的initial_node_representation的值初始化cur_node_states,根据placeholders中的adjacency_list和adjacency_weights中的值初始化一个adjacency_matrix。

tf.shape(x),其中x可以是tensor,也可不是tensor,返回是一个tensor.

shape=tf.placeholder(tf.float32, shape=[None, 227,227,3] )
  • 我们经常会这样来feed数据,如果在运行的时候想知道None到底是多少,这时候,只能通过tf.shape(x)[0]这种方式来获得

2.2.2:对于每个时间步长,更新cur_node_states

adjacency_matrix(node_num,node_num)  *  cur_node_states(node_num,100)* 位于该时间步的权重(100*100) 

得到 new_node_states (node_num*100)

有需要的话可以加个bias。

2.3:计算loss:

2.3.1:对每个task,计算gated_regression

增加两个权重矩阵,组成MLP多层感知机,其实就是全连接和relu。

regression_gate_task0(输入200,输出1)和regression_transform_task0(输入100,输出1)

cur_node_states与初始化node连起来组成gate_input(node_num*200)。计算流程如下:

  1. gate_input输入regression_gate_task0这个MLP
  2. 输入Sigmoid函数,变换到0~1
  3. 输入到regression_transform_task0这个MLP
  4. 得到的结果gated_outputs(node_num*1)

2.3.2:把每个图中所有的点求个和得到一个图的输出结果——computed_values(float)

2.3.3:Mask out unused values

diff = computed_values - self.placeholders['target_values'][internal_id,:]
task_target_mask = self.placeholders['target_mask'][internal_id,:]
task_target_num = tf.reduce_sum(task_target_mask) + SMALL_NUMBER
diff = diff * task_target_mask  # Mask out unused values
self.ops['accuracy_task%i' % task_id] = tf.reduce_sum(tf.abs(diff)) / task_target_num
task_loss = tf.reduce_sum(0.5 * tf.square(diff)) / task_target_num
# Normalise loss to account for fewer task-specific examples in batch:
task_loss = task_loss * (1.0 / (self.params['task_sample_ratios'].get(task_id) or 1.0))
self.ops['losses'].append(task_loss)

 

 

 

猜你喜欢

转载自blog.csdn.net/duyue3052/article/details/82625431