Tensorflow 坑(和一些说明)

工作中遇到的一些问题,随手记下
来自我的cmd https://www.zybuluo.com/jiehanwang/note/770502

    • densenet 耗费显存的解释:

    不少人跟我们反映过 DenseNet 在训练时对内存消耗非常厉害。这个问题其实是算法实现不优带来的。当前的深度学习框架对 DenseNet 的密集连接没有很好的支持,我们只能借助于反复的拼接(Concatenation)操作,将之前层的输出与当前层的输出拼接在一起,然后传给下一层。对于大多数框架(如 Torch 和 TensorFlow),每次拼接操作都会开辟新的内存来保存拼接后的特征。这样就导致一个 L 层的网络,要消耗相当于 L(L+1)/2 层网络的内存(第 l 层的输出在内存里被存了 (L-l+1) 份)。来自这里

    • tfrecord数据过大,导致训练迟迟不能运行(减少训练数据确实可以运行)。tfrecord为何需要如此巨大的cpu内存???

    • densenet 随着计算进行,CPU内存也逐渐增大,如下图:


      Tensorflow 坑(和一些说明)_第1张图片
      image_1br3j3cm319i61qq5qei97mgmhg.png-59.8kB
    • 在densenet_small代码中,用Momentum可以达到90%以上,而GD只能到80%左右。

    opt = tf.train.MomentumOptimizer(lr, 0.9, use_nesterov=True)
    # opt = tf.train.GradientDescentOptimizer(lr)
    
  1. 七个小贴士,顺利提升TensorFlow模型训练表现。链接

  2. tfrecord的数据必须保持完整,不然训练的时候会发生截断错误,导致退出

  3. retrain 报错:模型大小不能超过67M,新版的tf据说已经解决了这个问题,mac上运行也没有问题。但是yard估计没有更新。加入以下语句即可解决。export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python

  4. A placeholder generates an error if it is executed without a feed, so you won't forget to feed it. 如果用feeding输入数据的话,最好用placeholder,这样,如果没有输入,在编译的时候就会报错。

  5. sv = tf.train.Supervisor(logdir=log_path, init_op=init) 会判断模型是否存在.如果存在,会自动读取模型.不用显式地调用restore。如果训练程序shut down或者crash了,那么它最近的checkpoint以及事件文件就被留到了logdir里。当你重启程序的时候,managed_session会从最近的checkpoint中加载图,并且从中止的地方恢复训练。
    再youtube-8m的train代码中就是这种方式。

  6. 如果模型包含一个标量整型变量名字为global_step,则该变量的值会被添加到checkpoint文件名中。例如,在global step 1234,checkpoint 文件名就是 “model.ckpt-1234”。【youtube-8m中的模型保存方式】

  7. 深度学习theano/tensorflow多显卡多人使用问题集: https://zhuanlan.zhihu.com/p/23250782 里面提到,多人用同一块卡的时候容易出现一方的内存不足。TF默认会占用所有的显存。以及,如何设置TF占用显存的百分比。

  8. 当保存的模型带有设备信息时,可以用以下方法去除,这样在gpu上训练的模型就可以在只有cpu的机器上运行。

When importing such models, it's useful to be able to clear the device settings in the graph so that we can run it on locally available devices. This can be achieved by calling import_meta_graph with the clear_devices option set to True.

  1. 解决“device specification '/device:GPU:3' because no supported kernel for GPU devices is available.”问题的方法(这是一个坑)有些操作只能在cpu进行,不按照以下方式进行,可能会出错

I just follow mrry's suggestion here, adding "allow_soft_placement=True" as follows: config = tf.ConfigProto(allow_soft_placement = True) sess = tf.Session(config = config) Then it works. I reviewed the Using GPUs in tutorial. It mentions adding "allow_soft_placement" under the error "Could not satisfy explicit device specification '/gpu:X' ". But it not mentions it could also solve the error "no supported kernel for GPU devices is available". Maybe it's better to add this in tutorial text in order to avoid confusing future users.

  1. densenet并行化中,出现过的问题汇总:

1). ValueError: No variables to save。这是因为没有用同一个graph的命名空间。
2). ValueError: Variable BatchNorm/beta does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=None in VarScope?
3). ValueError: Variable block_1/weight_conv_1 already exists, disallowed. Did you mean to set reuse=True in VarScope?
4). Variable conv2d/weight_conv_0/ExponentialMovingAverage/ does not exist, or was not created with tf.get_variable(). Did you mean to set reuse=None in VarScope?

  1. 下面的这篇并行方式值得参考:http://geek.csdn.net/news/detail/191567

  2. 如果想要达到重复利用变量的效果, 我们就要使用 tf.variable_scope(), 并搭配 tf.get_variable() 这种方式产生和提取变量. 不像 tf.Variable() 每次都会产生新的变量, tf.get_variable() 如果遇到了同样名字的变量时, 它会单纯的提取这个同样名字的变量(避免产生新变量). 而在重复使用的时候, 一定要在代码中强调 scope.reuse_variables(), 否则系统将会报错, 以为你只是单纯的不小心重复使用到了一个变量.

  3. Tensorflow cifar10_multi_gpu问题:"Variable conv1/weights/ExponentialMovingAverage/ does not exist". you can find the answer to your problem here: Issue 6220

You need to put: with tf.variable_scope(tf.get_variable_scope()) in front of the loop which runs over your devices ... so, do that:

with tf.variable_scope(tf.get_variable_scope()):
    for i in xrange(FLAGS.num_gpus):
        with tf.device('/gpu:%d' % i): 

The explanation is given in the link... Here the quote: When you do tf.get_variable_scope().reuse_variables() you set the current scope to reuse variables. If you call the optimizer in such scope, it's trying to reuse slot variables, which it cannot find, so it throws an error. If you put a scope around, the tf.get_variable_scope().reuse_variables() only affects that scope, so when you exit it, you're back in the non-reusing mode, the one you want.Hope that helps, let me know if I should clarify more.

  1. 如果要在tfrecord 上加上limit epoch数值如下:

    filename_queue = tf.train.string_input_producer(file_, num_epochs = FLAGS.num_epoch)
    

    需要初始化如下,否则会报错

    session.run(tf.global_variables_initializer())
    session.run(tf.local_variables_initializer())
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=session, coord=coord)
    
  2. train 和 test的数据流切换实现training的时候eval。参考这下面的链接。主要用到了tf.cond() 和 tf.QueueBase.from_list()函数【我没有搞定】

https://stackoverflow.com/questions/41162955/tensorflow-queues-switching-between-train-and-validation-data

  1. tfrecord 清点里面的数据数量

    c = 0
    for fn in tf_records_filenames:
      for record in tf.python_io.tf_record_iterator(fn):
         c += 1
    
  2. Densenet 采用内存优化的代码,其实就是给每个block加了一层1*1的卷积?这个理解有误,需要进一步查看文献

你可能感兴趣的:(Tensorflow 坑(和一些说明))