说明
此版本代码为清华NLP团队的OpenNE里面的代码,代码网址为:https://github.com/thunlp/openne。 公正的说,代码还是比较规范,可读性较好,此处只对其Line代码进行简读,有空再写下其他代码,如有错误,请指正。
此处只读LINE核心代码的build_graph函数和train_one_epoch,因为他们一起训练了一阶和二阶损失函数。
build_graph
self.h = tf.placeholder(tf.int32, [None])
self.t = tf.placeholder(tf.int32, [None])
self.sign = tf.placeholder(tf.float32, [None])#预定义的占位符,h and t 用来后面进行相应顶点embedding的查找
cur_seed = random.getrandbits(32)#根据英文缩写,current seed,用作后面初始化embeddings and context_embeddings的seed
self.embeddings = tf.get_variable(name="embeddings"+str(self.order), shape=[self.node_size, self.rep_size], initializer = tf.contrib.layers.xavier_initializer(uniform = False, seed=cur_seed))
self.context_embeddings = tf.get_variable(name="context_embeddings"+str(self.order), shape=[self.node_size, self.rep_size], initializer = tf.contrib.layers.xavier_initializer(uniform = False, seed=cur_seed))
#上面两行是初始化矩阵embeddings,矩阵shape为node_size*rep_size,即顶点个数,以及每个顶点表示的维度,初始化方法为initializer
self.h_e = tf.nn.embedding_lookup(self.embeddings, self.h)#根据编号h得到h_e,即h顶点的embedding,大小为1*rep_size
self.t_e = tf.nn.embedding_lookup(self.embeddings, self.t)#同上
self.t_e_context = tf.nn.embedding_lookup(self.context_embeddings, self.t)#同上
self.second_loss = -tf.reduce_mean(tf.log_sigmoid(self.sign*tf.reduce_sum(tf.multiply(self.h_e, self.t_e_context), axis=1)))
#二阶损失的定义,可以看到二阶用的是环境embeddings,即每个顶点即有自身的embeddings,还有自身作为context的embedding
self.first_loss = -tf.reduce_mean(tf.log_sigmoid(self.sign*tf.reduce_sum(tf.multiply(self.h_e, self.t_e), axis=1)))
#一阶损失的定义,直接查找出两个顶点的embeddings,然后相乘以后作sigmoid,就是归一化,如果很类似就接近1,不类似就接近0
if self.order == 1:
self.loss = self.first_loss
else:
self.loss = self.second_loss
optimizer = tf.train.AdamOptimizer(0.001)#选择adam优化
self.train_op = optimizer.minimize(self.loss)
train_one_epoch
上面个函数是核心函数,都知道tensorflow是需要session才能执行,这个函数作的就是创建session并跑起来的工作。
sum_loss = 0.0
batches = self.batch_iter()#产生一个mini_batch,后面有函数
batch_id = 0
for batch in batches:#此处循环为取得h,t,sign based on mini_batch
h, t, sign = batch
feed_dict = {
self.h : h,
self.t : t,
self.sign : sign,
}
_, cur_loss = self.sess.run([self.train_op, self.loss],feed_dict)#创建session,跑起来
sum_loss += cur_loss#current loss,累积积
batch_id += 1
print('epoch:{} sum of loss:{!s}'.format(self.cur_epoch, sum_loss))
self.cur_epoch += 1
后记
核心函数简读到此,后面有时间再简读下其他函数。