Tensorflow 框架的一些细节

其中常用的fetches和feed_dict就是常用的传入参数。fetches主要指从计算图中取回计算结果进行放回的那些placeholder和变量,而feed_dict则是将对应的数据传入计算图中占位符,它是字典数据结构只在调用方法内有效。

DIEN 的代码在 model.train() 和 model.calculate() 中都用到了 session.run() 函数,

  • model.train([self.loss, self.accuracy, self.optimizer], feed_dict={...})
  • model.calculate([self.y_hat, self.loss, self.accuracy], feed_dict={...})

在这里,train() 要进行模型的优化,所以需要输出 self.optimizer, 保证 self.optimizer 这一变量进行了更新
calculate() 实际上是对应测试,需要输出 self.y_hat, 但并不需要进行模型的优化,迭代一个梯度步

似乎是必须要指定最后一维的维数,而先前 self.target_timepoint, self.item_history_timepoint 的维度无法被推测出来。因为 [128, 7], 128 是 batch size, 可能会变化,但是 tensorflow 静态图,必须先预先确定维数。

self.target_timepoint = tf.placeholder(tf.float32, [None, 7], name='target_timepoint') #[128, 7] 

类似如下在 model 中的修改修改:

self.timeconsecutive_history.set_shape([None, None, 7])
self.timecurrent_history.set_shape([None, None, 7])

这两种修改似乎都可以成功。

  • tensorflow 由于静态图,同时出现的模块必须要使用不同的名字,否则会报错:
    ValueError: Variable f1_attnull/kernel already exists, disallowed. Did you mean to set reuse=True or reuse=tf.AUTO_REUSE in VarScope? Originally defined at:
    attention_output2 = attention_DIN(self.target_timepoint, self.item_history_timepoint, ATTENTION_SIZE, self.mask, stag='time_point'
    使用 stag='time_point' 修改了此 bug。

  • numpy + tensorflow 很坑的 bug:

target_timepoint.append(inp[10][seqlen - maxlen:])
target_timepoint_np = np.zeros((n_samples, len(target_timepoint[0]))).astype('float32') # [128, 7]
for idx in range(128) :
      target_timepoint_np[idx, :] = target_timepoint[idx]

这里其实 inp[10] 就是一个长为 7 的序列,当 seq_len 很大 [seqlen - maxlen:] 会导致 append 一个空的 list. 而下面,把一个空集可以很轻松地赋给一个 numpy array, 并且没有抛出错误。

最终导致如下错误:
ValueError: Cannot feed value of shape (128, 0) for Tensor u'Inputs/target_timepoint:0', which has shape '(?, 7)'
输出 print target_timepoint_np, 发现了最后面有一个空 [], 这才发现了这个错误。

# from __future__ import absolute_import
# from __future__ import division
# from __future__ import print_function

需要使用这个。
或者 保证除法有一个数是浮点数,这样,就可以使得最终的数也是浮点数。我之前好像全部都弄错了?!

  • linux 上运行 python 程序,如果 train_data 太大(47 G),可能会导致需要使用非常大的 cpu 内存。当 cpu 内存使用量大到一定程度,系统即将崩溃的时候,linux 内核会直接 kill 该进程,输出 “killed”。关于 cpu 内存的使用量监控,可以使用 top 命令,会看到某一个进程的 cpu 内存使用量会一直增长,直到 100%,然后内核程序会 kill 到该进程。http://www.45fan.com/article.php?aid=20020575243365012677632517
    我的代码是使用了 GPU 的,GPU 显存的使用量不大,但不知为何 cpu 的内存炸了。而且似乎是在刚调用函数,还没有运行函数内部第一行命令(个人加的语句进行debug),就开始了预处理生成 tensorflow 的静态图。并在生成静态图的时候,cpu 内存一直增加,导致进程被 kill.

奇怪的是,当换用了小的 train data, 程序能够正常运行了。

posted @ 2020-07-08 15:07  Gelthin  阅读(464)  评论(0编辑  收藏  举报