原创文章~转载请注明出处哦。其他部分内容参见以下链接~

GraphSAGE 代码解析(一) - unsupervised_train.py

GraphSAGE 代码解析(二) - layers.py

GraphSAGE 代码解析(四) - models.py

1. class MeanAggregator(Layer):

该类主要用于实现

1. __init__()

__init_() 用于获取并初始化成员变量 dropout, bias(False), act(ReLu), concat(False), input_dim, output_dim, name(Variable scopr)

用glorot()方法初始化节点v的权值矩阵 vars['self_weights'] 和邻居节点均值u的权值矩阵 vars['neigh_weights']

用零向量初始化vars['bias']。(见inits.py: zeros(shape))

若logging为True,则调用 layers.py 中 class Layer()的成员函数_log_vars(), 生成vars中各个变量的直方图。

glorot()

其中,glorot() 在inits.py中定义,用于权值初始化。(from .inits import glorot)

均匀分布初始化方法,又称Xavier均匀初始化,参数从 [-limit, limit] 的均匀分布产生,其中limit为 sqrt(6 / (fan_in + fan_out))。fan_in为权值张量的输入单元数,fan_out是权重张量的输出单元数。该函数返回 [fan_in, fan_out]大小的Variable。

 def glorot(shape, name=None):
"""Glorot & Bengio (AISTATS 2010) init."""
init_range = np.sqrt(6.0/(shape[0]+shape[1]))
initial = tf.random_uniform(shape, minval=-init_range, maxval=init_range, dtype=tf.float32)
return tf.Variable(initial, name=name)

2. _call(inputs)

class MeanAggregator(Layer) 中的 _call(inputs) 函数是对父类class Layer(object)方法_call(inputs)的重写。

用于实现最上方的迭代更新式子。

在layer.py 中定义的 class Layer(object)中,执行特殊函数def __call__(inputs) 时有: outputs = self._call(inputs)调用_call(inputs) 方法,也即在这里调用子类MeanAggregator(Layer)中的_call(inputs)方法。

tf.nn.dropout(x, keep_prob, noise_shape=None, seed=None, name=None)

With probability keep_prob, outputs the input element scaled up by 1 / keep_prob, otherwise outputs 0. The scaling is so that the expected sum is unchanged.

注意:输出的非0元素是原来的 “1/keep_prob” 倍,以保证总和不变。

tf.add_n(inputs, name=None)

Adds all input tensors element-wise.

Args:
inputs: A list of Tensor or IndexedSlices objects, each with same shape and type.
name: A name for the operation (optional).
Returns:
A Tensor of same shape and type as the elements of inputs. Raises:
ValueError: If inputs don't all have same shape and dtype or the shape cannot be inferred.

output = tf.concat([from_self, from_neighs], axis=1)

这里注意在concat后其维数变为之前的2倍。

3. class MeanAggregator(Layer) 代码

 class MeanAggregator(Layer):
"""
Aggregates via mean followed by matmul and non-linearity.
""" def __init__(self, input_dim, output_dim, neigh_input_dim=None,
dropout=0., bias=False, act=tf.nn.relu,
name=None, concat=False, **kwargs):
super(MeanAggregator, self).__init__(**kwargs) self.dropout = dropout
self.bias = bias
self.act = act
self.concat = concat if neigh_input_dim is None:
neigh_input_dim = input_dim if name is not None:
name = '/' + name
else:
name = '' with tf.variable_scope(self.name + name + '_vars'):
self.vars['neigh_weights'] = glorot([neigh_input_dim, output_dim],
name='neigh_weights')
self.vars['self_weights'] = glorot([input_dim, output_dim],
name='self_weights')
if self.bias:
self.vars['bias'] = zeros([self.output_dim], name='bias') if self.logging:
self._log_vars() self.input_dim = input_dim
self.output_dim = output_dim def _call(self, inputs):
self_vecs, neigh_vecs = inputs neigh_vecs = tf.nn.dropout(neigh_vecs, 1-self.dropout)
self_vecs = tf.nn.dropout(self_vecs, 1-self.dropout)
neigh_means = tf.reduce_mean(neigh_vecs, axis=1) # [nodes] x [out_dim]
from_neighs = tf.matmul(neigh_means, self.vars['neigh_weights']) from_self = tf.matmul(self_vecs, self.vars["self_weights"]) if not self.concat:
output = tf.add_n([from_self, from_neighs])
else:
output = tf.concat([from_self, from_neighs], axis=1) # bias
if self.bias:
output += self.vars['bias'] return self.act(output)

2. class GCNAggregator(Layer)

这里__init__()与MeanAggregator基本相同,在_call()的实现中略有不同。

 def _call(self, inputs):
self_vecs, neigh_vecs = inputs neigh_vecs = tf.nn.dropout(neigh_vecs, 1-self.dropout)
self_vecs = tf.nn.dropout(self_vecs, 1-self.dropout)
means = tf.reduce_mean(tf.concat([neigh_vecs,
tf.expand_dims(self_vecs, axis=1)], axis=1), axis=1) # [nodes] x [out_dim]
output = tf.matmul(means, self.vars['weights']) # bias
if self.bias:
output += self.vars['bias'] return self.act(output)

其中对means求解时,

1. 先将self_vecs行列转换(tf.expand_dims(self_vecs, axis=1)),

2. 之后self_vecs的行数与neigh_vecs行数相同时,将二者concat, 即相当于在原先的neigh_vecs矩阵后面新增一列self_vecs的转置

3. 最后将得到的矩阵每行求均值,即得means.

之后means与权值矩阵vars['weights']求内积,并加上vars['bias'], 最终将该值带入激活函数(ReLu)。

下面举个例子简单说明(例子中省略了点乘W的操作):

 import tensorflow as tf

 neigh_vecs = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
self_vecs = [2, 3, 4] means = tf.reduce_mean(tf.concat([neigh_vecs,
tf.expand_dims(self_vecs, axis=1)], axis=1), axis=1) print(tf.shape(self_vecs)) print(tf.expand_dims(self_vecs, axis=0))
# Tensor("ExpandDims_1:0", shape=(1, 3), dtype=int32) print(tf.expand_dims(self_vecs, axis=1))
# Tensor("ExpandDims_2:0", shape=(3, 1), dtype=int32) sess = tf.Session()
print(sess.run(tf.expand_dims(self_vecs, axis=1)))
# [[2]
# [3]
# [4]] print(sess.run(tf.concat([neigh_vecs,
tf.expand_dims(self_vecs, axis=1)], axis=1)))
# [[1 2 3 2]
# [4 5 6 3]
# [7 8 9 4]] print(means)
# Tensor("Mean:0", shape=(3,), dtype=int32) print(sess.run(tf.reduce_mean(tf.concat([neigh_vecs,
tf.expand_dims(self_vecs, axis=1)], axis=1), axis=1)))
# [2 4 7] # [[1 2 3 2] = 8 // 4 = 2
# [4 5 6 3] = 18 // 4 = 4
# [7 8 9 4]] = 28 // 4 = 7 bias = [1]
output = means + bias
print(sess.run(output))
# [3 5 8]
# [2 + 1, 4 + 1, 7 + 1] = [3, 5, 8]

GraphSAGE 代码解析(三) - aggregators.py的更多相关文章

  1. GraphSAGE 代码解析(四) - models.py

    原创文章-转载请注明出处哦.其他部分内容参见以下链接- GraphSAGE 代码解析(一) - unsupervised_train.py GraphSAGE 代码解析(二) - layers.py ...

  2. GraphSAGE 代码解析(二) - layers.py

    原创文章-转载请注明出处哦.其他部分内容参见以下链接- GraphSAGE 代码解析(一) - unsupervised_train.py GraphSAGE 代码解析(三) - aggregator ...

  3. GraphSAGE 代码解析(一) - unsupervised_train.py

    原创文章-转载请注明出处哦.其他部分内容参见以下链接- GraphSAGE 代码解析(二) - layers.py GraphSAGE 代码解析(三) - aggregators.py GraphSA ...

  4. GraphSAGE 代码解析 - minibatch.py

    class EdgeMinibatchIterator """ This minibatch iterator iterates over batches of samp ...

  5. RobHess的SIFT代码解析步骤三

    平台:win10 x64 +VS 2015专业版 +opencv-2.4.11 + gtk_-bundle_2.24.10_win32 主要参考:1.代码:RobHess的SIFT源码 2.书:王永明 ...

  6. Celery 源码解析三: Task 对象的实现

    Task 的实现在 Celery 中你会发现有两处,一处位于 celery/app/task.py,这是第一个:第二个位于 celery/task/base.py 中,这是第二个.他们之间是有关系的, ...

  7. 用 TensorFlow 实现 k-means 聚类代码解析

    k-means 是聚类中比较简单的一种.用这个例子说一下感受一下 TensorFlow 的强大功能和语法. 一. TensorFlow 的安装 按照官网上的步骤一步一步来即可,我使用的是 virtua ...

  8. OpenStack之虚机热迁移代码解析

    OpenStack之虚机热迁移代码解析 话说虚机迁移分为冷迁移以及热迁移,所谓热迁移用度娘的话说即是:热迁移(Live Migration,又叫动态迁移.实时迁移),即虚机保存/恢复(Save/Res ...

  9. [nRF51822] 12、基础实验代码解析大全 · 实验19 - PWM

    一.PWM概述: PWM(Pulse Width Modulation):脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形. PWM 的几个基本概念: 1) 占空比:占空比是指 ...

随机推荐

  1. [LuoguP1111]修复公路

    [LuoguP1111]修复公路 题目描述: A地区在地震过后,链接所有村庄的公路都损坏了,而导致无法通车,政府派人修复这些公路. 给出A地区的N村庄数和M公路数,并且对于每一个公路给出其链接的两个村 ...

  2. 【题解】洛谷P3399 丝绸之路

    我丑,话说在前头 题目: https://www.luogu.org/problemnew/show/P3399 一道挺简单的DP 思路不难想 但是蒟蒻总是写错初始化啥的 思路 定义f[i][j]为第 ...

  3. CONVERT函数----SQL

    CONVERT函数是把时间转换成新类型的通用格式,这样方便查询 CONVERT(type,expression,style) type: 例如:varchar(10)  数据库字符串的类型,大小可以自 ...

  4. windows下搭建python

    windows下搭建python 下载python版本  https://www.python.org/   注意当前操作系统的位数,32位还是64位 同时   安装后  修改环境变量         ...

  5. vue 修改框架less变量

    以vant框架为例,vue项目以less作为css处理器: less/var-reset.less @import '~vant/lib/index.less'; // Color variables ...

  6. 第一次写C语言小程序,可以初步理解学生成绩管理系统的概念

    1 成绩管理系统概述 1.1  管理信息系统的概念  管理信息系统(Management Information Systems,简称MIS),是一个不断发展的新型学科,MIS的定义随着科技的进步也在 ...

  7. 菜鸟笔记 -- Chapter 6.2.3 成员变量

    6.2.3  成员变量 在Java中对象的属性也称为成员变量[也叫字段].成员变量的类型可以设置为Java中合法的数据类型,其实成员变量就是普通的变量,可以为它设置初始值,也可以不设置初始值,如果不设 ...

  8. 不再手写import - VSCode自动引入Vue组件和Js模块

    :first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdow ...

  9. LeetCode 简单 - 路径总和(112)

    给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和. 说明: 叶子节点是指没有子节点的节点. 示例: 给定如下二叉树,以及目标和 sum = 22 ...

  10. 【前行】◇第3站◇ 国庆训练营·OI制模拟赛

    [第3站] 国庆训练营·OI制模拟赛Ⅰ 怀着冲刺提高组400的愿望来到这个very small but very interesting 的训练营QwQ 在北大dalao的带领下开始了第一场OI模拟赛 ...