def histogram_labels(dataset_name: str,
                     double_bins: bool = False,
                     show_labels: bool = False):
    """ Plot an histogram of the labels. double_bins allow to have have more space between bins in the plot """
    annotations_df = pd.read_csv(
        constants.ANNOTATIONS_TRAIN_CSV_PATH.format(dataset_name))
    # if use_label_name:
    labels_values = list(helpers.get_labels_dict(dataset_name).values())
    labels_ids = annotations_df['label'].unique()
    n_bins = len(labels_ids)
    if double_bins:
        n_bins *= 2
    fig, ax = plt.subplots()
    bins = np.arange(n_bins + 1) - 0.5
    counts, bins, patches = ax.hist(annotations_df['label'], bins=bins)
    plt.xlim([-1, n_bins])
    if show_labels:
        plt.xticks(range(n_bins))

        # Label below the x-axis...
        bin_centers = bins + 0.5
        i = 0
        for count, x in zip(counts, bin_centers):
            ax.annotate(labels_values[i], (x, 0),
                        xycoords=('data', 'axes fraction'),
                        xytext=(0, -18),
                        textcoords='offset points',
                        va='top',
                        ha='center',
                        rotation=-90)
            i += 1
        plt.subplots_adjust(bottom=0.15)
    plt.show()
示例#2
0
def detect(model,
           dataset_name: str,
           image_path: str,
           title: str = "",
           output_path: str = None):
    labels_map_dict = helpers.get_labels_dict(dataset_name)

    img = tf.image.decode_image(open(image_path, 'rb').read(), channels=3)
    img = tf.expand_dims(img, 0)
    img_shape = np.array(
        [img.shape[2], img.shape[1], img.shape[2], img.shape[1]])

    img = helpers.transform_images(img, model.image_res)
    boxes, scores, classes, nums = model.inference_model(img)
    boxes, scores, classes = [
        np.array(elem[0]) for elem in [boxes, scores, classes]
    ]
    annotations = []

    for object_index in range(nums[0]):
        bbox = [int(elem) for elem in list(boxes[object_index] * img_shape)]
        annotations.append(bbox + [int(classes[object_index])])
        print(constants.C_OKGREEN, 'Object',
              labels_map_dict[str(int(classes[object_index]))],
              'with probability', scores[object_index], 'is in',
              annotations[object_index][:-1], constants.C_ENDC)
    visualize.plot_image_annotations(image_path, annotations, labels_map_dict,
                                     scores, title, output_path)
    if len(annotations) == 0:
        print(constants.C_WARNING, "No object found.", title, constants.C_ENDC)
示例#3
0
def create_label_map_pbtxt(dataset_name: str):
    """ This kind of label map is used in the google models research repository """
    labels_dict = helpers.get_labels_dict(dataset_name)
    with open(constants.LABEL_MAP_PBTXT_PATH.format(dataset_name), 'a') as t:
        for key, value in labels_dict.items():
            id = str(
                int(key) + 1
            )  # pbtxt files are used in google models and they require id 0 to be background
            t.write("item {\n name: \"" + value + "\"\n id: " + id +
                    "\n display_name: \"" + value + "\"\n}\n")
def plot_image_annotations_simple(image_path: str, title: str = ""):
    """ the image file should finish with: /dataset_name/train_val_test/image"""
    info = image_path.split('/')
    dataset_name, train_val_test, image = info[-3:]
    annotations = helpers.get_annotations_dict(dataset_name,
                                               train_val_test)[image]
    labels_map_dict = helpers.get_labels_dict(dataset_name)
    plot_image_annotations(image_path,
                           annotations,
                           labels_map_dict,
                           title=title)
示例#5
0
    def __init__(self,
                 dataset_name: str,
                 img_res: int,
                 train: bool,
                 model_version: str,
                 train_cluster: bool = False):
        self.model_name = "Recognizer_" + model_version
        if dataset_name == '':
            self.dataset_name = 'FAKE'
            self.n_classes = 10
        else:
            self.dataset_name = dataset_name
            self.label_map_json_path = constants.LABEL_MAP_JSON_PATH.format(
                dataset_name)
            self.n_classes = helpers.get_n_classes(self.label_map_json_path)
            self.labels_map_dict = helpers.get_labels_dict(dataset_name)
        if train:
            self.checkpoints_path, self.logs_path, self.figs_path = helpers.model_directories(
                constants.RECOGNIZER, self.dataset_name, train_cluster)
        self.model_description = ''
        if model_version == 'mini':
            self.train_model = self.model_mini(img_res)
        elif model_version == 'mini_2':
            self.train_model = self.model_mini_2(img_res)
        elif model_version == 'kaggle':
            self.train_model = self.kaggle_model(img_res)
        elif model_version == 'mod':
            self.train_model = self.mod(img_res)
        elif model_version == 'mod_bn':
            self.train_model = self.mod_bn(img_res)
        elif model_version == 'mod_bn_reg':
            self.train_model = self.mod_bn_reg(img_res)
        elif model_version == 'v0':
            self.train_model = self.model_v0(img_res)
        elif model_version == 'v0.1':
            self.train_model = self.model_v0_1(img_res)
        elif model_version == 'v0.2':
            self.train_model = self.model_v0_2(img_res)
        elif model_version == 'v0.3':
            self.train_model = self.model_v0_3(img_res)
        elif model_version == 'v0.4':
            self.train_model = self.model_v0_4(img_res)
        elif model_version == 'v1':
            self.train_model = self.model_v1(img_res)
        elif model_version == 'v2':
            self.train_model = self.model_v2(img_res)
        elif model_version == 'v3':
            self.train_model = self.model_v3(img_res)

        self.img_res = img_res
        self.model_description += 'The model has {:,} parameters.'.format(
            self.train_model.count_params())
        self.inference_model = self.train_model
def plot_images_and_boxes(img,
                          boxes,
                          switch=False,
                          multi=True,
                          i=None,
                          title="",
                          dataset_name=None,
                          colors=None):
    if type(boxes) != np.ndarray:
        boxes = np.array(boxes)
    fig, ax = plt.subplots(1)
    ax.imshow(img)
    img_shape = np.array(
        [img.shape[1], img.shape[0], img.shape[1], img.shape[0]])
    if dataset_name:
        labels_map = helpers.get_labels_dict(dataset_name)

    labels = []
    colors = get_colors(boxes, labels)

    if switch:
        boxes[:, [0, 1, 2, 3]] = boxes[:, [1, 0, 3, 2]]

    for bbox in boxes:
        original = bbox
        if multi:
            bbox = [int(elem) for elem in list(bbox[:4] * img_shape)
                    ] + ([int(bbox[-1])] if len(bbox) == 5 else [])
        if np.sum(bbox[:4]) == 0:
            continue
        # print("Box added:", bbox, "original", original)
        rect = patches.Rectangle((bbox[0], bbox[1]),
                                 bbox[2] - bbox[0],
                                 bbox[3] - bbox[1],
                                 linewidth=1,
                                 edgecolor=colors[labels.index(bbox[-1])],
                                 facecolor='none')
        if dataset_name and len(bbox) == 5:
            add_label_to_plot(ax, colors[labels.index(bbox[-1])],
                              labels_map[str(bbox[-1])], bbox[0], bbox[1])

        plt.scatter(bbox[0], bbox[1], c='r', marker='x')
        plt.scatter(bbox[2], bbox[3], c='g', marker='x')
        ax.add_patch(rect)
    plt.title(title)
    if i is not None:
        plt.savefig('{:03d}.png'.format(i))
    plt.show()
    if i is not None:
        return i + 1
    else:
        return i
示例#7
0
 def __init__(self,
              dataset_name: str,
              img_res: int,
              train: bool,
              model_name: str = "Recognizer"):
     self.model_name = model_name
     if dataset_name == '' or dataset_name == 'FAKE':
         self.dataset_name = 'FAKE'
         self.n_classes = 10
     else:
         self.dataset_name = dataset_name
         self.label_map_json_path = constants.LABEL_MAP_JSON_PATH.format(
             dataset_name)
         self.n_classes = helpers.get_n_classes(self.label_map_json_path)
         self.labels_map_dict = helpers.get_labels_dict(dataset_name)
     if train:
         self.checkpoints_path, self.logs_path, self.figs_path = helpers.model_directories(
             model_name, self.dataset_name)
     self.img_res = img_res
     leaky_relu = lambda x: tf.keras.activations.relu(x, alpha=0.1)
     self.train_model = tf.keras.models.Sequential([
         Conv2D(filters=32,
                kernel_size=(5, 5),
                kernel_regularizer=l2(0.0005),
                activation=leaky_relu,
                input_shape=(img_res, img_res, 3)),
         BatchNormalization(),
         MaxPool2D(pool_size=(2, 2)),
         Conv2D(filters=64,
                kernel_size=(3, 3),
                activation=leaky_relu,
                kernel_regularizer=l2(0.0005)),
         MaxPool2D(pool_size=(2, 2)),
         Dropout(rate=0.25),
         Conv2D(filters=64,
                kernel_size=(3, 3),
                activation=leaky_relu,
                kernel_regularizer=l2(0.0005)),
         MaxPool2D(pool_size=(2, 2)),
         Dropout(rate=0.25),
         Conv2D(filters=128,
                kernel_size=(1, 1),
                activation=leaky_relu,
                kernel_regularizer=l2(0.0005)),
         Dropout(rate=0.5),
         Flatten(),
         Dense(self.n_classes, 'softmax')
     ])
     self.inference_model = self.train_model
     self.model_description = 'The model has {:,} parameters.'.format(
         self.train_model.count_params())
示例#8
0
 def __init__(self, dataset_name: str, tiny: bool = True):
     if dataset_name == '':
         self.dataset_name = 'FAKE'
         self.n_classes = 80
         self.tiny = tiny
         print(constants.C_OKBLUE, "FAKE dataset created", constants.C_ENDC)
         return
     self.dataset_name = dataset_name
     self.label_map_json_path = constants.LABEL_MAP_JSON_PATH.format(dataset_name)
     self.tf_paths = constants.PROCESSED_PROJECT_FOLDER_PATH + constants.TFRECORDS_PATH
     self.n_classes = helpers.get_n_classes(self.label_map_json_path)
     self.labels_map_dict = helpers.get_labels_dict(dataset_name)
     self.train_data, self.validation_data, self.test_data = None, None, None
     self.image_res, self.loading_train = None, None  # To be defined when called load_datasets
     print(constants.C_OKBLUE, "Dataset", dataset_name, "created", constants.C_ENDC)
def load_tensorboard_image(image, groundtruth_ann: list, annotations: list,
                           probs: list, dataset_name: str):
    labels_map_dict = helpers.get_labels_dict(dataset_name)
    # Create figure and axes
    fig, ax = plt.subplots(1)
    labels = []

    # Get the unique labels to assign a color to each
    colors = get_colors(groundtruth_ann + annotations, labels)
    separation = 10
    # Concatenate the same image with a white space in between
    new_image = np.concatenate((image, 255 * np.ones(
        (image.shape[0], separation, 3)).astype(np.int32), image),
                               axis=1)
    # Load the original image with its groundtruth annotations
    ax.imshow(new_image)
    for i, bbox in enumerate(groundtruth_ann):
        if sum(bbox) == 0:
            continue
        plot_image_annotations_help(ax=ax,
                                    bbox=bbox,
                                    colors=colors,
                                    labels=labels,
                                    labels_map=labels_map_dict,
                                    show_axis=False)
    # Load the predicted labels
    for i, bbox in enumerate(annotations):
        if sum(bbox) == 0:
            continue
        # Move the bounding boxes to the left to align with the second image
        bbox[:3] = (np.array(bbox[:3]) +
                    (separation + image.shape[1], 0,
                     separation + image.shape[1])).tolist()
        plot_image_annotations_help(ax=ax,
                                    bbox=bbox,
                                    colors=colors,
                                    labels=labels,
                                    labels_map=labels_map_dict,
                                    show_axis=False,
                                    probability=probs[i])
    # Workaround for returning the image with the annotations as a tensor, save and load it.
    plt.axis('off')
    plt.savefig('/tmp/tb_img.png', dpi=500, bbox_inches='tight', pad_inches=0)
    plt.close()
    img = tf.image.decode_jpeg(open('/tmp/tb_img.png', 'rb').read(),
                               channels=3)
    img = tf.cast(tf.image.resize(img, (400, 1200)), tf.uint8)
    return img
示例#10
0
def train_recognition(_argv):
    """
    Train an image classifier. The images should be saved each in a folder with name the class labels.
    It will save a dictionary that maps each output neuron to the corresponding label as a pickle
    file named 'neuron_to_class_dict.p'. Divides de training set into train and validation sets and uses
    the test set to analyze the accuracy of the model.
    It saves the parameters passed to train the model in a file named 'train_info.txt' in the checkpoints
    directory.
    For the moment it has been checked only with the GTSR dataset.
    """
    img_res = FLAGS.img_res
    gpu_aval = tf.test.is_gpu_available(cuda_only=True)
    model = Recognizer(FLAGS.dataset_name, img_res=img_res, train=True, model_name=FLAGS.model_name)
    gpus = 0
    if gpu_aval:
        for x in device_lib.list_local_devices():
            if x.device_type == "GPU":
                gpus += 1

    print(constants.C_WARNING, "Are CUDA gpus available? \n\t-",
          (constants.C_OKBLUE + ('Yes, ' + str(gpus)) if gpu_aval
           else constants.C_FAIL + 'No.'), constants.C_ENDC)

    batch_size = FLAGS.batch_size
    optimizer = tf.keras.optimizers.Adam(lr=FLAGS.lr)

    if gpus > 1:
        strategy = tf.distribute.MirroredStrategy()
        # Here the batch size scales up by number of workers since
        # `tf.data.Dataset.batch` expects the global batch size. Previously we used 'batch_size',
        # and now this is multiplied by the number of workers.
        batch_size *= gpus
        with strategy.scope():
            model.train_model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
    else:
        model.train_model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])

    model.train_model.summary()

    train_info = FLAGS.extra.replace('\\n', '\n') + '\n'
    train_info += "Train model: {} For {} epochs and {} as Database. \nParameters used:\n    " \
                  "- Frequency = {}\n    " \
                  "- Batch size = {}\n    " \
                  "- Image resolution = {}\n".format(model.model_description, FLAGS.epochs, FLAGS.dataset_name,
                                                     FLAGS.save_freq, FLAGS.batch_size, FLAGS.img_res)

    print(constants.C_WARNING, FLAGS.extra.replace('\\n', '\n'), constants.C_ENDC)
    if model.dataset_name != 'FAKE':
        ds_directory = constants.DATASET_PATH.format(FLAGS.dataset_name)
        train_directory = ds_directory + "train"

        if FLAGS.simple_aug:
            generator = tf.keras.preprocessing.image.ImageDataGenerator(
                rescale=1. / 255.0,
                validation_split=0.1,
                rotation_range=20,
                height_shift_range=0.2,
                width_shift_range=0.2,
                zoom_range=0.3,
                shear_range=0.3,
                brightness_range=(0.2, 0.8)
            )
            train_generator = generator.flow_from_directory(
                train_directory,
                target_size=(img_res, img_res),
                batch_size=batch_size,
                class_mode='categorical',
                subset='training'
            )
            val_generator = generator.flow_from_directory(
                train_directory,
                target_size=(img_res, img_res),
                batch_size=batch_size,
                class_mode='categorical',
                subset='validation'
            )
            class_to_neuron_dict = train_generator.class_indices
        else:
            generator = Generator(directory=train_directory,
                                  batch_size=FLAGS.batch_size,
                                  image_dimensions=(img_res, img_res),
                                  validation_split=0.1)
            train_generator = generator.train_generator
            val_generator = generator.val_generator
            class_to_neuron_dict = generator.class_indices

        neuron_to_class_dict = {}
        labels_dict = helpers.get_labels_dict(model.dataset_name)
        neuron_labels = []
        for class_id, neuron in class_to_neuron_dict.items():
            neuron_to_class_dict[str(neuron)] = str(class_id)
            neuron_labels.append(labels_dict[str(neuron)])

        print('class_to_neuron_dict', class_to_neuron_dict)

        start = time.time()
        history, history_callback = train.train(model=model,
                                                epochs=FLAGS.epochs,
                                                train_data=train_generator,
                                                val_data=val_generator,
                                                save_freq=FLAGS.save_freq,
                                                initial_lr=FLAGS.lr,
                                                train_info=train_info,
                                                use_fit_generator=gpus <= 1,
                                                use_cosine_lr=FLAGS.use_cosine_lr)

        model.train_model.save_weights(model.checkpoints_path + 'weights.ckpt')

        test_acc = 100 * test_model(model, neuron_to_class_dict)
        history_callback.test_acc = test_acc
        print(constants.C_OKGREEN, "Test accuracy {:0.2f} %".format(test_acc),
              constants.C_ENDC)

        with open(model.checkpoints_path + 'neuron_to_class_dict.json', 'w') as fp:
            json.dump(neuron_to_class_dict, fp, indent=4)
        with open(model.checkpoints_path + 'train_info.txt', 'a') as t:
            t.write("Test accuracy {:0.2f} %".format(test_acc))
        with open(model.checkpoints_path + 'neuron_labels.txt', 'a') as t:
            for label in neuron_labels:
                t.write(label + '\n')


    else:
        print("Train with fake data")
        train_data, val_data = helpers.load_fake_dataset_recognition(img_res)
        start = time.time()
        history, history_callback = train.train(model, FLAGS.epochs, train_data, val_data, FLAGS.save_freq,
                                                FLAGS.lr, 'Use FAKE DS\n', False, FLAGS.use_cosine_lr)

    helpers.save_history(FLAGS, model.model_name, model.dataset_name, history, start, 'recognition')

    if FLAGS.tflite:
        converter = tf.lite.TFLiteConverter.from_keras_model(model.inference_model)
        tflite_model = converter.convert()
        open(model.checkpoints_path + "model.tflite", "wb").write(tflite_model)

    return model, history, history_callback