Jus*_*her 8 python machine-learning tensorflow
我正在用TensorFlow进行一些实验,并遇到了障碍.我正在尝试使用TF来评估模型中的变化,然后根据损失函数的结果变化保留或恢复模型.我已经找到了困难的部分(条件控制),但我坚持一些应该相当简单的事情:我似乎无法存储一个tf.trainable_variables迭代,然后在需要时恢复它.
让我们说一个构建一个Op:
...
store_trainable_vars = []
for v in tf.trainable_variables():
store_trainable_vars.append(v)
...
Run Code Online (Sandbox Code Playgroud)
然后,我想恢复tf.trainable_variables到上次运行此操作时的值.我想做的事情如下:
def reject_move():
revert_state = []
for (v, s) in zip(tf.trainable_variables(), store_trainable_vars):
revert_state.append(tf.assign(v, s, name="revert_state"))
return(revert_state)
Run Code Online (Sandbox Code Playgroud)
显然,这将重新评估store_trainable_vars,这反过来又与现在的价值相关联tf.trainable_variables(),从而避免了revert_stateOp.我需要一些方法来存储和检索Tensors的值,而不回调那些Tensors的现值.就像是
...
store_trainable_vars = []
for v in tf.trainable_variables():
store_trainable_vars.append(v.value_right_now())
...
Run Code Online (Sandbox Code Playgroud)
其中v.value_right_now()返回一个在被覆盖之前不会改变的常量.
我知道我可以使用Saver,但是该解决方案会写入磁盘,这对于此应用程序是不可接受的,因为它将在训练循环内运行.
我可能错过了一些明显的东西 - 任何指导都会受到赞赏.
要手动恢复图形状态,您需要使用tf.tuple或tf.group操作,这将修改批量更改的流程:
这将创建一个具有与tensors参数相同值的张量元组,除了每个张量的值仅在计算了所有张量的值后返回.
[更新]以下是我将如何做到这一点:
import numpy as np
import tensorflow as tf
x = tf.placeholder(shape=[None, 5], dtype=tf.float32, name='x')
W = tf.Variable(np.zeros([5, 5]), dtype=tf.float32, name='W')
b = tf.Variable(np.zeros([5]), dtype=tf.float32, name='b')
y = tf.add(tf.matmul(x, W), b)
with tf.Session() as session:
batch = np.ones([2, 5])
session.run(tf.global_variables_initializer())
print session.run(y, feed_dict={x: batch}) # prints [2, 5] zeros
# store the current value
store = {v.name: v.eval(session) for v in tf.trainable_variables()}
print store # prints [5, 5] and [5] zeros
# update
new = {'W:0': np.ones([5, 5]), 'b:0': np.ones([5])}
session.run(tf.tuple([tf.assign(var, new[var.name]) for var in tf.trainable_variables()]))
print session.run(y, feed_dict={x: batch}) # prints [2, 5] sixes
# restore
session.run(tf.tuple([tf.assign(var, store[var.name]) for var in tf.trainable_variables()]))
print session.run(y, feed_dict={x: batch}) # prints [2, 5] zeros again
Run Code Online (Sandbox Code Playgroud)
但我真的认为你应该重新考虑你的决定Saver,因为它也被设计用于训练循环中.在内部,Saver为你做的所有棘手的工作(特别是,它恢复操作调用tf.group,tf.control_dependencies如果需要),否则可能成为非常讨厌的错误的来源.此外,磁盘(几乎)总是比GPU和主内存大,所以如果你能负担得起将模型存储在内存中,你也应该能够存储在磁盘上.
max_to_keep表示要保留的最近检查点文件的最大数量.创建新文件时,将删除旧文件.如果为None或0,则保留所有检查点文件.默认为5(即保留最近的5个检查点文件).keep_checkpoint_every_n_hours:除了保留最新的
max_to_keep检查点文件之外,您可能希望每N小时的训练保留一个检查点文件.如果您想稍后分析模型在长时间训练期间的进展情况,这将非常有用.例如,传递keep_checkpoint_every_n_hours=2确保每2小时训练保留一个检查点文件.默认值10,000小时有效地禁用了该功能.[更新]正如评论中所阐明的那样,主要关注的是磁盘延迟,如果过于频繁访问,可能会减慢培训速度.如果您使用的是Linux,它会缓存经常使用的磁盘页面,Windows也会这样做.但如果你想绝对确定,请考虑使用tmpfs.
我本来不想自己回答这个问题,但我想出了一个相当有效的方法。所以,我想我会分享它。关键的见解来自这个非常聪明的答案。该方法是重用为初始变量赋值创建的赋值节点。下面给出了实现该方法的完整类。
import tensorflow as tf
class TensorFlowState(object):
def __init__(self):
# Get the graph.
graph = tf.get_default_graph()
# Extract the global varibles from the graph.
self.gvars = graph.get_collection(tf.GraphKeys.GLOBAL_VARIABLES)
# Exract the Assign operations for later use.
self.assign_ops = [graph.get_operation_by_name(v.op.name + "/Assign")
for v in self.gvars]
# Extract the initial value ops from each Assign op for later use.
self.init_values = [op.inputs[1] for op in self.assign_ops]
def start(self, sess):
self.sess = sess
def store(self):
# Record the current state of the TF global varaibles
self.state = self.sess.run(self.gvars)
def restore(self):
# Create a dictionary of the iniailizers and stored state of globals.
feed_dict = {init_value: val
for init_value, val in zip(self.init_values, self.state)}
# Use the initializer ops for each variable to load the stored values.
return(self.sess.run(self.assign_ops, feed_dict=feed_dict))
Run Code Online (Sandbox Code Playgroud)
使用时,只需实例化该类,调用该start方法来传递 a ,然后根据需要在命令式训练循环中tf.Session调用store和方法。restore我使用此实现构建了一个优化器,其运行速度与 TensorFlow 中包含的梯度下降优化器一样快。
| 归档时间: |
|
| 查看次数: |
246 次 |
| 最近记录: |