【问题标题】:Calling a Keras model on a TensorFlow tensor but keep weights在 TensorFlow 张量上调用 Keras 模型但保留权重
【发布时间】:2018-03-29 03:59:48
【问题描述】:

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))

我为什么要这样做:

如果网络“惩罚”搜索空间中不允许的位置,我想在另一个最小化方案中使用经过训练的网络。因此,如果您有不涉及这种特定方法的想法,那也非常感谢。

【问题讨论】:

    标签: tensorflow keras


    【解决方案1】:

    终于找到了答案。该问题的示例中有两个问题。

    1:

    第一个也是最明显的是我调用了tf.global_variables_intializer() 函数,它将重新初始化会话中的所有变量。相反,我应该调用tf.variables_initializer(var_list),其中var_list 是要初始化的变量列表。

    2:

    第二个问题是 Keras 没有使用与原生 Tensorflow 对象相同的会话。这意味着为了能够使用我的会话 sess 运行 tensorflow 对象 model2(v),它需要重新初始化。再次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 时,请确保所有内容都使用相同的会话。

    【讨论】:

    • 在您的示例中使用 tf.global_variables_initializer() 有什么问题?
    • @ImranRashid tf.global_variables_initializer() 将重新初始化 所有 变量,包括我希望保持不变的 Keras 模型中的权重。
    【解决方案2】:

    感谢您提出这个问题并回答它,它帮助了我!除了在 Keras 后端设置相同的 tf 会话之外,还需要注意的是,如果要从文件中加载 Keras 模型,则需要在加载模型之前运行全局变量初始化程序操作。

    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')
    

    【讨论】:

    • 很高兴听到我的努力帮助了某人。实际上,正是提出问题的过程让我走上了解决问题的正确轨道。
    猜你喜欢
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-11
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    相关资源
    最近更新 更多