Mask_RCNN
Mask_RCNN copied to clipboard
Mask R CNN predicts one class for everything
Hey guys! I'm using Mask R CNN on a custom dataset, very simple: solid background and objects divided into 4 classes, more or less of the same size, in the same place in the image. The dataset is balanced, every class has exactly the same number of images in the train and in the test. However, regardless of any parameters, length of training, anything, it predicts me one class only. I have tried to increase the weight for the class prediction - and it is dropping with every epoch, but the predictions remain the same - I always get the class 1 , even if in fact there is class 4 or 3. Here is the configuration:
image_size = 256
rpn_anchor_template = (2, 4, 8, 16, 32) # anchor sizes in pixels
rpn_anchor_scales = tuple(i * (image_size // 16) for i in rpn_anchor_template)
class NewConfig(Config):
NAME = "industry"
GPU_COUNT = 1
IMAGES_PER_GPU = 2
NUM_CLASSES = len(subset)+1
IMAGE_MAX_DIM = image_size
IMAGE_MIN_DIM = image_size
RPN_ANCHOR_SCALES = rpn_anchor_scales
TRAIN_ROIS_PER_IMAGE = 8
LOSS_WEIGHTS={'mrcnn_mask_loss': 1.0,
'rpn_class_loss': 5.0, 'mrcnn_class_loss': 5.0,
'mrcnn_bbox_loss': 1.0, 'rpn_bbox_loss': 2.0}
STEPS_PER_EPOCH = 100
VALIDATION_STEPS = STEPS_PER_EPOCH / 10
def __init__(self, num_classes):
self.NUM_CLASSES = num_classes
super().__init__()
config = NewConfig(num_classes=len(subset)+1)
config.display()
Maybe there is something wrong here, because in the dataset the number of classes is correct.
What are the parameters passed to your model.load_weights() function?
@ebernalg92
model.load_weights(model_path, by_name=True,exclude=[ "mrcnn_class_logits", "mrcnn_bbox_fc","mrcnn_bbox", "mrcnn_mask"])
But actually, I also checked, and it changes the prediction from time to time (with the same weights, taken from the same epoch) which is strange, because for the same parameters it should be consistent, no?
yeah, i was experimenting the same issue, just use :
model.load_weights(model_path, by_name=True)
not excluding [ "mrcnn_class_logits", "mrcnn_bbox_fc","mrcnn_bbox", "mrcnn_mask"]
This is while doing inference this way
model = MaskRCNN( mode="inference", model_dir='./', config=cfg )
@ebernalg92 that worked!! Thank you so much, now it's super precise! But if it's not too difficult could you, please, explain, why?
Hey guys! I'm using Mask R CNN on a custom dataset, very simple: solid background and objects divided into 4 classes, more or less of the same size, in the same place in the image. The dataset is balanced, every class has exactly the same number of images in the train and in the test. However, regardless of any parameters, length of training, anything, it predicts me one class only. I have tried to increase the weight for the class prediction - and it is dropping with every epoch, but the predictions remain the same - I always get the class 1 , even if in fact there is class 4 or 3. Here is the configuration:
image_size = 256 rpn_anchor_template = (2, 4, 8, 16, 32) # anchor sizes in pixels rpn_anchor_scales = tuple(i * (image_size // 16) for i in rpn_anchor_template) class NewConfig(Config): NAME = "industry" GPU_COUNT = 1 IMAGES_PER_GPU = 2 NUM_CLASSES = len(subset)+1 IMAGE_MAX_DIM = image_size IMAGE_MIN_DIM = image_size RPN_ANCHOR_SCALES = rpn_anchor_scales TRAIN_ROIS_PER_IMAGE = 8 LOSS_WEIGHTS={'mrcnn_mask_loss': 1.0, 'rpn_class_loss': 5.0, 'mrcnn_class_loss': 5.0, 'mrcnn_bbox_loss': 1.0, 'rpn_bbox_loss': 2.0} STEPS_PER_EPOCH = 100 VALIDATION_STEPS = STEPS_PER_EPOCH / 10 def __init__(self, num_classes): self.NUM_CLASSES = num_classes super().__init__() config = NewConfig(num_classes=len(subset)+1) config.display()
Maybe there is something wrong here, because in the dataset the number of classes is correct.
Dear STASYA00
I want to use Mask-RCNN to train on my custom dataset (just one class).
First of all, I use Labelme to create groundtruth for each image. Each image has a .json file as its ground-truth.
After that, I don't know what should I do...
I want to know how to convert my groundtruth file to a format that Mask-rcnn can use. Do you have any tools ?
Looking forward to hearing from you, thanks in advance.
With best regards, Ming
@hjm1990818 If you have the json files as annotations, it should be enough. You can check in the Shapes and the Balloon samples, there is a class Dataset with the functions inside. You can copy it and change the functions a bit in order to take your input. I can give you my functions and if you still have problems, give me your telegram or email and I can help you.
# The function in the Dataset class that loads the information from the image
def load_image(self, dataset_dir, filename_annotation):
annotations = json.load(open(os.path.join(ANNO_DIR, filename_annotation)))
self.add_class('superclass', 1, 'class') # add all your classes with indices
for a in range(len(annotations['annotations'])):
if annotations['annotations'][a]['image_id'] in labels:
polygons = annotations['annotations'][a]['segmentation'] # information from your annotation json file
image_path = os.path.join(new_dataset_dir, annotations['images'][a]['file_name']) # path to load the image, from your annotation file
self.add_image(
'shoes', # dataset name
class_ids=annotations['annotations'][a]['category_id'], # which class the image belongs to
image_id=annotations['images'][a]['id'], # a unique image id
path=image_path,
width=annotations['images'][a]['width'],
height=annotations['images'][a]['height'],
polygons=polygons)
And then you also write a load_mask function that gets mask and class from your json and should return you a mask in a form of mask.astype(np.uint8) and class ids as np.array(class_ids,dtype=np.int32)
Basically that's it. And I would suggest you to put all the jsons in one json file and to load all the annotations from there directly. Then you do:
d=ShoeDataset()
d.load_image(DATA_DIR, filename_annotation) # add other arguments if you need them for your load_image function
d.prepare() # get dataset
Hi, everyone I still meet the same problem. I used VIA to annotate about 80 images. My environment is Tensorflow gpu 1.6 + python3.6, the training looks good and no error, the segmentation is also good enough. But every time, the model predicts the object is a cat with almost 100%. I do not know where is the problem. Hope for help, appreciate so much. My codes of test are shown below:
`import os import mrcnn.visualize import cv2 import time from mrcnn.config import Config
import mrcnn.model as modellib
from datetime import datetime
Root directory of the project
ROOT_DIR = os.getcwd()
Root directory of the project
Directory to save logs and trained model
MODEL_DIR = os.path.join(ROOT_DIR, "logs")
Local path to trained weights file
COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_balloon_0100.h5")
Download COCO trained weights from Releases if needed
Directory of images to run detection on
IMAGE_DIR = os.path.join(ROOT_DIR, "images2")
class_names = ['BG', 'cat', 'dog'] class SimpleConfig(mrcnn.config.Config): NAME = "balloon" GPU_COUNT = 1 IMAGES_PER_GPU = 1 NUM_CLASSES = len(class_names)
import mrcnn.model
Create model object in inference mode.
model = modellib.MaskRCNN(mode="inference", model_dir=MODEL_DIR, config=SimpleConfig())
#model = mrcnn.model.MaskRCNN(mode="inference", model_dir=ROOT_DIR, config=SimpleConfig())
model.load_weights(filepath=COCO_MODEL_PATH, by_name=True)
class_names = ['BG', 'cat', 'dog']
Load a random image from the images folder
image = cv2.imread(r'C:\Users\Owner\Downloads\Mask_RCNN-2.1\images2\test6.jpg') image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
r = model.detect([image], verbose=1)
r = r[0] #print(r)
mrcnn.visualize.display_instances(image=image, boxes=r['rois'], masks=r['masks'], class_ids=r['class_ids'], class_names=class_names, scores=r['scores'])`
Hey guys! I'm using Mask R CNN on a custom dataset, very simple: solid background and objects divided into 4 classes, more or less of the same size, in the same place in the image. The dataset is balanced, every class has exactly the same number of images in the train and in the test. However, regardless of any parameters, length of training, anything, it predicts me one class only. I have tried to increase the weight for the class prediction - and it is dropping with every epoch, but the predictions remain the same - I always get the class 1 , even if in fact there is class 4 or 3. Here is the configuration:
image_size = 256 rpn_anchor_template = (2, 4, 8, 16, 32) # anchor sizes in pixels rpn_anchor_scales = tuple(i * (image_size // 16) for i in rpn_anchor_template) class NewConfig(Config): NAME = "industry" GPU_COUNT = 1 IMAGES_PER_GPU = 2 NUM_CLASSES = len(subset)+1 IMAGE_MAX_DIM = image_size IMAGE_MIN_DIM = image_size RPN_ANCHOR_SCALES = rpn_anchor_scales TRAIN_ROIS_PER_IMAGE = 8 LOSS_WEIGHTS={'mrcnn_mask_loss': 1.0, 'rpn_class_loss': 5.0, 'mrcnn_class_loss': 5.0, 'mrcnn_bbox_loss': 1.0, 'rpn_bbox_loss': 2.0} STEPS_PER_EPOCH = 100 VALIDATION_STEPS = STEPS_PER_EPOCH / 10 def __init__(self, num_classes): self.NUM_CLASSES = num_classes super().__init__() config = NewConfig(num_classes=len(subset)+1) config.display()
Maybe there is something wrong here, because in the dataset the number of classes is correct.
Hi, i'm using Mask Rcnn for detection just one class , i habe some question how can i contact you , if you would like to help thanks