TFLearn载入模型NotFoundError: Key ...BatchNormalization/is_training not found in checkpoint解决方法

解决TFLearn模型加载错误
本文详细介绍了在使用TFLearn加载AffectNet模型时遇到的NotFoundError,并提供了具体的解决方案。通过调整batch_normalization层的trainable参数为False,成功解决了模型加载问题。

最近在使用TFLearn来载入AffectNet的TrainedNetwork,采用深度学习提取Valence & Arousal。关于AffectNet是IEEE Transactions on Affective Computing, 2017的论文成果,全名是《AffectNet: A Database for Facial Expression, Valence, and Arousal Computing in the Wild》,作者公开了database和model,可以到项目网页来获取信息和申请数据库和模型,论文可以在arXiv网页上获取到。

在通过model.load()的方法载入时报了一个非常长的错,看起来非常吓人,核心来说就是:

NotFoundError: Key ResNeXtBlock/BatchNormalization/is_training not found in checkpoint

查了许多资料,发现出现这样的原因,主要就是因为模型和代码不匹配。

通过inspect_checkpoint查看checkpoint模型中的网络结构,代码:

import tensorflow as tf
from tensorflow.python.tools import inspect_checkpoint as chkp

chkp.print_tensors_in_checkpoint_file("./model_resnet_-332000", tensor_name=None, all_tensors=True)

刚开头就显示出来关于is_training的信息

这说明之前报错中的is_training在模型中是False的状态,那在代码中是什么样的呢?

找到代码中的关键一句函数,也是报错中有显示到的batch_normalization,这两者关联在一起,出错在这里的概率最大

net = tflearn.batch_normalization(net)

查看TFLearn关于batch_normalization的文档说明

tflearn.layers.normalization.batch_normalization (incoming, beta=0.0, gamma=1.0, epsilon=1e-05, decay=0.9, stddev=0.002, trainable=True, restore=True, reuse=False, scope=None, name='BatchNormalization')

Normalize activations of the previous layer at each batch.

Arguments

  • trainablebool. If True, weights will be trainable.

可以看出,有trainable参数,且默认值为True,这就跟之前模型中的is_training为False有冲突了。

把这一句话修改一下

net = tflearn.batch_normalization(net, trainable=False)

其他不修改,load的部分就没有报错执行成功了!!

另外,TFLearn存下的模型最好还是用TFLearn来载入,用TensorFlow的saver.restore()方法也会报错,目前还不知道如何解决,如果有思路的欢迎留言!(参考TensorFlow: NotFoundError: Key not found in checkpoint

KeyError: "The name 'SGD' refers to an Operation not in the graph.

最后,把载入部分的完整代码结构放出来,出于对AffectNet的版权考虑,如需要完整数据库和模型,请联系作者,这里也将核心代码略去,只保留对解决这个问题最关键的一行代码。

from __future__ import division, print_function, absolute_import
import tensorflow as tf
import tflearn

import numpy as np

# Core part of training code of AffectNet. Please contact the author to request the official version.

# Important change of code to solve the problem.
net = tflearn.batch_normalization(net, trainable=False)

# The rest of the training code...

# Loading trained model
model.load("./Valence_Arousal/meta-data/model_resnet_-332000")

# Model loaded and you can do whatever you want now!

 

<think>嗯,用户遇到了TensorFlow加载模型检查点时出现的错误:“Key DecomNet/bn1_0/beta not found in checkpoint”。我之前已经给过他们一些解决方案,现在他们又提供了更详细的错误日志,我需要进一步分析。 首先,错误信息明确指出在检查点中不到DecomNet/bn1_0/beta这个变量。可能的原因包括变量命名不一致、模型结构变化或者检查点文件损坏。用户已经按照之前的建议检查了变量列表,但可能问题依然存在。 用户这次的错误日志显示他们在尝试加载检查点时,TensorFlow在save_restore_v2_ops.cc中抛出了NOT_FOUND错误。这说明问题可能出现在变量名的映射上,或者检查点文件确实缺少这个变量。我需要考虑用户是否正确地执行了变量名检查,或者是否有其他潜在的问题。 用户可能在加载检查点时没有正确指定作用域,或者模型代码中的层名称被修改了。例如,模型中的层可能没有正确使用命名空间,导致保存和加载时的变量名不一致。此外,用户可能在迁移或修改模型结构后没有更新检查点,导致部分变量缺失。 另外,用户的环境信息显示他们使用的是Anaconda中的PyTorch环境,但错误却来自TensorFlow。这可能意味着环境中同时安装了TensorFlow和PyTorch,可能存在版本冲突或者检查点文件是用不同版本的TensorFlow保存的,导致加载时出现问题。 还需要考虑用户是否正确使用了加载检查点的方法。例如,是否使用了tf.train.Saver或者tf.train.Checkpoint,并且是否正确指定了var_list。如果用户最近更新了TensorFlow版本,可能会有API的变化导致兼容性问题。 可能的解决方案包括:再次确认检查点中的变量名,使用更灵活的加载方式如expect_partial()来忽略缺失变量,或者检查模型代码中的变量作用域是否正确。此外,用户可能需要检查检查点文件是否完整,或者尝试重新保存模型权重。 用户可能需要进一步的帮助,例如提供模型定义和加载检查点的代码片段,以便更准确地定位问题。同时,提醒用户注意版本兼容性和命名空间的一致性,避免未来出现类似问题。</think>你的错误信息表明TensorFlow在加载检查点时无法到名为 `DecomNet/bn1_0/beta` 的变量。以下是详细的解释和解决方法: --- ### **错误原因** - **直接原因**:检查点文件(`.ckpt`)中缺少模型代码中定义的 `DecomNet/bn1_0/beta` 变量。 - **潜在原因**: 1. **变量命名不一致**:模型代码中的变量作用域(scope)或名称与检查点中保存的名称不一致。 2. **模型结构修改**:模型在训练后被修改(例如删除了某层或重命名了变量)。 3. **检查点文件不完整**:检查点未正确保存或被其他代码覆盖。 --- ### **解决方案步骤** #### 1. **检查检查点中的变量名** - **列出检查点所有变量**: 运行以下代码,查看检查点中实际保存的变量名称: ```python import tensorflow as tf checkpoint_path = '你的检查点路径' # 例如:'model.ckpt' variables = tf.train.list_variables(checkpoint_path) for name, shape in variables: print(f"变量名: {name}, 形状: {shape}") ``` - **观察输出**: - 如果输出中存在类似 `bn1_0/beta`(无 `DecomNet/` 前缀),说明变量作用域不一致。 - 如果完全缺失 `beta` 变量,可能是模型结构变更或检查点损坏。 #### 2. **修复变量名称映射** - **方案1:调整作用域**: 如果检查点中的变量名缺少 `DecomNet/` 前缀,在模型代码中添加作用域: ```python with tf.variable_scope("DecomNet"): # 定义 bn1_0 层(示例) bn1_0 = tf.keras.layers.BatchNormalization(name="bn1_0") ``` 重新训练模型并保存,确保作用域一致。 - **方案2:手动映射变量**: 使用 `tf.train.init_from_checkpoint` 指定名称映射: ```python var_list = { # 将检查点中的 "bn1_0/beta" 映射到当前模型的 "DecomNet/bn1_0/beta" "bn1_0/beta": tf.get_variable("DecomNet/bn1_0/beta", ...) } tf.train.init_from_checkpoint(checkpoint_path, var_list) ``` #### 3. **忽略缺失变量(仅限部分加载)** - 如果缺失变量可忽略(例如新增的层参数未在检查点中),使用 `expect_partial()` 跳过错误: ```python # 使用 tf.train.Checkpoint 加载 checkpoint = tf.train.Checkpoint(model=model) checkpoint.restore(checkpoint_path).expect_partial() print("部分加载成功,缺失变量将使用默认初始化值。") ``` #### 4. **验证检查点完整性** - **检查文件是否存在**: 确保检查点目录包含以下文件: - `model.ckpt.index` - `model.ckpt.data-00000-of-00001` - `model.ckpt.meta`(可选,仅旧版需要) - **重新保存模型**: 如果怀疑检查点损坏,尝试重新保存: ```python model.save_weights('new_checkpoint.ckpt') ``` #### 5. **版本兼容性检查** - **TensorFlow版本**: 确保保存和加载检查点时使用的TensorFlow版本一致(例如2.x与1.x不兼容)。 - **代码变更记录**: 回顾模型代码的历史修改,确认是否删除了 `DecomNet/bn1_0/beta` 相关层。 --- ### **附加排查建议** - **最小化复现**:尝试加载一个极简模型(仅包含报错层),验证是否能复现问题。 - **模型结构对比**: ```python # 打印当前模型所有变量名 for var in model.trainable_variables: print(var.name) ``` 与检查点变量列表对比,确认差异点。 --- ### **示例代码(修复作用域不一致)** 假设检查点中的变量名是 `bn1_0/beta`,而模型代码中变量名为 `DecomNet/bn1_0/beta`,可修改模型代码: ```python # 移除作用域定义(或与检查点作用域对齐) with tf.variable_scope(""): # 空作用域 bn_layer = tf.keras.layers.BatchNormalization(name="bn1_0") ``` --- 如果问题仍未解决,请提供以下信息: 1. 模型定义中 `DecomNet/bn1_0` 层的代码片段。 2. 检查点文件中的变量列表(通过 `list_variables` 输出)。 3. 使用的TensorFlow版本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值