Skip to content

Commit

Permalink
Changes in model.py and annotations. added attribute annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian committed Nov 10, 2020
1 parent 8708258 commit cc776a6
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 3,134 deletions.
4 changes: 2 additions & 2 deletions datasets/feather_damage/train/coco_annotations.json
Original file line number Diff line number Diff line change
Expand Up @@ -487065,10 +487065,10 @@
],
"categories": [
{
"id": 0,
"id": 1,
"name": "Hen",
"supercategory": "root"
}
],
"tag_categories": []
}
}
4 changes: 2 additions & 2 deletions datasets/feather_damage/val/coco_annotations.json
Original file line number Diff line number Diff line change
Expand Up @@ -487065,10 +487065,10 @@
],
"categories": [
{
"id": 0,
"id": 1,
"name": "Hen",
"supercategory": "root"
}
],
"tag_categories": []
}
}
5 changes: 1 addition & 4 deletions mrcnn/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1240,7 +1240,6 @@ def load_image_gt(dataset, config, image_id, augmentation=None):
max_dim=config.IMAGE_MAX_DIM,
mode=config.IMAGE_RESIZE_MODE)
mask = utils.resize_mask(mask, scale, padding, crop)
print(image.shape)

# Augmentation
# This requires the imgaug lib (https://github.com/aleju/imgaug)
Expand Down Expand Up @@ -1683,7 +1682,7 @@ def __init__(self, dataset, config, shuffle=True, augmentation=None,
random_rois=0, detection_targets=False):
print("Datagenerator called")
self.image_ids = np.copy(dataset.image_ids)
print(self.image_ids)
#print(self.image_ids)
self.dataset = dataset
self.config = config

Expand All @@ -1703,8 +1702,6 @@ def __init__(self, dataset, config, shuffle=True, augmentation=None,
self.detection_targets = detection_targets

def __len__(self):
print("Length:")
print(int(np.ceil(len(self.image_ids) / float(self.batch_size))))
return int(np.ceil(len(self.image_ids) / float(self.batch_size)))

def __getitem__(self, idx):
Expand Down
1 change: 1 addition & 0 deletions mrcnn/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ def load_mask(self, image_id):
logging.warning("You are using the default load_mask(), maybe you need to define your own one.")
mask = np.empty([0, 0, 0])
class_ids = np.empty([0], np.int32)
print(mask)
return mask, class_ids


Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ tensorflow>=2.0.0
opencv-python
h5py
imgaug
IPython[all]
IPython[all]
232 changes: 232 additions & 0 deletions samples/feather_damage/training.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import os
import sys
import json
import numpy as np
import time
from PIL import Image, ImageDraw

# Set the ROOT_DIR variable to the root directory of the Mask_RCNN git repo
ROOT_DIR = '../../'
assert os.path.exists(ROOT_DIR), 'ROOT_DIR does not exist. Did you forget to read the instructions above? ;)'

# Import mrcnn libraries
sys.path.append(ROOT_DIR)
from mrcnn.config import Config
import mrcnn.utils as utils
from mrcnn import visualize
import mrcnn.model as modellib

# Directory to save logs and trained model
MODEL_DIR = "/media/christian/SamsungSSD/tensorflow_logs/"

# Local path to trained weights file
COCO_MODEL_PATH = os.path.join(ROOT_DIR, "mask_rcnn_coco.h5")

# Download COCO trained weights from Releases if needed
if not os.path.exists(COCO_MODEL_PATH):
utils.download_trained_weights(COCO_MODEL_PATH)

class CigButtsConfig(Config):
"""Configuration for training on the cigarette butts dataset.
Derives from the base Config class and overrides values specific
to the cigarette butts dataset.
"""
# Give the configuration a recognizable name
NAME = "feather__damage"

# Train on 1 GPU and 1 image per GPU. Batch size is 1 (GPUs * images/GPU).
GPU_COUNT = 1
IMAGES_PER_GPU = 1

# Number of classes (including background)
NUM_CLASSES = 1 + 2 # background + 2 (feather damage + no feather damage)

# All of our training images are 512x512
IMAGE_MIN_DIM = None
IMAGE_MAX_DIM = 512 # must be dividable by 2 at least 6 times

# You can experiment with this number to see if it improves training
STEPS_PER_EPOCH = 50 # 500

# This is how often validation is run. If you are using too much hard drive space
# on saved models (in the MODEL_DIR), try making this value larger.
VALIDATION_STEPS = 10 # 5

# Matterport originally used resnet101, but I downsized to fit it on my graphics card
BACKBONE = 'resnet50'

# To be honest, I haven't taken the time to figure out what these do
RPN_ANCHOR_SCALES = (8, 16, 32, 64, 128)
TRAIN_ROIS_PER_IMAGE = 32
MAX_GT_INSTANCES = 20
POST_NMS_ROIS_INFERENCE = 500
POST_NMS_ROIS_TRAINING = 1000

config = CigButtsConfig()
config.display()

class CocoLikeDataset(utils.Dataset):
""" Generates a COCO-like dataset, i.e. an image dataset annotated in the style of the COCO dataset.
See http://cocodataset.org/#home for more information.
"""
def load_data(self, annotation_json, images_dir):
""" Load the coco-like dataset from json
Args:
annotation_json: The path to the coco annotations json file
images_dir: The directory holding the images referred to by the json file
"""
# Load json from file
json_file = open(annotation_json)
coco_json = json.load(json_file)
json_file.close()

# Add the class names using the base method from utils.Dataset
source_name = "coco_like"
for category in coco_json['categories']:
class_id = category['id']
class_name = category['name']
if class_id < 1:
print('Error: Class id for "{}" cannot be less than one. (0 is reserved for the background)'.format(class_name))
return

self.add_class(source_name, class_id, class_name)

# Get all annotations
annotations = {}
for annotation in coco_json['annotations']:
image_id = annotation['image_id']
if image_id not in annotations:
annotations[image_id] = []
annotations[image_id].append(annotation)

# Get all images and add them to the dataset
seen_images = {}
for image in coco_json['images']:
image_id = image['id']
if image_id in seen_images:
print("Warning: Skipping duplicate image id: {}".format(image))
else:
seen_images[image_id] = image
try:
#image_file_name = format(image['id'], '08d')+"_"+image['file_name']
image_file_name = image['file_name']
image_width = image['width']
image_height = image['height']
except KeyError as key:
print("Warning: Skipping image (id: {}) with missing key: {}".format(image_id, key))

image_path = os.path.abspath(os.path.join(images_dir, image_file_name))
image_annotations = annotations[image_id]
hasCrowd = False # Quick fix to avoid problems with "count" annotations. If more than 1segmentation/object -> skip image
for element in image_annotations:
if element['iscrowd']:
hasCrowd = True

# Add the image using the base method from utils.Dataset (if file exists)
if os.path.isfile(image_path):
if not hasCrowd:
self.add_image(
source=source_name,
image_id=image_id,
path=image_path,
width=image_width,
height=image_height,
annotations=image_annotations
)


def load_mask(self, image_id):
""" Load instance masks for the given image.
MaskRCNN expects masks in the form of a bitmap [height, width, instances].
Args:
image_id: The id of the image to load masks for
Returns:
masks: A bool array of shape [height, width, instance count] with
one mask per instance.
class_ids: a 1D array of class IDs of the instance masks.
"""
image_info = self.image_info[image_id]
annotations = image_info['annotations']
instance_masks = []
class_ids = []

for annotation in annotations:
class_id = annotation['category_id']
mask = Image.new('1', (image_info['width'], image_info['height']))
mask_draw = ImageDraw.ImageDraw(mask, '1')
for segmentation in annotation['segmentation']:
mask_draw.polygon(segmentation, fill=1)
bool_array = np.array(mask) > 0
instance_masks.append(bool_array)
class_ids.append(class_id)

mask = np.dstack(instance_masks)
class_ids = np.array(class_ids, dtype=np.int32)

return mask, class_ids

dataset_train = CocoLikeDataset()
dataset_train.load_data('/media/christian/SamsungSSD/ZED/datasets/900_images/attribute_annotations.json', '/media/christian/SamsungSSD/ZED/datasets/900_images/train/')
dataset_train.prepare()

dataset_val = CocoLikeDataset()
dataset_val.load_data('/media/christian/SamsungSSD/ZED/datasets/900_images/attribute_annotations.json', '/media/christian/SamsungSSD/ZED/datasets/900_images/val/')
dataset_val.prepare()

print(dataset_train)
#dataset = dataset_train
#image_ids = np.random.choice(dataset.image_ids, 4)
#for image_id in image_ids:
# image = dataset.load_image(image_id)
# #print(image.shape)
# mask, class_ids = dataset.load_mask(image_id)
# visualize.display_top_masks(image, mask, class_ids, dataset.class_names)

#### Training ####

# Create model in training mode
model = modellib.MaskRCNN(mode="training", config=config,
model_dir=MODEL_DIR)

# Which weights to start with?
init_with = "coco" # imagenet, coco, or last

if init_with == "imagenet":
model.load_weights(model.get_imagenet_weights(), by_name=True)
elif init_with == "coco":
# Load weights trained on MS COCO, but skip layers that
# are different due to the different number of classes
# See README for instructions to download the COCO weights
model.load_weights(COCO_MODEL_PATH, by_name=True,
exclude=["mrcnn_class_logits", "mrcnn_bbox_fc",
"mrcnn_bbox", "mrcnn_mask"])
elif init_with == "last":
# Load the last model you trained and continue training
model.load_weights(model.find_last(), by_name=True)

# Train the head branches
# Passing layers="heads" freezes all layers except the head
# layers. You can also pass a regular expression to select
# which layers to train by name pattern.

#start_train = time.time()
#model.train(dataset_train, dataset_val,
# learning_rate=config.LEARNING_RATE,
# epochs=10,
# layers='heads')
#end_train = time.time()
#minutes = round((end_train - start_train) / 60, 2)
#print(f'Training took {minutes} minutes')

# Fine tune all layers
# Passing layers="all" trains all layers. You can also
# pass a regular expression to select which layers to
# train by name pattern.
start_train = time.time()
model.train(dataset_train, dataset_val,
learning_rate=config.LEARNING_RATE / 10,
epochs=100,
layers="all")
end_train = time.time()
minutes = round((end_train - start_train) / 60, 2)
print(f'Training took {minutes} minutes')
32 changes: 0 additions & 32 deletions samples/nucleus/README.md

This file was deleted.

Loading

0 comments on commit cc776a6

Please sign in to comment.