Python Tensorflow在重用设置为true的情况下创建新变量
我正在尝试构建一个基本的RNN,但在培训后尝试使用网络时会出现错误。 我在函数Python Tensorflow在重用设置为true的情况下创建新变量,python,tensorflow,keras,Python,Tensorflow,Keras,我正在尝试构建一个基本的RNN,但在培训后尝试使用网络时会出现错误。 我在函数推理 def inference(inp): with tf.name_scope("inference"): layer = SimpleRNN(1, activation='sigmoid', return_sequences=False)(inp) layer = Dense(1)(layer) return layer 但每次我调用它时,都会创建另一组变
推理
def inference(inp):
with tf.name_scope("inference"):
layer = SimpleRNN(1, activation='sigmoid', return_sequences=False)(inp)
layer = Dense(1)(layer)
return layer
但每次我调用它时,都会创建另一组变量,尽管在培训中使用了相同的作用域:
def train(sess, seq_len=2, epochs=100):
x_input, y_input = generate_data(seq_len)
with tf.name_scope('train_input'):
x = tf.placeholder(tf.float32, (None, seq_len, 1))
y = tf.placeholder(tf.float32, (None, 1))
with tf.variable_scope('RNN'):
output = inference(x)
with tf.name_scope('training'):
loss = tf.losses.mean_squared_error(labels=y, predictions=output)
train_op = tf.train.RMSPropOptimizer(learning_rate=0.1).minimize(loss=loss, global_step=tf.train.get_global_step())
with sess.as_default():
sess.run([tf.global_variables_initializer(), tf.local_variables_initializer()])
for i in tqdm.trange(epochs):
ls, res, _ = sess.run([loss, output, train_op], feed_dict={x:x_input, y:y_input})
if i%100==0:
print(f'{ls}: {res[10]} - {y_input[10]}')
x_input, y_input = generate_data(seq_len)
预测:
def predict_signal(sess, x, seq_len):
# Preparing signal (omitted)
# Predict
inp = tf.convert_to_tensor(prepared_signal, tf.float32)
with sess.as_default():
with tf.variable_scope('RNN', reuse=True) as scope:
output = inference(inp)
result = output.eval()
return result
到目前为止,我已经花了几个小时阅读了变量范围,但是在运行预测时,我仍然得到一个错误
,试图使用未初始化的值RNN_1/推理/simple_RNN_2/内核
,其中RNN_1的数量随着每次调用的增加而增加这只是猜测,直到您向我们展示SimpleRNN
实现。然而,我怀疑SimpleRNN
的实现非常糟糕。有一个不同的getweentf.get_variable
和tf.variable
。我希望您的SimpleRNN
使用tf.Variable
要重现这种行为:
import tensorflow as tf
def inference(x):
w = tf.Variable(1., name='w')
layer = x + w
return layer
x = tf.placeholder(tf.float32)
with tf.variable_scope('RNN'):
output = inference(x)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
print(sess.run(output, {x: 10}))
with sess.as_default():
with tf.variable_scope('RNN', reuse=True):
output2 = inference(x)
print(sess.run(output2, {x: 10}))
这会产生完全相同的错误:
试图使用未初始化的值RNN_1/w
但是,使用w=tf.get_变量('w',初始值设定项=1。)
而不是w=tf.variable(1',name='w')
的版本可以工作
为什么??见文件:
获取具有这些参数的现有变量或创建新变量。
此函数使用当前变量范围作为名称的前缀,并执行重用检查
编辑
谢谢你的提问(我在你的问题中添加了keras标志)。这正成为我最喜欢的理由,向人们展示为什么使用Keras是他们做过的最糟糕的决定
单纯形
这个
哪个
这是实现中的一个明显缺陷。
在Keras以正确的方式使用TensorFlow之前(至少涉及
范围
和变量集合
),您应该寻找替代方案。有人能给你的最好建议是切换到更好的版本,比如官方的tf.layers
@Patwie对错误做出了正确的诊断-参考Keras实现中可能存在的错误
然而,在我看来,合乎逻辑的结论不是排除Keras,而是使用tensorflow附带的Keras实现,可以在tf.Keras
中找到。您将发现在这个实现中正确地生成了变量tf.keras
是专门为tensorflow实现的,应将此类接口错误降至最低
事实上,如果您已经是tensorflow,我看不到使用参考Keras而不是
tf.Keras
有什么特别的好处,除非您使用它的最新功能,tf.Keras
在版本上通常有点落后(例如,目前在TF1.8中是2.1.5,而Keras 2.2.0已经发布了大约一个月).我使用来自keras的SimpleRN实现keras有太多问题。Keras不尊重范围
和集合
打破TensorFlow的所有常见假设。有人能给你的最好建议就是坚持使用官方的tf.layers
。现在凯拉斯·范博伊斯让落选开始了。伟大的观察@Patwie!我遇到了一些来自keras simpleRNN的奇怪行为,他们试图解决一个相当简单的任务。发布了关于它的消息。我相信这是由于这个实现错误造成的。切换到keras tf似乎可以解决这个问题。只是想让你的观点更有力,我现在坚信,如果你使用tensorflow,那么就使用专门为它实现的keras,而不是一般的keras。我还没有测试过tf.keras。但是快速查看一下实现,就会发现add\u weight
中涉及到更多的逻辑。我这边请大家投票,建议使用tf.keras来代替keras(我认为它们应该是一样的)。但是如果这有帮助,为什么不呢。
self.kernel = self.add_weight(shape=(input_shape[-1], self.units),
name='kernel',...)
weight = K.variable(initializer(shape),
dtype=dtype,
name=name,
constraint=constraint)
v = tf.Variable(value, dtype=tf.as_dtype(dtype), name=name)