0

I'm trying to detect 5 classes of weed species with mask rcnn, but I only get loss: nan - val_loss: nan in mask_rcnn during training, I already tried to change the value of learning hate but I always got the same result. Below I will leave my code, i'll also leave an example of how the .xml is organized

class WeedsDataset(Dataset):
    def load_dataset(self, dataset_dir, is_train=True):
        # define classes
        self.add_class("dataset", 1, "vassourinha")
        self.add_class("dataset", 2, "agriaozinho")
        self.add_class("dataset", 3, "capim_amargoso")
        self.add_class("dataset", 4, "mastruco")
        self.add_class("dataset", 5, "coqueiro")
        
        # define data locations
        images_dir = dataset_dir + '/images/'
        annotations_dir = dataset_dir + '/anotations/'
        
        # find all images
        for filename in listdir(images_dir):
            #print(filename)
            # extract image id
            image_id = filename[:-4]
            #print('IMAGE ID: ',image_id)
            
            if is_train and int(image_id) >= 500:
                continue
            # skip all images before 115 if we are building the test/val set
            if not is_train and int(image_id) < 500:
                continue
            img_path = images_dir + filename
            ann_path = annotations_dir + image_id + '.xml'
            # add to dataset
            self.add_image('dataset', image_id=image_id, path=img_path, annotation=ann_path, class_ids = [0,1,2,3,4,5])
            
    # extract bounding boxes from an annotation file               
    def extract_boxes(self, filename):
        # load and parse the file
        tree = ElementTree.parse(filename)
        # get the root of the document
        root = tree.getroot()
        # extract each bounding box
        boxes = list()
        for box in root.findall('.//object'):
            name = box.find('name').text   #Add label name to the box list
            xmin = int(box.find('./bndbox/xmin').text)
            xmax = int(box.find('./bndbox/xmax').text)
            ymin = int(box.find('./bndbox/ymin').text)
            ymax = int(box.find('./bndbox/ymax').text)
            coors = [xmin, ymin, xmax, ymax, name]
            boxes.append(coors)
        # extract image dimensions
        width = int(root.find('.//size/width').text)
        height = int(root.find('.//size/height').text)
        return boxes, width, height
    
    # load the masks for an image
    def load_mask(self, image_id):
        # get details of image
        info = self.image_info[image_id]
        # define box file location
        path = info['annotation']
        #return info, path
        
        
        # load XML
        boxes, w, h = self.extract_boxes(path)
        # create one array for all masks, each on a different channel
        masks = zeros([h, w, len(boxes)], dtype='uint8')
        # create masks
        class_ids = list()
        for i in range(len(boxes)):
            box = boxes[i]
            row_s, row_e = box[1], box[3]
            col_s, col_e = box[0], box[2]
            
            
            # box[4] will have the name of the class 
            if (box[4] == 'vassourinha'):
                masks[row_s:row_e, col_s:col_e, i] = 1
                class_ids.append(self.class_names.index('vassourinha'))
            elif(box[4] == 'agriaozinho'):
                masks[row_s:row_e, col_s:col_e, i] = 2
                class_ids.append(self.class_names.index('agriaozinho')) 
            elif(box[4] == 'capim_amargoso'):
                masks[row_s:row_e, col_s:col_e, i] = 3
                class_ids.append(self.class_names.index('capim_amargoso'))
            elif(box[4] == 'mastruco'):
                masks[row_s:row_e, col_s:col_e, i] = 4
                class_ids.append(self.class_names.index('mastruco'))
            elif(box[4] == 'coqueiro'):
                masks[row_s:row_e, col_s:col_e, i] = 5
                class_ids.append(self.class_names.index('coqueiro'))
                
        return masks, asarray(class_ids, dtype='int32')
    
    # load an image reference
    def image_reference(self, image_id):
        info = self.image_info[image_id]
        return info['path']
    
# train set
dataset_dir='C:/TCC Gelson/xml_proj.v1i.voc/train_backup'

train_set = WeedsDataset()
train_set.load_dataset(dataset_dir, is_train=True)
train_set.prepare()
print('Train: %d' % len(train_set.image_ids))

# test/val set
test_set = WeedsDataset()
test_set.load_dataset(dataset_dir, is_train=False)
test_set.prepare()
print('Test: %d' % len(test_set.image_ids))

import random
num=random.randint(0, len(train_set.image_ids))
# define image id
image_id = num
# load the image
image = train_set.load_image(image_id)
# load the masks and the class ids
mask, class_ids = train_set.load_mask(image_id)
# extract bounding boxes from the masks
bbox = extract_bboxes(mask)
# display image with masks and bounding boxes
display_instances(image, bbox, mask, class_ids, train_set.class_names)

# define a configuration for the model
class WeedsConfig(Config):
 
    NAME = "weeds_cfg"
    GPU_COUNT = 1
    IMAGES_PER_GPU = 1
   NUM_CLASSES = 1 + 5
    LEARNING_RATE = 0.0025
    
    
# prepare config
config = WeedsConfig()
config.display()

# define the model
model = MaskRCNN(mode='training', model_dir=MODEL_DIR, config=config)
# load weights (mscoco) and exclude the output layers
model.load_weights("C:/TCC Gelson/xml_proj.v1i.voc/train_backup/weights/mask_rcnn_coco.h5", by_name=True, exclude=["mrcnn_class_logits", "mrcnn_bbox_fc",  "mrcnn_bbox", "mrcnn_mask"])

# train weights (output layers or 'heads')
model.train(train_set, test_set, learning_rate=config.LEARNING_RATE, epochs=5, layers='heads')

# change directory to logs directory
os.chdir(DEFAULT_LOGS_DIR)

# save weights
model_path = 'Weeds_mask_rcnn.h5'
model.keras_model.save_weights(model_path)

xml file

output

0 Answers0