在Keras as a simplified interface to TensorFlow: tutorial中,他们描述了如何在TensorFlow张量上调用Keras模型。
from keras.models import Sequential
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=784))
model.add(Dense(10, activation='softmax'))
# this works!
x = tf.placeholder(tf.float32, shape=(None, 784))
y = model(x)
他们还说:
注意:通过调用Keras模型,您将重用其体系结构和权重。当您在张量上调用模型时,您将在输入张量之上创建新的TF操作,并且这些操作正在重用模型中已存在的TF变量实例。
我将此解释为模型的权重在y
中与模型中的权重相同。但是,对我来说,似乎重新初始化了生成的Tensorflow节点中的权重。一个最小的例子可以在下面看到:
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
# Create model with weight initialized to 1
model = Sequential()
model.add(Dense(1, input_dim=1, kernel_initializer='ones',
bias_initializer='zeros'))
model.compile(loss='binary_crossentropy', optimizer='adam',
metrics=['accuracy'])
# Save the weights
model.save_weights('file')
# Create another identical model except with weight initialized to 0
model2 = Sequential()
model2.add(Dense(1, input_dim=1, kernel_initializer='zeros',
bias_initializer='zeros'))
model2.compile(loss='binary_crossentropy', optimizer='adam',
metrics=['accuracy'])
# Load the weight from the first model
model2.load_weights('file')
# Call model with Tensorflow tensor
v = tf.Variable([[1, ], ], dtype=tf.float32)
node = model2(v)
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
print(sess.run(node), model2.predict(np.array([[1, ], ])))
# Prints (array([[ 0.]], dtype=float32), array([[ 1.]], dtype=float32))
我想在另一个最小化方案中使用经过训练的网络,因为网络“惩罚”了搜索空间中不允许的位置。因此,如果您有不涉及这种特定方法的想法,那也非常感激。
答案 0 :(得分:8)
终于找到了答案。该问题的示例中存在两个问题。
第一个也是最明显的是我调用了tf.global_variables_intializer()
函数,它将重新初始化会话中的所有变量。相反,我应该调用tf.variables_initializer(var_list)
,其中var_list
是要初始化的变量列表。
第二个问题是Keras没有使用与原生Tensorflow对象相同的会话。这意味着为了能够使用我的会话model2(v)
运行tensorflow对象sess
,需要重新初始化它。再次Keras as a simplified interface to tensorflow: Tutorial能够提供帮助
我们应该首先创建一个TensorFlow会话并将其注册到Keras。这意味着Keras将使用我们注册的会话来初始化它在内部创建的所有变量。
import tensorflow as tf
sess = tf.Session()
from keras import backend as K
K.set_session(sess)
如果我们将这些更改应用于我的问题中提供的示例,我们将获得以下代码,该代码完全符合预期。
from keras import backend as K
from keras.models import Sequential
from keras.layers import Dense
sess = tf.Session()
# Register session with Keras
K.set_session(sess)
model = Sequential()
model.add(Dense(1, input_dim=1, kernel_initializer='ones',
bias_initializer='zeros'))
model.compile(loss='binary_crossentropy', optimizer='adam',
metrics=['accuracy'])
model.save_weights('test')
model2 = Sequential()
model2.add(Dense(1, input_dim=1, kernel_initializer='zeros',
bias_initializer='zeros'))
model2.compile(loss='binary_crossentropy', optimizer='adam',
metrics=['accuracy'])
model2.load_weights('test')
v = tf.Variable([[1, ], ], dtype=tf.float32)
node = model2(v)
init = tf.variables_initializer([v, ])
sess.run(init)
print(sess.run(node), model2.predict(np.array([[1, ], ])))
# prints: (array([[ 1.]], dtype=float32), array([[ 1.]], dtype=float32))
经验教训是,在混合Tensorflow和Keras时,请确保所有内容都使用相同的会话。
答案 1 :(得分:0)
感谢您提出这个问题,并回答了它,它对我有帮助!除了在Keras后端中设置相同的tf会话外,还需要注意的是,如果要从文件加载Keras模型,则需要在加载模型之前运行全局变量初始值设定项op。
sess = tf.Session()
# make sure keras has the same session as this code
tf.keras.backend.set_session(sess)
# Do this BEFORE loading a keras model
init_op = tf.global_variables_initializer()
sess.run(init_op)
model = models.load_model('path/to/your/model.h5')