Reputation: 31
I'm trying to use the matterport Mask R-CNN implementation to identify items in an image. I'm using the coco dataset as a starting point, and have trained it to recognize an additional type of object. That worked fine. It was able to recognize the presence of that type of object in a scene, with some success. I've recently completed a second batch of training, and now it is throwing an error when I try to examine the same scene for the presence of the same item.
While calling this code:
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)
my program now hits the following error:
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).
What causes this error? The fact that it only now showed up made me suspect that I messed up the second training process somehow, but I used the same process as the first training session, just with different images, so that seems like it can't be it. I haven't made any significant changes to the code in the intervening time either.
The only things about the images for the second training session that I can think of that might be off is that not all of the images have an instance of the object I'm training it to recognize, and I'm only training it to recognize one new type of object. I'm also using a smaller number of epochs for the second training session (15 total instead of 60 total).
If it's relevant, the bulk of the code for training and saving the layer weights is this:
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)
Upvotes: 1
Views: 2407
Reputation: 41
You should exclude some layers such as mrcnn_bbox_fc
, mrcnn_class_logits
(fill the layer's name in the load_weights
method), then start fine-tuning.
You can exclude these layers, instead of:
model.load_weights(CUSTOM_MODEL_PATH, by_name=True)
use:
model.load_weights(
COCO_MODEL_PATH, by_name=True,
exclude=["mrcnn_class_logits", "mrcnn_bbox_fc", "mrcnn_bbox", "mrcnn_mask", "rpn_model"])
Upvotes: 4