def build(self):
        super(ImageClassifier, self).build()

        classifier, self.preprocess_input = Classifiers.get(
            self.config.BACKBONE)
        base_model = classifier(input_shape=self.config.IMAGE_SHAPE,
                                include_top=True,
                                classes=self.config.NUM_CLASSES)

        for layer in base_model.layers:
            self.backbone_layer_names.append(layer.name)

        if self.config.MODE == 'training':
            input_label = Input(shape=[self.config.NUM_CLASSES],
                                name='input_label',
                                dtype=float)

            wfocal_loss_graph = weighted_focal_loss(
                self.config.CCE_WEIGHTS, self.config.FOCAL_LOSS_GAMMA)
            wfocal_loss = Lambda(lambda x: wfocal_loss_graph(*x), name='wfocal_loss') \
                ([input_label, base_model.output])

            inputs = base_model.inputs
            inputs += [input_label]
            outputs = base_model.outputs
            outputs += [wfocal_loss]
            model = Model(inputs, outputs, name=self.config.BACKBONE)

            return model
        else:
            return base_model
Beispiel #2
0
    def __init__(self,nClass,featureNames=["conv2_block5_0_relu","conv3_block9_0_relu","conv4_block26_0_relu"],dropoutRate=0.0,weights="imagenet",useScoreMapConnect=False,height=224,width=224):        
        self.dropoutRate=dropoutRate
        self.nUpConvo=2
        self.nDownConvo=2
        self.activation="relu"
        self.nClass=nClass
        self.softmaxLayers=[]
        self.E=[None]*4*3
        self.width=width
        self.height=height
        self.useScoreMapConnect=useScoreMapConnect
        classifier, preprocess_input = Classifiers.get('densenet169')
        self.preprocess=lambda x:preprocess_input(x*255)
        basemodel = classifier((height, width, 3), weights=weights)
        outputs=list(map(lambda x:basemodel.get_layer(x).output,featureNames))
        encoderModel=Model(inputs=[basemodel.input],outputs=outputs)

        input=Input(shape=(height,width,3))
        x=input     
        self.bigFeature,self.smallFeature,x=encoderModel(x)
        x=self.upBlock(x,0,0)
        x=self.upBlock(x,0,1)
        x=self.downBlock(x,1,1)
        x=self.downBlock(x,1,0)
        x=self.upBlock(x,2,0)
        x=self.upBlock(x,2,1)
        x=self.upBlock(x,3,2,compress=False)
        x=self.upBlock(x,3,2,compress=False)
        x=Conv2D(nClass, (3,3), kernel_initializer='he_normal', padding='same')(x)
        x = Activation('softmax',name="output")(x)
        self.softmaxLayers.append(x)        
        self.trainModel=Model(input,self.softmaxLayers)
        self.trainModel.summary()
        self.model=Model(input,x)
        self.model.summary()
Beispiel #3
0
    def __init__(self, name: str, size: int, preload_image: np.ndarray = None):
        classifier, preprocess_input = Classifiers.get(name)
        self.model = classifier((size, size, 3), weights='imagenet')
        self.preprocess_input = preprocess_input
        self.size = size

        if isinstance(preload_image, np.ndarray):
            self.classify(preload_image)
def data_generator(dataset: ClassificationDataset,
                   config,
                   batch_size,
                   shuffle=True):
    preprocess_input = Classifiers.get_preprocessing(config.BACKBONE)

    b = 0  # batch item index
    image_index = -1
    image_ids = np.arange(dataset.num_images)
    error_count = 0

    lock = threading.Lock()
    # Keras requires a generator to run indefinitely.
    while True:
        try:
            with lock:
                # Increment index to pick next image. Shuffle if at the start of an epoch.
                image_index = (image_index + 1) % len(image_ids)
                if shuffle and image_index == 0:
                    np.random.shuffle(image_ids)

                # Get GT bounding boxes and masks for image.
                image_id = image_ids[image_index]
                image = dataset.load_image(image_id)
                label = dataset.load_label(image_id)

                # Init batch arrays
                if b == 0:
                    batch_images = np.zeros((batch_size, ) + image.shape,
                                            dtype=np.float32)
                    batch_labels = np.zeros((batch_size, dataset.num_classes),
                                            dtype=np.float32)

                # Add to batch
                batch_images[b] = preprocess_input(image.astype(np.float32))
                batch_labels[b] = label.astype(np.float32)

                b += 1

                # Batch full?
                if b >= batch_size:
                    inputs = [batch_images, batch_labels]
                    outputs = []

                    yield inputs, outputs

                    # start a new batch
                    b = 0

        except (GeneratorExit, KeyboardInterrupt):
            raise
        except:
            # Log it and skip the image
            logging.exception("Error processing image {}".format(image_id))
            error_count += 1
            if error_count > 5:
                raise
def _test_application(name,
                      input_shape=(224, 224, 3),
                      last_dim=1000,
                      label='bull_mastiff'):
    classifier, preprocess_input = Classifiers.get(name)
    model = classifier(input_shape=input_shape, weights='imagenet')

    output_shape, preds = _get_output_shape(model, preprocess_input)
    assert output_shape == (None, last_dim)

    names = [p[1] for p in decode_predictions(preds)[0]]
    assert label in names[:3]
    def __build_convnet__(self):
        resnet, _ = Classifiers.get('resnet18')
        base_model = resnet(input_shape=(224, 224, 3),
                            include_top=False,
                            weights='imagenet')
        x = base_model.output
        x = GlobalAveragePooling2D()(x)
        x = Dense(4096, activation='relu')(x)
        x = Dropout(0.6)(x)
        x = Dense(4096, activation='relu')(x)
        x = Dropout(0.6)(x)
        x = Lambda(lambda x_: K.l2_normalize(x_, axis=1))(x)
        convnet_model = Model(inputs=base_model.input, outputs=x)

        self.convnet = convnet_model
def _test_save_load(name, input_shape=(224, 224, 3)):
    # create first model
    classifier, preprocess_input = Classifiers.get(name)
    model1 = classifier(input_shape=input_shape, weights=None)
    model1.save('model.h5')

    # load same model from file
    model2 = load_model('model.h5', compile=False)
    os.remove('model.h5')

    x = _get_img()
    y1 = model1.predict(x)
    y2 = model2.predict(x)

    assert np.allclose(y1, y2)
def make_model(network, input_shape, classes=6, predict_flag=0, drop_rate=0.3):
    classifier, _ = Classifiers.get(network)
    if predict_flag == 0:
        weights = 'imagenet'
    else:
        weights = None
    base_model = classifier(input_shape=input_shape,
                            weights=weights,
                            include_top=False)
    x = keras.layers.GlobalAveragePooling2D()(base_model.output)

    x = keras.layers.Dropout(drop_rate)(x)

    output = keras.layers.Dense(classes, activation='softmax')(x)
    model = keras.models.Model(inputs=[base_model.input], outputs=[output])

    return model
Beispiel #9
0
    def get_backbone_and_feature_layers(self, num_feature_layers):
        super(SemanticModelWrapper, self).build()
        image_shape = self.config.IMAGE_SHAPE
        classifier, self.preprocess_input = Classifiers.get(
            self.config.BACKBONE)
        backbone = classifier(input_shape=image_shape,
                              input_tensor=None,
                              weights=self.config.BACKBONE_WEIGHTS,
                              include_top=False)

        for layer in backbone.layers:
            self.backbone_layer_names.append(layer.name)

        if self.config.FEATURE_LAYERS == 'default':
            feature_layers = get_feature_layers(self.config.BACKBONE,
                                                n=num_feature_layers)
        else:
            feature_layers = self.config.FEATURE_LAYERS

        return backbone, feature_layers
def get_gpu_model(input_size=None,
                  activation=None,
                  initial_weights=None,
                  is_corruption=False):
    ResNet50v2, preprocess_input = Classifiers.get('resnet50v2')
    model = ResNet50v2(input_shape=input_size,
                       weights='imagenet',
                       classes=1,
                       include_top=False,
                       pooling='avg')
    model_inputs = model.inputs
    model_outsputs = model.output
    model_outsputs = Dense(128, activation='relu')(model_outsputs)
    model_outsputs = Dense(32, activation='relu')(model_outsputs)
    model_outsputs = Dense(1, activation=activation)(model_outsputs)
    model = Model(model_inputs, model_outsputs)
    model = multi_gpu_model(model, gpus=2)
    model.compile(loss=keras.losses.mean_squared_error,
                  optimizer=keras.optimizers.Adam())
    return model
Beispiel #11
0
def network(data, labels_one_hot, mode):
    model_name = S("model.classification_models.model")
    dataset = S("model.classification_models.dataset")

    # keras.backend.set_learning_phase(1 if mode==tf.estimator.ModeKeys.TRAIN else 0) # 0: Test(default), 1: Train
    keras.backend.set_learning_phase(0)  # 0: Test(default), 1: Train
    classifier, preprocess_input = Classifiers.get(model_name)

    # overwrite preprocess_input for mobilenet (workaround for a bug in keras_applications)
    if "mobilenet" in model_name:
        from keras.applications import imagenet_utils
        preprocess_input = lambda data: imagenet_utils.preprocess_input(
            data, mode='tf')

    # apply model
    data = preprocess_input(data)
    GLOBAL["keras_model_preprocess"] = preprocess_input
    model = classifier((224, 224, 3), input_tensor=data, weights=dataset)
    GLOBAL["keras_model"] = model
    logits = model.output

    # keras-models do not use empty-class
    logits = tf.concat([tf.expand_dims(logits[:, 0] * 0, 1), logits], axis=-1)
    return logits
Beispiel #12
0
def mold_image(images, backbone_name):
    if 'vgg' in backbone_name:
        return images.astype(np.float32) / 127.0 - 1.0
    else:
        preprocess_input = Classifiers.get_preprocessing(backbone_name)
        return preprocess_input(images)
def _test_application_notop(name, input_shape=(None, None, 3), last_dim=1024):
    classifier = Classifiers.get_classifier(name)
    model = classifier(input_shape=input_shape,
                       weights=None,
                       include_top=False)
    assert model.output_shape == (None, None, None, last_dim)
def test_imports(name):
    data = Classifiers.get(name)
    assert data is not None
import six
import random
import pytest
import logging
import numpy as np
import keras.backend as K

from skimage.io import imread
from keras.applications.imagenet_utils import decode_predictions
from keras.models import load_model
from classification_models import Classifiers

logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger()

MODELS = Classifiers.names()

RESNET_LIST = [
    ('resnet18', 512),
    ('resnet34', 512),
    ('resnet50', 2048),
    ('resnet101', 2048),
    ('resnet152', 2048),
]

SERESNET_LIST_1 = [
    ('seresnet18', 512),
    ('seresnet34', 512),
]

SERESNET_LIST_2 = [
Beispiel #16
0
        mask_bg = np.zeros(shape=(math.ceil((w - h) / 2), w), dtype=np.uint8)
        image = cv2.vconcat([image_bg, image, image_bg])
        mask = cv2.vconcat([mask_bg, mask, mask_bg])

    image = cv2.resize(image, (320, 320))
    mask = cv2.resize(mask, (320, 320))

    return image, mask


if MODEL_TYPE == 'classification':
    from classification_models import Classifiers
    from keras.layers import GlobalAveragePooling2D, Dense
    from keras.models import Model

    Vgg16, preprocess_input = Classifiers.get('vgg16')

    n_classes = 4

    # build model
    base_model = Vgg16(input_shape=(320, 320, 3),
                       weights='imagenet',
                       include_top=False)

    for layer in base_model.layers:
        layer.trainable = True

    global_avrg_pool = GlobalAveragePooling2D()(base_model.output)
    fc_1 = Dense(1024, activation='relu', name='fc_1')(global_avrg_pool)
    predictions = Dense(n_classes, activation='softmax',
                        name='predictions')(fc_1)
    elif modelname == "mobilenetv2":
        modelfile = "~/.keras/models/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_224.h5"
    elif modelname == "nasnetmobile":
        modelfile = "~/.keras/models/nasnet_mobile.h5"
    else:
        print("guessing modelfile from modelname")
if modelfile:
    modelfile = os.path.expanduser(modelfile)

# download graph
print("downloading model ", modelname)
import tensorflow as tf
from tensorflow import keras
import re
from classification_models import Classifiers
classifier, preprocess_input = Classifiers.get(modelname)
model = classifier((224, 224, 3), weights=dataset)

# actually builds the graph
data = tf.placeholder(shape=(None, 224, 224, 3), dtype=tf.float32)
logits = model(data)

# guess the modelfile
modeldir = os.path.expanduser("~/.keras/models")
if modelfile is None:
    modelfile = [f for f in os.listdir(modeldir)
                 if modelname + "_" in f]  #ignores the version-suffixes
    if len(modelfile) == 0:
        modelfile = [
            f for f in os.listdir(modeldir)
            if re.sub(r"v\d+$", "", modelname) in f
Beispiel #18
0
def get_backbone(name, *args, **kwargs):
    return Classifiers.get_classifier(name)(*args, **kwargs)
def build_maskrcnn(config):
    # Image size must be dividable by 2 multiple times
    if config.IMAGE_WIDTH % 64 != 0 and config.IMAGE_HEIGHT % 64 != 0:
        raise Exception('Image size must be dividable by 2 at least 6 times '
                        'to avoid fractions when downscaling and upscaling.'
                        'For example, use 256, 320, 384, 448, 512, ... etc. ')

    image_shape = config.IMAGE_SHAPE
    # Inputs
    input_image = Input(
        shape=image_shape, name='input_image')
    input_image_meta = Input(shape=[config.IMAGE_META_SIZE],
                             name='input_image_meta')

    classifier = Classifiers.get_classifier(config.BACKBONE)
    backbone = classifier(input_tensor=input_image,
                          input_shape=image_shape,
                          include_top=False,
                          weights=config.BACKBONE_WEIGHTS)

    backbone_layer_names = []
    for layer in backbone.layers:
        backbone_layer_names.append(layer.name)

    feature_layers = get_maskrcnn_feature_layers(config, backbone)

    # convert layer names to indices
    skip_connection_idx = ([get_layer_number(backbone, l) if isinstance(l, str) else l
                            for l in feature_layers])
    backbone_features = []
    for idx in skip_connection_idx:
        backbone_features.append(backbone.layers[idx].output)

    feature_pyramids = fpn_graph(backbone_features, config.TOP_DOWN_PYRAMID_SIZE)
    rpn_feature_maps = feature_pyramids
    mrcnn_feature_maps = feature_pyramids[:-1]

    # Anchors
    if config.MODE == 'training':
        anchors = get_anchors(config)
        # Duplicate across the batch dimension because Keras requires it
        # TODO: can this be optimized to avoid duplicating the anchors?
        anchors = np.broadcast_to(anchors, (config.BATCH_SIZE,) + anchors.shape)
        # A hack to get around Keras's bad support for constants
        anchors = Lambda(lambda x: tf.Variable(anchors), name='anchors')(input_image)
    else:
        # Anchors in normalized coordinates
        anchors = Input(shape=[None, 4], name='input_anchors')

    # RPN Model
    rpn = RegionProposalNet(config.RPN_ANCHOR_STRIDE,
                            len(config.RPN_ANCHOR_RATIOS), config.TOP_DOWN_PYRAMID_SIZE)

    # Loop through FPN outputs
    layer_outputs = []  # list of lists
    for p in rpn_feature_maps:
        layer_outputs.append(rpn([p]))

    # Concatenate layer outputs
    # Convert from list of lists of level outputs to list of lists
    # of outputs across levels.
    # e.g. [[a1, b1, c1], [a2, b2, c2]] => [[a1, a2], [b1, b2], [c1, c2]]
    output_names = ['rpn_class_logits', 'rpn_class', 'rpn_bbox']
    outputs = list(zip(*layer_outputs))
    outputs = [Concatenate(axis=1, name=n)(list(o))
               for o, n in zip(outputs, output_names)]

    '''
    input: (B, N, N, 3)
    anchors_per_location: len(config.RPN_ANCHOR_RATIOS)
    the coef: 341 / 4096 = (1/4)**2 + (1/8)**2 + (1/16)**2 + (1/32)**2 + (1/64)**2
        rpn_class_logits: (B, anchors_per_location * N * N * (341 / 4096), 2)
        rpn_class: (B, anchors_per_location * N * N * (341 / 4096), 2)
        rpn_bbox: (B, anchors_per_location * N * N * (341 / 4096), 4)

    '''
    rpn_class_logits, rpn_class, rpn_bbox = outputs

    # Generate proposals
    # Proposals are [batch, N, (y1, x1, y2, x2)] in normalized coordinates
    # and zero padded.
    proposal_count = config.POST_NMS_ROIS_TRAINING if config.MODE == 'training' \
        else config.POST_NMS_ROIS_INFERENCE
    rpn_rois = ProposalLayer(
        proposal_count=proposal_count,
        nms_threshold=config.RPN_NMS_THRESHOLD,
        name='ROI',
        config=config)([rpn_class, rpn_bbox, anchors])

    if config.MODE == 'training':
        # Create all the input layers
        # RPN GT
        input_rpn_match = Input(
            shape=[None, 1], name='input_rpn_match', dtype=tf.int32)
        input_rpn_bbox = Input(
            shape=[None, 4], name='input_rpn_bbox', dtype=tf.float32)

        # Detection GT (class IDs, bounding boxes, and masks)
        # 1. GT Class IDs (zero padded)
        input_gt_class_ids = Input(
            shape=[None], name='input_gt_class_ids', dtype=tf.int32)
        # 2. GT Boxes in pixels (zero padded)
        # [batch, MAX_GT_INSTANCES, (y1, x1, y2, x2)] in image coordinates
        input_gt_boxes = Input(
            shape=[None, 4], name='input_gt_boxes', dtype=tf.float32)
        # Normalize coordinates
        gt_boxes = Lambda(lambda x: norm_boxes_graph(
            x, shape(input_image)[1:3]))(input_gt_boxes)
        # 3. GT Masks (zero padded)
        # [batch, height, width, MAX_GT_INSTANCES]
        if config.USE_MINI_MASK:
            input_gt_masks = Input(
                shape=[config.MINI_MASK_SHAPE[0],
                       config.MINI_MASK_SHAPE[1], None],
                name='input_gt_masks', dtype=bool)
        else:
            input_gt_masks = Input(
                shape=[image_shape[0], image_shape[1], None],
                name='input_gt_masks', dtype=bool)

        # Class ID mask to mark class IDs supported by the dataset the image
        # came from.
        active_class_ids = Lambda(
            lambda x: parse_image_meta_graph(x)['active_class_ids']
        )(input_image_meta)

        # Generate detection targets
        # Subsamples proposals and generates target outputs for training
        # Note that proposal class IDs, gt_boxes, and gt_masks are zero
        # padded. Equally, returned rois and targets are zero padded.
        rois, target_class_ids, target_bbox, target_mask = \
            DetectionTargetLayer(config, name='proposal_targets')([
                rpn_rois, input_gt_class_ids, gt_boxes, input_gt_masks])

        # Network Heads
        # TODO: verify that this handles zero padded ROIs
        mrcnn_class_logits, mrcnn_class, mrcnn_bbox = \
            mrcnn_classifier_graph(rois, mrcnn_feature_maps, input_image_meta,
                                   config.POOL_SIZE, config.NUM_CLASSES,
                                   fc_layers_size=config.FPN_CLASSIF_FC_LAYERS_SIZE)

        mrcnn_mask = mrcnn_mask_graph(rois, mrcnn_feature_maps,
                                      input_image_meta,
                                      config.MASK_POOL_SIZE,
                                      config.NUM_CLASSES)

        # TODO: clean up (use tf.identify if necessary)
        output_rois = Lambda(lambda x: x * 1, name='output_rois')(rois)

        # Losses
        rpn_class_loss = Lambda(lambda x: rpn_class_loss_graph(*x), name='rpn_class_loss')(
            [input_rpn_match, rpn_class_logits])
        rpn_bbox_loss = Lambda(lambda x: rpn_bbox_loss_graph(config, *x), name='rpn_bbox_loss')(
            [input_rpn_bbox, input_rpn_match, rpn_bbox])
        class_loss = Lambda(lambda x: mrcnn_class_loss_graph(*x), name='mrcnn_class_loss')(
            [target_class_ids, mrcnn_class_logits, active_class_ids])
        bbox_loss = Lambda(lambda x: mrcnn_bbox_loss_graph(*x), name='mrcnn_bbox_loss')(
            [target_bbox, target_class_ids, mrcnn_bbox])
        mask_loss = Lambda(lambda x: mrcnn_mask_loss_graph(*x), name='mrcnn_mask_loss')(
            [target_mask, target_class_ids, mrcnn_mask])

        # Model
        inputs = [input_image, input_image_meta,
                  input_rpn_match, input_rpn_bbox, input_gt_class_ids, input_gt_boxes, input_gt_masks]
        outputs = [rpn_class_logits, rpn_class, rpn_bbox,
                   mrcnn_class_logits, mrcnn_class, mrcnn_bbox, mrcnn_mask,
                   rpn_rois, output_rois,
                   rpn_class_loss, rpn_bbox_loss, class_loss, bbox_loss, mask_loss]
        model = Model(inputs, outputs, name='maskrcnn')
    else:
        # Network Heads
        # Proposal classifier and BBox regressor heads
        mrcnn_class_logits, mrcnn_class, mrcnn_bbox = \
            mrcnn_classifier_graph(rpn_rois, mrcnn_feature_maps, input_image_meta,
                                   config.POOL_SIZE, config.NUM_CLASSES,
                                   fc_layers_size=config.FPN_CLASSIF_FC_LAYERS_SIZE)

        # Detections
        # output is [batch, num_detections, (y1, x1, y2, x2, class_id, score)] in
        # normalized coordinates
        detections = DetectionLayer(config, name='mrcnn_detection')(
            [rpn_rois, mrcnn_class, mrcnn_bbox, input_image_meta])

        # Create masks for detections
        detection_boxes = Lambda(lambda x: x[..., :4])(detections)
        mrcnn_mask = mrcnn_mask_graph(detection_boxes, mrcnn_feature_maps,
                                      input_image_meta,
                                      config.MASK_POOL_SIZE,
                                      config.NUM_CLASSES)

        model = Model([input_image, input_image_meta, anchors],
                      [detections, mrcnn_class, mrcnn_bbox,
                       mrcnn_mask, rpn_rois, rpn_class, rpn_bbox],
                      name='maskrcnn')

    return model, backbone_layer_names
def main():
    tf.keras.backend.set_image_data_format('channels_last')
    train_input_dataset = input_fn(
      mode='train',
      is_training=True,
      batch_size=args.batch_size,
      num_epochs=args.n_epochs,
      parse_record_fn=parse_record)
    
    val_input_dataset = input_fn(
      mode='val',
      is_training=False,
      batch_size=args.batch_size,
      num_epochs=args.n_epochs,
      parse_record_fn=parse_record)
    
    test_input_dataset = input_fn(
      mode='test',
      is_training=False,
      batch_size=args.batch_size,
      num_epochs=args.n_epochs,
      parse_record_fn=parse_record)

    optimizer = tf.keras.optimizers.SGD(lr=args.lr, momentum=0.9)
    if args.resnet_size == 18 and args.pretrained:
        classifier, _ = Classifiers.get('resnet18')
        base_model = classifier(input_shape=(224,224,3), weights='imagenet', include_top=True)
        new_layer = tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')
        model = tf.keras.models.Model(base_mode.input, new_layer(base_model.layers[-1].output))
    if args.resnet_size == 18:
        print('USING RESNET18')
        model = ResNet18(input_shape=(args.image_size, args.image_size, 3), classes=NUM_CLASSES)
        model_to_save = ResNet18(input_shape=(jr_main.HEIGHT, jr_main.WIDTH, 3), classes=NUM_CLASSES)
    elif args.resnet_size == 50 and not args.pretrained:
        print('USING RESNET50')
        model = ResNet50(input_shape=(args.image_size, args.image_size, 3), classes=NUM_CLASSES)
        model_to_save = ResNet50(input_shape=(args.image_size,args.image_size, 3), classes=NUM_CLASSES)
    elif args.resnet_size == 50 and args.pretrained:
        print('using pretrained resnet50')
        temp_model = tf.keras.applications.ResNet50(include_top=True, weights='imagenet', input_tensor=None, input_shape=(224,224, 3))
        temp_model.layers.pop()
        new_layer = tf.keras.layers.Dense(NUM_CLASSES, activation='softmax')
        model = tf.keras.models.Model(temp_model.input, new_layer(temp_model.layers[-1].output))

    else:
        print('Need to specifcy resnet18 or 50!')
        sys.exit(0)


    model.compile(loss='categorical_crossentropy',
                  optimizer=optimizer,
                  metrics=['categorical_accuracy', single_class_accuracy(0), 
                    single_class_accuracy(1), single_class_accuracy(2), mean_per_class_accuracy])
    #time_callback, tensorboard_callback, lr_callback = keras_common.get_callbacks(
     # learning_rate_schedule, NUM_IMAGES['train'])
    tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=args.checkpoint_dir)
    time_callback = TimeHistory(args.batch_size, log_steps=100)
    lr_callback = tf.keras.callbacks.LearningRateScheduler(step_decay)
    #lr_callback = LearningRateBatchScheduler(learning_rate_schedule, batch_size=args.batch_size, num_images=NUM_IMAGES['train'])
    
    checkpoint_path = os.path.join(args.checkpoint_dir, 'checkpoint.h5')
    cp_callback = tf.keras.callbacks.ModelCheckpoint(
            checkpoint_path, monitor='val_mean_per_class_accuracy', verbose=1, save_best_only=True, save_weights_only=True, period=1)

    num_train_steps = NUM_IMAGES['train'] // args.batch_size
    num_val_steps = NUM_IMAGES['validation'] // args.batch_size
    num_test_steps = NUM_IMAGES['test'] // args.batch_size

    history = model.fit(train_input_dataset,
                      epochs=args.n_epochs,
                      steps_per_epoch=num_train_steps,
                      callbacks=[
                          time_callback,
                          lr_callback,
                          tensorboard_callback,
                          cp_callback,
                      ],
                      validation_steps=num_val_steps,
                      validation_data=val_input_dataset,
                      verbose=2,
                      workers=4)
    
    print('TESTING')
    test_output = model.evaluate(test_input_dataset,
                                 steps=num_test_steps,
                                 verbose=1)
    stats = build_stats(history, eval_output, time_callback)
    print('loading weights from best checkpoint')
    model_to_save.load_weights(checkpoint_path)
    print('saving final model')
    model_to_save.save('{}_final.h5'.format(checkpoint_path.split('/')[-2]))

    print('\nstats: ', stats)
Beispiel #21
0
def data_generator(dataset, config, shuffle=True, batch_size=1):
    """A generator that returns images and corresponding target class ids,
    bounding box deltas, and masks.

    dataset: The Dataset object to pick data from
    config: The model config object
    shuffle: If True, shuffles the samples before every epoch
    batch_size: How many images to return in each call

    Returns a Python generator. Upon calling next() on it, the
    generator returns two lists, inputs and outputs. The contents
    of the lists differs depending on the received arguments:
    inputs list:
    - images: [batch, H, W, C]
    - gt_mask: [batch, height, width, NUM_CLASSES]. The height and width
                are those of the image and NUM_CLASSES doesn't include background

    outputs list: empty
    """
    b = 0  # batch item index
    image_index = -1
    image_ids = np.copy(dataset.image_ids)
    error_count = 0

    preprocess_input = Classifiers.get_preprocessing(config.BACKBONE)
    lock = threading.Lock()
    # Keras requires a generator to run indefinitely.
    while True:
        try:
            with lock:
                # Increment index to pick next image. Shuffle if at the start of an epoch.
                image_index = (image_index + 1) % len(image_ids)
                if shuffle and image_index == 0:
                    np.random.shuffle(image_ids)

                # Get GT bounding boxes and masks for image.
                image_id = image_ids[image_index]
                image, gt_mask = load_image_gt(dataset, image_id,
                                               config.IMAGE_SHAPE,
                                               config.USE_MINI_MASK,
                                               config.MINI_MASK_SHAPE)

                # Init batch arrays
                if b == 0:
                    batch_images = np.zeros((batch_size, ) + image.shape,
                                            dtype=np.float32)
                    batch_gt_mask = np.zeros(
                        (batch_size, gt_mask.shape[0], gt_mask.shape[1],
                         config.NUM_CLASSES - 1),
                        dtype=gt_mask.dtype)

                # Add to batch
                batch_images[b] = preprocess_input(image.astype(np.float32))
                batch_gt_mask[b, :, :, :] = gt_mask

                b += 1

                # Batch full?
                if b >= batch_size:
                    inputs = [batch_images, batch_gt_mask]
                    outputs = []

                    yield inputs, outputs

                    # start a new batch
                    b = 0

        except (GeneratorExit, KeyboardInterrupt):
            raise
        except:
            # Log it and skip the image
            logging.exception("Error processing image {}".format(image_id))
            error_count += 1
            if error_count > 5:
                raise
Beispiel #22
0
def get_preprocessing(name):
    return Classifiers.get_preprocessing(name)
from classification_models import Classifiers

from data_generators.utils import resize, load_image_rgb

# Parse command line arguments
parser = argparse.ArgumentParser(
    description='Imagenet classification example.')
parser.add_argument('-b',
                    '--backbone',
                    required=True,
                    metavar='backbone model name',
                    help='The name of the backbone architecture')
args = parser.parse_args()

backbone = args.backbone
classifier, preprocess_input = Classifiers.get(backbone)

# load model
model = classifier(input_shape=(224, 224, 3),
                   include_top=True,
                   weights='imagenet')

image_files = ['cat1.jpg', 'cat2.jpg', 'dog1.jpg', 'dog2.jpg']
print('=============results=============')
for image_file in image_files:
    # read and prepare image
    img = load_image_rgb(image_file)
    x = resize(img, (224, 224), preserve_range=True)
    x = preprocess_input(x)
    x = np.expand_dims(x, 0)