tensorflow训练过程的日志与监控

Logging and Monitoring Basics with tf.contrib.learn


https://www.tensorflow.org/get_started/monitors


这篇文档的准备是 tf.estimator Quickstart,
https://www.tensorflow.org/get_started/estimator
对应的博客在:
http://blog.csdn.net/vagrantabc2017/article/details/77479632
最终的参考代码:
https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/examples/tutorials/monitors/iris_monitors.py


小结下Getting Started教程,前5篇在讲模型,后5篇都在讲可视化,可视化本身地TF的一大特点。
作用:在训练模型的过程中实时跟踪和评估模型的成熟度,以免欠拟合或过拟合。
重点:logging能力和Monitor API。
先不看最终代码,从网页给的代码看起。拷入IDE,把iris_training.csv和iris_test.csv拷入同级目录。
estimator那篇有个问题就是没有过程日志,直接给了结果,没办法跟踪。
模型是否收敛?early stopping是否适当?没日志就没有过程感觉。
方式一:把training划分为若干个更小的fit调用,步骤更小,每调完一次,可以做一次评估,逐步渐近,但很慢,不推荐。
方式二:tf.contrib.learn Monitor API.可以在模型训练的同时度量指标并完成模型评估。
解决三个问题:
1.如何打开log?
2.如何设置ValidationMonitor完成流式评估?
3.如何在TensorBoard中看度量数据?


问题一:如何打开log?
tensorflow使用五级日志:DEBUG, INFO, WARN, ERROR, and FATAL. 没什么特别的,使用过log4j的人表示很习惯。
一般设到WARN级比较合适,但调试日志会设到DEBUG级。与log4j差不多。
解决这个问题要使用tf.logging模块,位置在tensorflow\python\platform\tf_logging.py,这个模块基于python3的logging模块创建。
例:把日志设置为INFO级别
tf.logging.set_verbosity(tf.logging.INFO)
当设置INFO级别后,tf.contrib.learn会自动每百步后输出损失度量数据到标准输出。
代码在IDE中没有跑过。报异常。
从日志上看,monitor用得有问题。
WARNING:tensorflow:From C:\Users\hasee\workspace\tftest\com\monitor\iris_monitors.py:77: calling BaseEstimator.fit (from tensorflow.contrib.learn.python.learn.estimators.estimator) with y is deprecated and will be removed after 2016-12-01.
Instructions for updating:
Estimator is decoupled from Scikit Learn interface by moving into
separate class SKCompat. Arguments x, y and batch_size are only
available in the SKCompat class, Estimator will only accept input_fn.
Example conversion:
  est = Estimator(...) -> est = SKCompat(Estimator(...))
所以,官网本小节给出的代码可能是没有更新的,查了下stackoverflow,可能适用于老版本的代码。
这里澄清下:目前classifier本质上是estimator,没有fit方法,并且本身的train等方法也不再接收x,y等参数,这些参数交给了input_fn去处理,而train方法只接收input_fn参数。这看上去与老版本不同。
索性把tf.estimator Quickstart的代码拷过来改。
跑一下:
Test Accuracy: 0.966667


New Samples, Class Predictions:    [array([b'1'], dtype=object), array([b'1'], dtype=object)]
和原来一样,妥妥的。
在import后面加上句:
tf.logging.set_verbosity(tf.logging.INFO)
就开始打印配置信息,创建CheckpointSaverHook,并且把过程打出来。每百步的损失值,消耗时间,每秒跑的步数等。
INFO:tensorflow:step = 40001, loss = 4.66333
INFO:tensorflow:global_step/sec: 458.689
INFO:tensorflow:step = 40101, loss = 1.37071 (0.219 sec)
INFO:tensorflow:global_step/sec: 602.375
INFO:tensorflow:step = 40201, loss = 2.09407 (0.164 sec)
INFO:tensorflow:global_step/sec: 781.205
这个格式比官网信息更多点,估计是官网没更新。
小结:使用tf.logging.set_verbosity()可设置日志级别。


问题二:如何设置ValidationMonitor完成流式评估?
日志可以看到loss,从而发现模型是否收敛,但看不到内部过程。Monitor显然更厉害。
对于monitor的类别,网上有很多类似的文章,如:http://blog.csdn.net/sysstc/article/details/74172683,这里简单小结下。
CaptureVariable:每n步训练,把某指定变量的值保存在一个集合中。
PrintTensor:每n步训练,反某指定张量的值打出来。
SummarySaver:每n步训练,使用tf.summary.FileWriter把特定张量的 tf.Summary protocol buffers保存下来。什么是协议缓存?官方定义为一种灵活有效自动化的序列化数据结构的一种机制,简单讲就是用来做序列化用的,想下xml,它差不多,只是更小,更快,更简单。有兴趣可以参看官网:https://developers.google.com/protocol-buffers/docs/overview
ValidationMonitor:每n步训练,记录一套特定的度量数据,如果需要,在一定条件下可以中止训练。这个好。官网也是介绍的这个。
测试下model_dir的作用。检查C:\tmp\iris_model,里面有checkpoint文件1个,事件输出文件若干,graph.pbtxt文件1个,模型检查点数据文件和索引文件若干。这些文件记录了模型从一开始到上次训练结束的状态。代码一跑起来,这些文件会载入内存,模型会从上次状态继续训练。测试下:
跑一次,step最后记录:
INFO:tensorflow:step = 45901, loss = 3.31337 (0.146 sec)
INFO:tensorflow:Saving checkpoints for 46000 into /tmp/iris_model\model.ckpt.
。。。
再跑一次:
INFO:tensorflow:Restoring parameters from /tmp/iris_model\model.ckpt-46000
INFO:tensorflow:Saving checkpoints for 46001 into /tmp/iris_model\model.ckpt.
INFO:tensorflow:loss = 3.47932, step = 46001
INFO:tensorflow:global_step/sec: 666.628
INFO:tensorflow:loss = 2.28465, step = 46101 (0.150 sec)
INFO:tensorflow:global_step/sec: 740.699
可以看出,上一次是46000结束的,后面还以46000开始,每100步做一次评估。检查点看上去只在跑完后做了一次保存。
把C:\tmp\iris_model的内容清空,再跑。
INFO:tensorflow:Saving checkpoints for 1 into /tmp/iris_model\model.ckpt.
INFO:tensorflow:loss = 303.956, step = 1
INFO:tensorflow:global_step/sec: 425.507
模型从1开始训练了,相当于从头训练!
并且,意外的是[5.8, 3.1, 5.0, 1.7]被分类为2了,而不再是1.
我有点怀疑之前跑出来一直是1就是因为这个目录一直没清。
下面来改改这个行为。
任务:基于test数据,每50步评估一次,配置一个ValidationMonitor。
在分类器定义之前放上monitor定义代码:
validation_monitor = tf.contrib.learn.monitors.ValidationMonitor(
    test_set.data,
    test_set.target,
    every_n_steps=50)  #每50步评估一次
把config=tf.contrib.learn.RunConfig(save_checkpoints_secs=1)做为第5个参数加给分类器定义。
    classifier = tf.estimator.DNNClassifier(feature_columns=feature_columns,
                                          hidden_units=[10, 20, 10],
                                          n_classes=3,
                                          model_dir="/tmp/iris_model",
                                          config=tf.contrib.learn.RunConfig(save_checkpoints_secs=1)) #每秒保存一次检查点
再跑一次:
INFO:tensorflow:Restoring parameters from /tmp/iris_model\model.ckpt-4000
INFO:tensorflow:Saving checkpoints for 4001 into /tmp/iris_model\model.ckpt.
INFO:tensorflow:loss = 5.7697, step = 4001
INFO:tensorflow:Saving checkpoints for 4022 into /tmp/iris_model\model.ckpt.
INFO:tensorflow:global_step/sec: 121.944
INFO:tensorflow:loss = 9.37391, step = 4101 (0.816 sec)
INFO:tensorflow:global_step/sec: 724.596
INFO:tensorflow:loss = 10.04, step = 4201 (0.135 sec)
INFO:tensorflow:Saving checkpoints for 4274 into /tmp/iris_model\model.ckpt.
每秒做一次ckpt已有效了。step还是100,因为定义的validation_monitor和classifier还没啥关系。
官网的做法是:
classifier.fit(x=training_set.data,
               y=training_set.target,
               steps=2000,
               monitors=[validation_monitor])
但现在classifier已没有fit了。且train的定义是:
def train(self, input_fn, hooks=None, steps=None, max_steps=None):
想加下monitor也加不进去啊。有点没办法了。
想想原因猜一下:DNNClassifier, DNNRegressor, LinearClassifer, LinearRegressor这些东西自己就是评估工具,不需要ValidationMonitor吧。
现在的estimator的class的定义中已有evaluate方法:
  def evaluate(self, input_fn, steps=None, hooks=None, checkpoint_path=None,
               name=None):
不瞎猜了,这个版本才出来,以后熟悉了,就知道咋回事了,有知道咋回事的同学请在下面留言。我觉得现在多跑跑这个方法比想着monitor靠谱。




你可能感兴趣的:(深度学习)