【问题标题】:Unable to load tensorflow model with pickle无法使用 pickle 加载 tensorflow 模型
【发布时间】:2022-08-10 19:42:31
【问题描述】:

我正在尝试使用 pickle 进行 tensorflow 模型序列化。这是将模型保存在 pickle 文件中的代码 (dump.py):

import tensorflow as tf
import pickle
import numpy as np

tf.random.set_seed(42)

input_x = np.random.randint(0, 50000, (10000,1))
input_y = np.random.randint(0, 50000, (10000,1))
output = input_x + input_y
input = np.concatenate((input_x, input_y), axis=1)

model = tf.keras.Sequential([
    tf.keras.layers.Dense(2, activation = tf.keras.activations.relu, input_shape=[2]),   
    tf.keras.layers.Dense(2, activation = tf.keras.activations.relu),
    tf.keras.layers.Dense(1),
])

model.compile(loss = tf.keras.losses.mae,
              optimizer=tf.optimizers.Adam(learning_rate=0.00001),
              metrics = [\'mse\'])
          
model.fit(input, output, epochs = 1000)

fl = open(\'D:/tf/tf.pkl\', \'wb\')
pickle.dump(model, fl)
fl.close()

这是从 pickle 文件加载模型的代码 (load.py):

import pickle

fl = open(\'D:/tf/tf.pkl\', \'rb\')
model = pickle.load(fl)
print(model.predict([[2.2, 5.1]]))
fl.close()

这在 Linux 下运行良好。从 Windows 调用时,dump.py 成功,但 load.py 失败并显示以下错误消息:

2022-08-09 19:48:30.078245: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library \'cudart64_110.dll\'; dlerror: cudart64_110.dll not found
2022-08-09 19:48:30.078475: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
2022-08-09 19:48:32.847626: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library \'nvcuda.dll\'; dlerror: nvcuda.dll not found
2022-08-09 19:48:32.847804: W tensorflow/stream_executor/cuda/cuda_driver.cc:269] failed call to cuInit: UNKNOWN ERROR (303)
2022-08-09 19:48:32.851014: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: DEVELOPER
2022-08-09 19:48:32.851211: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: DEVELOPER
2022-08-09 19:48:32.851607: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
Traceback (most recent call last):
  File \"D:\\tf\\load_model.py\", line 4, in <module>
    model = dill.load(fl)
  File \"C:\\Users\\developer\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\dill\\_dill.py\", line 373, in load
    return Unpickler(file, ignore=ignore, **kwds).load()
  File \"C:\\Users\\developer\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\dill\\_dill.py\", line 646, in load
    obj = StockUnpickler.load(self)
  File \"C:\\Users\\developer\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\keras\\saving\\pickle_utils.py\", line 48, in deserialize_model_from_bytecode
    model = save_module.load_model(temp_dir)
  File \"C:\\Users\\developer\\AppData\\Local\\Programs\\Python\\Python39\\lib\\site-packages\\keras\\utils\\traceback_utils.py\", line 67, in error_handler
    raise e.with_traceback(filtered_tb) from None
  File \"C:\\Users\\developer\\AppData\\Roaming\\Python\\Python39\\site-packages\\tensorflow\\python\\saved_model\\load.py\", line 915, in load_partial
    raise FileNotFoundError(
FileNotFoundError: Unsuccessful TensorSliceReader constructor: Failed to find any matching files for ram://c1c4c456-27ff-4fb3-8f13-e0fb558da843/variables/variables
 You may be trying to load on a different device from the computational device. Consider setting the `experimental_io_device` option in `tf.saved_model.LoadOptions` to the io_device such as \'/job:localhost\'.

我怎样才能解决这个问题?

标签: python windows tensorflow pickle


【解决方案1】:

正如错误所说,当“您可能试图在与计算设备不同的设备上加载”时,可能会出现此问题。

该错误并非直接来自pickle,而是来自Tensorflow本身,正如您在堆栈跟踪中看到的那样,当它尝试执行此行时:

model = save_module.load_model(temp_dir)

因此,pickle 只是尝试在引擎盖下使用 Tensorflow 的 SavedModel 加载模型。解决方案是按照建议添加保存选项。 但是,您必须将它们添加到load_model 调用中,我认为这不能通过pickle.load() 完成。

如果你没有特别的理由使用pickle而不是直接调用Tensorflow的实用程序,我建议你直接切换到saveload_model

在这种情况下,这是您可以使用的代码:

# save
save_option = tf.saved_model.SaveOptions(experimental_io_device="/job:localhost")
model.save(model_dir, options=save_option)

# load
loaded_model = tf.keras.models.load_model(model_dir, options=save_option)

否则,如果您真的想保留泡菜,我想您只能泡菜模型的重量。指令weights = model.get_weights() 将所有权重张量的列表作为 Numpy 数组返回。您可以将权重转换为数组并腌制它。在另一台设备上,您可以重新创建您的架构并在那里重新加载权重。要加载权重,只需执行model.set_weights(weights)。请参阅here 了解更多信息。

这里的主要缺点是必须在目标设备上复制架构的代码,因为您必须自己重新创建模型的结构,但如果您对此感到满意,那么这绝对可以。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    相关资源
    最近更新 更多