python - 层权重的 keras 形状与保存的权重形状不匹配
问题描述
我正在尝试使用 matterport Mask R-CNN 实现来识别图像中的项目。我使用 coco 数据集作为起点,并训练它识别其他类型的对象。那工作得很好。它能够成功地识别出场景中存在这种类型的物体。我最近完成了第二批训练,现在当我尝试检查同一个场景是否存在同一个项目时,它会抛出一个错误。
调用此代码时:
model = modellib.MaskRCNN(mode="inference", config=config, model_dir=LOGS_AND_MODEL_DIR)
weights = args["weights"] if args["weights"] \
else model.find_last()
model.load_weights(weights, by_name=True)
我的程序现在遇到以下错误:
Traceback (most recent call last):
File "mask_training.py", line 185, in <module>
model.load_weights(weights, by_name=True)
File "/usr/local/lib/python3.6/site-packages/mask_rcnn-2.1-py3.6.egg/mrcnn/model.py", line 2132, in load_weights
File "/usr/local/lib/python3.6/site-packages/keras/engine/saving.py", line 1018, in load_weights_from_hdf5_group_by_name
str(weight_values[i].shape) + '.')
ValueError: Layer #389 (named "mrcnn_bbox_fc"), weight <tf.Variable 'mrcnn_bbox_fc/kernel:0' shape=(1024, 8) dtype=float32_ref> has shape (1024, 8), but the saved weight has shape (1024, 324).
是什么导致了这个错误?它现在才出现的事实让我怀疑我以某种方式搞砸了第二次训练过程,但我使用了与第一次训练相同的过程,只是使用了不同的图像,所以这似乎不可能。在此期间,我也没有对代码进行任何重大更改。
我能想到的关于第二次训练的图像的唯一可能是关闭的,不是所有的图像都有我训练它识别的对象的实例,我只是训练它识别一种新型对象。我还在第二次培训课程中使用了较少数量的 epoch(总共 15 个而不是总共 60 个)。
如果相关,用于训练和保存层权重的大部分代码是这样的:
idxs = list(range(0, len(IMAGE_PATHS)))
random.seed(42)
random.shuffle(idxs)
i = int(len(idxs) * TRAINING_SPLIT)
trainIdxs = idxs[:i]
valIdxs = idxs[i:]
trainDataset = ImageBoundaryDataset(IMAGE_PATHS, CLASS_NAMES)
trainDataset.load_images(trainIdxs)
trainDataset.prepare()
valDataset = ImageBoundaryDataset(IMAGE_PATHS, CLASS_NAMES)
valDataset.load_images(valIdxs)
valDataset.prepare()
config = ImageBoundaryConfig()
config.display()
#image augmentation, flip or rotate image
aug = iaa.SomeOf((0, 2), [
iaa.Fliplr(0.5),
iaa.Flipud(0.5),
iaa.Affine(rotate=(-10, 10))
])
model = modellib.MaskRCNN(mode="training", config=config, model_dir=LOGS_AND_MODEL_DIR)
model.load_weights(COCO_PATH, by_name=True,
exclude=["mrcnn_class_logits", "mrcnn_bbox_fc",
"mrcnn_bbox", "mrcnn_mask"])
print("loaded weights, about to train layer heads")
#train layer heads
model.train(trainDataset, valDataset, learning_rate=config.LEARNING_RATE, epochs=5,
layers="heads",
augmentation=aug)
print("trained layer heads, about to train model")
#train all layers
model.train(trainDataset, valDataset, epochs=10, #usually 40 for serious training
layers="all", learning_rate=config.LEARNING_RATE / 10, augmentation=aug)
解决方案
您应该排除一些层,例如mrcnn_bbox_fc
, mrcnn_class_logits
(在方法中填写层的名称load_weights
),然后开始微调。
您可以排除这些层,而不是:
model.load_weights(CUSTOM_MODEL_PATH, by_name=True)
利用:
model.load_weights(
COCO_MODEL_PATH, by_name=True,
exclude=["mrcnn_class_logits", "mrcnn_bbox_fc", "mrcnn_bbox", "mrcnn_mask", "rpn_model"])
推荐阅读
- c++ - 智能指针:不存在合适的构造函数来从 derived_object* 转换为 std::shared_ptr
- java - 如何在循环中从 EditText 中提取文本并将其连接起来以在单个 TextView 中查看?
- javascript - 尽管范围是十六进制值,但 D3 scaleLinear() 返回 rgb 值
- strapi - 自动定时动作
- python - 联合子查询的 SqlAlchemy groupby
- haskell - 函数中的数据类型不匹配
- swift - 如何为结构实现哈希(进入哈希:输入哈希)
- python - 如何将 CoreML 模型转换为 TensorFlow 模型?
- java - 如何正确地从另一个实体中删除一个实体?
- python - Ttle 和颜色属性不适用于此散景图