Beispiel #1
0
def do_predict_dir(dicts_models, all_files, num_class=30, gpu_num=1):
    if isinstance(all_files, str):  # csv file
        all_files, all_labels = my_data.get_images_labels(
            filename_csv_or_pd=all_files)

    batch_size_test = 64  # 虽然可以128,但是my_images_generator 将list转换np 耗费CPU

    # 不是写死几个模型,提高灵活性
    prob_list = []  ##每一个模型的概率

    for i, model in enumerate(dicts_models):
        if ('model' not in model1)(model['model'] is None):
            print('prepare to load model:', model['model_file'])
            model1 = keras.models.load_model(model['model_file'],
                                             compile=False)
            print('load model:', model['model_file'], ' complete')

            if gpu_num > 1:
                print('convert Multi-GPU model:', model['model_file'])
                model1 = keras.utils.multi_gpu_model(model1, gpus=gpu_num)
                print('convert Multi-GPU model:', model['model_file'],
                      ' complete')
        else:
            model1 = model['model']

        prob_list.append(np.empty((0, num_class)))

        j = 0  # 样本数可能很多,每计算100个,一个数出提示

        image_size = model['image_size']
        for x in my_images_generator.my_Generator_test(
                all_files,
                image_shape=(image_size, image_size, 3),
                batch_size=batch_size_test):
            probabilities = model1.predict_on_batch(x)
            if prob_list[i].size == 0:
                prob_list[i] = probabilities
            else:
                prob_list[i] = np.vstack((prob_list[i], probabilities))

            j += 1
            print('batch:', j)

    sum_models_weights = 0
    for i, prob1 in enumerate(prob_list):
        if 'model_weight' not in dicts_models[i]:
            model_weight = 1
        else:
            model_weight = dicts_models[i]['model_weight']

        sum_models_weights += model_weight

        if i == 0:
            prob_total = prob1 * model_weight
        else:
            prob_total += prob1 * model_weight

    prob_total /= sum_models_weights

    return prob_total
Beispiel #2
0
def compute_probs(models, file_csv, batch_size=32, cuda_visible_devices='0'):

    os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
    os.environ["CUDA_VISIBLE_DEVICES"] = cuda_visible_devices

    all_files, all_labels = my_data.get_images_labels(file_csv)

    #region using every model to predict every image, generate list_probs
    list_probs = []
    for i, model in enumerate(models):
        if ('model' not in model) or (model['model'] is None):
            print('prepare to load model:', model['model_file'])
            model1 = keras.models.load_model(model['model_file'],
                                             compile=False)
            print('load model:', model['model_file'], ' complete')
        else:
            model1 = model['model']

        batch_no = 0  # batch number
        tmp_probs = None

        image_size = model['image_size']

        generator_test = my_images_generator_2d.My_images_generator_2d_test(
            all_files,
            batch_size=batch_size,
            image_shape=(image_size, image_size, 3))
        for x in generator_test.gen():
            probabilities = model1.predict_on_batch(x)
            if tmp_probs is None:
                tmp_probs = probabilities
            else:
                tmp_probs = np.vstack((tmp_probs, probabilities))

            batch_no += 1
            print('batch:', batch_no)

        list_probs.append(tmp_probs)
    #endregion

    #region weighted average every model's result, generate list_probs_weighted
    list_probs_weighted = None
    model_weight_sum = 0

    for i, probs1 in enumerate(list_probs):
        model_weight = models[i]['model_weight']
        model_weight_sum += model_weight
        if i == 0:
            list_probs_weighted = probs1 * model_weight
        else:
            list_probs_weighted = list_probs_weighted + probs1 * model_weight

    list_probs_weighted = list_probs_weighted / model_weight_sum
    #endregion

    # import keras.backend as K
    # K.clear_session()  # release GPU memory

    return list_probs, list_probs_weighted
Beispiel #3
0
def save_multi_label_csv(file_csv, list_probs, csv_results, list_threshold):

    num_classes = len(list_threshold)
    all_files, all_labels = my_data.get_images_labels(file_csv)

    if csv_results != '':
        if os.path.exists(csv_results):
            os.remove(csv_results)

        with open(csv_results, 'w', newline='') as csvfile:
            csv_writer = csv.writer(csvfile,
                                    quotechar='"',
                                    quoting=csv.QUOTE_ALL,
                                    delimiter=',')

            list_title = ['images', 'labels', 'bigclasses']
            for i in range(num_classes):
                list_title.append('class' + str(i))

            csv_writer.writerow(list_title)

            for i in range(len(all_files)):
                file, label = all_files[i], all_labels[i]
                probs1 = list_probs[i]

                # 0_1_1
                pred_classes = ''
                for j, prob1 in enumerate(probs1):
                    if prob1 > list_threshold[j]:
                        pred_classes += '1_'
                    else:
                        pred_classes += '0_'
                pred_classes = pred_classes[:-1]

                # 4_8_28
                '''
                pred_classes = '_'
                for class_i in range(num_classes):
                    if probs1[class_i] > list_threshold[class_i]:
                        pred_classes = pred_classes + str(class_i) + str('_')
                '''

                list_row = [file, label, pred_classes]

                for k in range(num_classes):
                    list_row.append(round(probs1[k], 3))

                csv_writer.writerow(list_row)

        print('csv file ok')
Beispiel #4
0
    'model_weight': 1
}
dicts_models.append(dict_model1)
dict_model1 = {
    'model_file': os.path.join(model_dir, 'Xception-004-0.984.hdf5'),
    'input_shape': (299, 299, 3),
    'model_weight': 1
}
dicts_models.append(dict_model1)

filename_csv = os.path.join(dir_dest, 'LaserSpot_predict_dir.csv')
if GEN_CSV:
    os.makedirs(os.path.dirname(filename_csv), exist_ok=True)
    write_csv_dir_nolabel(filename_csv, dir_preprocess)
df = pd.read_csv(filename_csv)
all_files, all_labels = get_images_labels(filename_csv_or_pd=df)

prob_total, y_pred_total, prob_list, pred_list = \
    do_predict(dicts_models, filename_csv, argmax=True)

import pickle

os.makedirs(os.path.dirname(pkl_prob), exist_ok=True)
with open(pkl_prob, 'wb') as file:
    pickle.dump(prob_total, file)

if COMPUTE_DIR_FILES:
    op_files_multiclass(filename_csv,
                        prob_total,
                        dir_preprocess=dir_preprocess,
                        dir_dest=dir_dest,
def train_task(filename_csv_train, filename_csv_valid, epoch_fine_tuning=20):

    str_subclass_no = '0.3'
    TRAIN_TYPE = 'DLP_SubClass' + str_subclass_no
    IMG_AUG_ROTATE_MODE = 1  #1:do flip,roate, 2:do flip 3: only translate_percent
    MODEL_SAVE_DIR = '/tmp2/models_subclass/' + TRAIN_TYPE

    #region read csv set weight_class_start, split train validation set
    df = pd.read_csv(filename_csv_train)
    NUM_CLASSES = df['labels'].nunique(dropna=True)

    #  len(df.loc[(df['labels'] == 0)])
    weight_class_start = np.array([1, 9.5])  #23648, 2020
    weight_class_end = np.array([1, 9.5])
    balance_ratio = 0.93

    train_files, train_labels = my_data.get_images_labels(filename_csv_train,
                                                          shuffle=True)
    valid_files, valid_labels = my_data.get_images_labels(filename_csv_valid,
                                                          shuffle=False)

    #endregion

    #region load pre-trained modal

    model_name = 'ResNet448'
    IMAGE_SIZE = 448
    # model_file = '/home/ubuntu/dlp/deploy_models_2019/SubClass0_3/ResNet448-008-train0.7611_val0.840.hdf5'
    model_file = '/home/ubuntu/dlp/deploy_models/DR0_DR1/ResNet448-007-train0.8310_val0.883.hdf5'

    model1 = keras.models.load_model(model_file, compile=False)
    model1.summary()

    BATCH_SIZE_TRAIN = 32
    BATCH_SIZE_VALID = 64

    #endregion

    #region save model dir and checkpointer

    if not os.path.exists(MODEL_SAVE_DIR):
        os.makedirs(MODEL_SAVE_DIR)
    model_save_filepath = os.path.join(
        MODEL_SAVE_DIR, model_name + "-{epoch:03d}-{val_acc:.3f}.hdf5")

    checkpointer = ModelCheckpoint(model_save_filepath,
                                   verbose=1,
                                   save_weights_only=False,
                                   save_best_only=False)
    #endregion

    image_shape = (IMAGE_SIZE, IMAGE_SIZE, 3)

    #region train header layers

    model_train_top = my_transfer_learning.convert_model_transfer(
        model1, change_top=False, clsss_num=NUM_CLASSES)

    #endregion

    #region change learn rate(only fine tuning )

    def scheduler(epoch):
        try:
            file_object = open('lr.txt')
            line = file_object.readline()
            file_object.close()
            line = line.strip('\n')  #删除换行符
            lr_rate = float(line)

            print('set learning rate by lr.txt')
            print("epoch:%d, current learn rate:  %f" % (epoch, lr_rate))
            K.set_value(model1.optimizer.lr, lr_rate)

        except Exception:
            print('read lr-rate file error')
            print('set learning rate automatically')

            # 内置dictionary数据类型是无序的
            dict_lr_rate = collections.OrderedDict()
            dict_lr_rate['0'] = 1e-3  # 0.00001
            dict_lr_rate['2'] = 2e-4
            dict_lr_rate['4'] = 1e-4
            dict_lr_rate['6'] = 3e-5
            dict_lr_rate['8'] = 1e-5
            dict_lr_rate['10'] = 1e-6  # 0.000001
            dict_lr_rate['15'] = 6e-7

            for (k, v) in dict_lr_rate.items():
                if epoch >= int(k):
                    lr_rate = v
            print("epoch:%d, current learn rate:  %f" % (epoch, lr_rate))
            K.set_value(model1.optimizer.lr, lr_rate)

        return K.get_value(model1.optimizer.lr)

    change_lr = keras.callbacks.LearningRateScheduler(scheduler)

    # endregion

    #region fine tuning all layers

    model_fine_tune = my_transfer_learning.convert_trainable_all(
        model_train_top)
    if GPU_NUM > 1:
        print('convert fine tuning model to Multiple GPU...')
        model1 = ModelMGPU(model_fine_tune, GPU_NUM)
        print('convert fine tuning model to Multiple GPU OK')
    else:
        model1 = model_fine_tune

    op_adam_fine_tune = keras.optimizers.Adam(lr=1e-3,
                                              beta_1=0.9,
                                              beta_2=0.999,
                                              epsilon=1e-08,
                                              decay=0.0)

    model1.compile(loss='categorical_crossentropy',
                   optimizer=op_adam_fine_tune,
                   metrics=['acc'],
                   weighted_metrics=['acc'])

    #region data generator

    from imgaug import augmenters as iaa
    sometimes = lambda aug: iaa.Sometimes(0.96, aug)
    # sometimes1 = lambda aug: iaa.Sometimes(0.96, aug)
    imgaug_train = iaa.Sequential([
        # iaa.Crop(px=(0, 16)),  # crop images from each side by 0 to 16px (randomly chosen)
        # sometimes(iaa.CropAndPad(
        #     percent=(-0.04, 0.04),
        #     pad_mode=ia.ALL,
        #     pad_cval=(0, 255)
        # )),
        iaa.Fliplr(0.5),  # horizontally flip 50% of the images
        iaa.Flipud(0.2),  # horizontally flip 50% of the images
        # iaa.GaussianBlur(sigma=(0, 3.0)),  # blur images with a sigma of 0 to 3.0,
        # iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)),  # sharpen images
        # sometimes(iaa.Crop(percent=(0, 0.1))),  # crop images by 0-10% of their height/width
        # shuortcut for CropAndPad

        # improve or worsen the contrast  If PCH is set to true, the process happens channel-wise with possibly different S.
        # sometimes1(iaa.ContrastNormalization((0.9, 1.1), per_channel=0.5), ),
        # change brightness of images (by -5 to 5 of original value)
        # sometimes1(iaa.Add((-6, 6), per_channel=0.5),),
        sometimes(
            iaa.Affine(
                # scale={"x": (0.92, 1.08), "y": (0.92, 1.08)},
                # scale images to 80-120% of their size, individually per axis
                # Translation Shifts the pixels of the image by the specified amounts in the x and y directions
                translate_percent={
                    "x": (-0.02, 0.02),
                    "y": (-0.02, 0.02)
                },
                # translate by -20 to +20 percent (per axis)
                rotate=(-10, 10),  # rotate by -10 to +10 degrees
                # shear=(-16, 16),  # shear by -16 to +16 degrees
                # order=[0, 1],  # use nearest neighbour or bilinear interpolation (fast)
                # cval=(0, 255),  # if mode is constant, use a cval between 0 and 255
                # mode=ia.ALL  # use any of scikit-image's warping modes (see 2nd image from the top for examples)
            )),
    ])

    my_gen_train = My_images_weight_generator(
        files=train_files,
        labels=train_labels,
        image_shape=image_shape,
        weight_class_start=weight_class_start,
        weight_class_end=weight_class_end,
        balance_ratio=balance_ratio,
        num_class=NUM_CLASSES,
        imgaug_seq=imgaug_train,
        batch_size=BATCH_SIZE_TRAIN)

    my_gen_valid = My_images_generator(files=valid_files,
                                       labels=valid_labels,
                                       image_shape=image_shape,
                                       num_output=NUM_CLASSES,
                                       batch_size=BATCH_SIZE_VALID)

    #endregion

    history_fine_tuning = model1.fit_generator(
        my_gen_train.gen(),
        steps_per_epoch=math.ceil(len(train_files) /
                                  BATCH_SIZE_TRAIN),  #number of training batch
        epochs=epoch_fine_tuning,
        validation_data=my_gen_valid.gen(),
        validation_steps=math.ceil(len(valid_files) / BATCH_SIZE_VALID),
        callbacks=[checkpointer, change_lr])

    #endregion

    K.clear_session()  #release GPU memory
Beispiel #6
0
import os

os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
os.environ["CUDA_VISIBLE_DEVICES"] = "0"
import pandas as pd
from LIBS.DataPreprocess import my_data

nb_classes = 2
train_type = 'Gradable'
data_version = 'V1'
filename_csv_test = os.path.join(
    os.path.abspath('..'), 'datafiles', train_type,
    'split_patid_test_{}.csv'.format(data_version))

df = pd.read_csv(filename_csv_test)
files, labels = my_data.get_images_labels(filename_csv_or_pd=df)

model_file = '/home/ubuntu/dlp/deploy_models_english_dr/Gradable/MobileNetV2-005-0.946.hdf5'
input_shape = (224, 224, 3)
save_tsne_image = "/tmp5/t_sne_2020_5_21/Gradable_tsne.png"

from LIBS.Neural_Networks.TSNE.my_tsne_helper import compute_features, gen_tse_features, draw_tsne

features = compute_features(model_file, files, input_shape=input_shape)
X_tsne = gen_tse_features(features)

# save_npy_file = "/tmp5/probs_test1.npy"
# import numpy as np
# np.save(save_npy_file, X_tsne)
# X_tsne = np.load(save_npy_file)
def train_task(filename_csv_train, filename_csv_valid, sub_class_no, model_no,
               imagenet=True, epoch=None):

    str_subclass_no = str(sub_class_no)
    TRAIN_TYPE = 'DLP_SubClass' + str_subclass_no
    IMG_AUG_ROTATE_MODE = 1 #1:do flip,roate, 2:do flip 3: only translate_percent
    model_save_dir = MODEL_SAVE_DIR + TRAIN_TYPE

    #region read csv set weight_class_start, split train validation set
    df = pd.read_csv(filename_csv_train)
    NUM_CLASSES = df['labels'].nunique(dropna=True)

    #  len(df.loc[(df['labels'] == 0)])
    if sub_class_no == -1:  # fundus images, ocular surface ,others
        #191443,25278,568463
        # 153332,25321,719762
        weight_class_start = np.array([1.6, 9, 1])
        weight_class_end = np.array([1.6, 9, 1])

        weight_class_start = np.array([2.6, 11, 1])
        weight_class_end = np.array([2.6, 11, 1])

        balance_ratio = 0.93
    if sub_class_no == 0.1:  #Tessellated fundus  4567, 1324
        weight_class_start = np.array([1, 2.4])
        weight_class_end = np.array([1, 2.4])
        balance_ratio = 0.93
    if sub_class_no == 0.2:  # Big Optic Cup 4567,6639
        weight_class_start = np.array([1, 0.5])
        weight_class_end = np.array([1, 0.5])
        balance_ratio = 0.93
    if sub_class_no == 1:  #DR2,3  10284,2490, single label:9715, 2636
        #8412,2241
        weight_class_start = np.array([1, 2.4])
        weight_class_end = np.array([1, 2.4])
        #12949,3129,  8412,2241
        # add test dataset  11156,2664
        weight_class_start = np.array([1, 2.9])
        weight_class_end = np.array([1, 2.9])
        balance_ratio = 0.93
    if sub_class_no == 2:  #Data CRVO  2636,1527, single label:2548,1391
        weight_class_start = np.array([1, 1.4])
        weight_class_end = np.array([1, 1.4])
        balance_ratio = 0.93
    if sub_class_no == 5:   #543, 683, single label:665,604
        weight_class_start = np.array([1, 1])
        weight_class_end = np.array([1, 1])
        balance_ratio = 0.93
    if sub_class_no == 10:   # 5953 1449
        weight_class_start = np.array([1, 2.6])
        weight_class_end = np.array([1, 2.6])
        balance_ratio = 0.93
    if sub_class_no == 15:  # single label:1523,136
        weight_class_start = np.array([1, 6])
        weight_class_end = np.array([1, 6])
        balance_ratio = 0.93
    if sub_class_no == 29:  # Blur 16253 1814, single label:20882,1099, 12949,3129,
        #train:17580, 1234, total:20709,1432
        weight_class_start = np.array([1, 11])
        weight_class_end = np.array([1, 11])
        balance_ratio = 0.93

    train_files, train_labels = my_data.get_images_labels(filename_csv_train, shuffle=True)
    valid_files, valid_labels = my_data.get_images_labels(filename_csv_valid, shuffle=False)

    #endregion

    #region load pre-trained modal

    #region define and compile model

    if model_no == 1:
        model_name = 'Xception'
        image_size = 299
        image_shape = (image_size, image_size, 3)
        print('loading model...')
        if imagenet:
            model1 = keras.applications.xception.Xception(include_top=True, weights='imagenet',
                                              input_shape=image_shape)
        else:
            model_file = '/home/ubuntu/dlp/deploy_models_new/bigclasses_multilabels/class_weights5_0.2_0.7/Multi_label_Xception-015-train0.9671_val0.945.hdf5'
            model1 = keras.models.load_model(model_file, compile=False)
        print('loading model OK!')

    if model_no == 2:
        model_name = 'InceptionResNetV2'
        image_size = 299
        image_shape = (image_size, image_size, 3)
        print('loading model...')
        if imagenet:
            model1 = keras.applications.inception_resnet_v2.InceptionResNetV2(include_top=True, weights='imagenet',
                                              input_shape=image_shape)
        else:
            model_file = '/home/ubuntu/dlp/deploy_models_new/bigclasses_multilabels/class_weights5_0.2_0.7/Multi_label_InceptionResNetV2-006-train0.9674_val0.951.hdf5'
            model1 = keras.models.load_model(model_file, compile=False)
        print('loading model OK!')

    if model_no == 3:
        model_name = 'Inception_V3'
        image_size = 299
        image_shape = (image_size, image_size, 3)
        print('loading model...')
        model1 = keras.applications.inception_v3.InceptionV3(weights='imagenet', include_top=True,
                                             input_shape=image_shape)
        print('loading model OK!')

    if model_no == 4:
        model_name = 'MobilenetV2'
        image_size = 224
        image_shape = (image_size, image_size, 3)
        print('loading model...')
        from keras.applications import MobileNetV2
        if imagenet:
            model1 = MobileNetV2(include_top=True, input_shape=image_shape, weights='imagenet')
        else:
            model1 = MobileNetV2(include_top=True, input_shape=image_shape, weights=None, classes=NUM_CLASSES)
        print('loading model OK!')

    if model_no == 5:
        model_name = 'ResNet448'
        image_size = 448
        image_shape = (image_size, image_size, 3)
        from LIBS.CNN_Models import my_models
        model1, IMAGE_SIZE, BATCH_SIZE_TRAIN = my_models.get_models(model_name, NUM_CLASSES)
        print('loading model OK!')

    model1 = my_transfer_learning.convert_model_transfer(model1, change_top=True, freeze_feature_extractor=False, clsss_num=NUM_CLASSES)

    if GPU_NUM > 1:
        print('convert model multiple GPU...')
        # bug change to lambda layer, how to generate CAM?
        # model1 = keras.utils.multi_gpu_model(model1, gpus=GPU_NUM)
        model1 = ModelMGPU(model1, GPU_NUM)
        print('convert model multiple GPU OK!')

    op_adam = keras.optimizers.Adam(lr=1e-3, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
    model1.compile(loss='categorical_crossentropy',
                   optimizer=op_adam, metrics=['acc'])

    # endregion

    BATCH_SIZE_TRAIN = 32
    BATCH_SIZE_VALID = 32

    #endregion

    #region save model dir and checkpointer

    if not os.path.exists(model_save_dir):
        os.makedirs(model_save_dir)
    model_save_filepath = os.path.join(model_save_dir, model_name + "-{epoch:03d}-{val_acc:.3f}.hdf5")

    checkpointer = ModelCheckpoint(model_save_filepath, verbose=1,
                                   save_weights_only=False, save_best_only=False)
    #endregion


    def scheduler(epoch):
        try:
            file_object = open('lr.txt')
            line = file_object.readline()
            file_object.close()
            line = line.strip('\n') #删除换行符
            lr_rate = float(line)

            print('set learning rate by lr.txt')
            print("epoch:%d, current learn rate:  %f" % (epoch, lr_rate))
            K.set_value(model1.optimizer.lr, lr_rate)

        except Exception:
            print('read lr-rate file error')
            print('set learning rate automatically')

            # 内置dictionary数据类型是无序的
            dict_lr_rate = collections.OrderedDict()
            dict_lr_rate['0'] = 1e-3
            dict_lr_rate['2'] = 3e-4
            dict_lr_rate['3'] = 1e-4
            dict_lr_rate['5'] = 1e-5
            dict_lr_rate['7'] = 2e-6
            dict_lr_rate['9'] = 1e-6  # 0.000001
            dict_lr_rate['15'] = 6e-7

            #only for ocular surface
            dict_lr_rate['0'] = 1e-3
            dict_lr_rate['1'] = 1e-4
            dict_lr_rate['2'] = 1e-5
            dict_lr_rate['3'] = 1e-6
            dict_lr_rate['15'] = 6e-7

            for (k, v) in dict_lr_rate.items():
                if epoch >= int(k):
                    lr_rate = v
            print("epoch:%d, current learn rate:  %f" % (epoch, lr_rate))
            K.set_value(model1.optimizer.lr, lr_rate)

        return K.get_value(model1.optimizer.lr)

    change_lr = keras.callbacks.LearningRateScheduler(scheduler)


    #region train

    if epoch is None:
        if len(df) > 10000:
            epoch = 20
        elif len(df) > 5000:
            epoch = 25
        elif len(df) > 2000:
            epoch = 30
        else:
            epoch = 40

    #region data generator

    from imgaug import augmenters as iaa
    sometimes = lambda aug: iaa.Sometimes(0.96, aug)
    # sometimes1 = lambda aug: iaa.Sometimes(0.96, aug)
    imgaug_train_seq = iaa.Sequential([
        # iaa.Crop(px=(0, 16)),  # crop images from each side by 0 to 16px (randomly chosen)
        # sometimes(iaa.CropAndPad(
        #     percent=(-0.04, 0.04),
        #     pad_mode=ia.ALL,
        #     pad_cval=(0, 255)
        # )),
        iaa.Fliplr(0.5),  # horizontally flip 50% of the images
        iaa.Flipud(0.2),  # horizontally flip 50% of the images
        # iaa.GaussianBlur(sigma=(0, 3.0)),  # blur images with a sigma of 0 to 3.0,
        # iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)),  # sharpen images
        # sometimes(iaa.Crop(percent=(0, 0.1))),  # crop images by 0-10% of their height/width
        # shuortcut for CropAndPad

        # improve or worsen the contrast  If PCH is set to true, the process happens channel-wise with possibly different S.
        # sometimes1(iaa.ContrastNormalization((0.9, 1.1), per_channel=0.5), ),
        # change brightness of images (by -5 to 5 of original value)
        # sometimes1(iaa.Add((-6, 6), per_channel=0.5),),
        sometimes(iaa.Affine(
            # scale={"x": (0.92, 1.08), "y": (0.92, 1.08)},
            # scale images to 80-120% of their size, individually per axis
            # Translation Shifts the pixels of the image by the specified amounts in the x and y directions
            translate_percent={"x": (-0.02, 0.02), "y": (-0.02, 0.02)},
            # translate by -20 to +20 percent (per axis)
            rotate=(-10, 10),  # rotate by -10 to +10 degrees
            # shear=(-16, 16),  # shear by -16 to +16 degrees
            # order=[0, 1],  # use nearest neighbour or bilinear interpolation (fast)
            # cval=(0, 255),  # if mode is constant, use a cval between 0 and 255
            # mode=ia.ALL  # use any of scikit-image's warping modes (see 2nd image from the top for examples)
        )),
    ])


    my_gen_train = My_images_weight_generator(files=train_files, labels=train_labels, image_shape=image_shape,
                                              weight_class_start=weight_class_start, weight_class_end=weight_class_end, balance_ratio=balance_ratio,
                                              num_class=NUM_CLASSES, imgaug_seq=imgaug_train_seq, batch_size=BATCH_SIZE_TRAIN)

    my_gen_valid = My_images_generator(files=valid_files, labels=valid_labels, image_shape=image_shape,
                                       num_output=NUM_CLASSES, batch_size=BATCH_SIZE_VALID)

    #endregion

    history_train = model1.fit_generator(
        my_gen_train.gen(),
        steps_per_epoch=math.ceil(len(train_files) / BATCH_SIZE_TRAIN), #number of training batch
        epochs=epoch,
        validation_data=my_gen_valid.gen(),
        validation_steps=math.ceil(len(valid_files) / BATCH_SIZE_VALID),
        callbacks=[checkpointer, change_lr]
    )
Beispiel #8
0
def train_task_one_step(model_file,
                        filename_csv_train,
                        filename_csv_valid,
                        filename_csv_test=None,
                        num_classes=None,
                        pre_define_model=None,
                        add_top=False,
                        change_top=False,
                        input_shape=(299, 299, 3),
                        imgaug_train_seq=None,
                        optimizer="adam",
                        lookahead=False,
                        epoch=None,
                        dict_lr=None,
                        batch_size_train=32,
                        batch_size_valid=64,
                        label_smoothing=0,
                        class_weight=None,
                        weight_class_start=None,
                        weight_class_end=None,
                        balance_ratio=None,
                        sensitivity=None,
                        specificity=None,
                        devices=None,
                        verbose=1,
                        model_save_dir='/tmp',
                        model_name='model1',
                        config_file_realtime='config_file_realtime.json',
                        use_multiprocessing=True,
                        workers=5,
                        plt_history_image_file=None):

    #region read csv, split train validation set
    if num_classes is None:
        df = pd.read_csv(filename_csv_train)
        num_classes = df['labels'].nunique(dropna=True)

    train_files, train_labels = my_data.get_images_labels(filename_csv_train,
                                                          shuffle=True)
    valid_files, valid_labels = my_data.get_images_labels(filename_csv_valid)
    #endregion

    #region data sequence
    if weight_class_start is not None:
        generator_train = My_images_weight_generator_2d(
            train_files,
            train_labels,
            num_output=num_classes,
            batch_size=batch_size_train,
            weight_class_start=weight_class_start,
            weight_class_end=weight_class_end,
            balance_ratio=balance_ratio,
            imgaug_seq=imgaug_train_seq,
            label_smoothing=label_smoothing,
            image_shape=input_shape,
        )
    else:
        generator_train = My_images_generator_2d(
            train_files,
            train_labels,
            num_output=num_classes,
            batch_size=batch_size_train,
            image_shape=input_shape,
            imgaug_seq=imgaug_train_seq,
            label_smoothing=label_smoothing)

    list1 = [None] + list(
        input_shape)  # the last batch of an epoch may be smaller.
    shape_x = tuple(list1)  #(batch_size_train, 299, 299, 3)
    shape_y = (None, num_classes)  #(batch_size, num_classes)
    data_train = tf.data.Dataset.from_generator(generator=generator_train.gen,
                                                output_types=(tf.float32,
                                                              tf.float32),
                                                output_shapes=(shape_x,
                                                               shape_y))

    generator_valid = My_images_generator_2d(valid_files,
                                             valid_labels,
                                             num_output=num_classes,
                                             batch_size=batch_size_valid,
                                             image_shape=input_shape)
    data_valid = tf.data.Dataset.from_generator(generator=generator_valid.gen,
                                                output_types=(tf.float32,
                                                              tf.float32),
                                                output_shapes=(shape_x,
                                                               shape_y))

    if filename_csv_test is not None:
        test_files, test_labels = my_data.get_images_labels(filename_csv_test)

    #endregion

    #region callbacks

    os.makedirs(model_save_dir, exist_ok=True)
    save_filepath_finetuning = os.path.join(
        model_save_dir, model_name + "-{epoch:03d}-{val_acc:.3f}.hdf5")
    checkpointer_finetuning = keras.callbacks.ModelCheckpoint(
        save_filepath_finetuning,
        verbose=1,
        save_weights_only=False,
        save_best_only=False)

    class My_callback(keras.callbacks.Callback):
        def on_epoch_end(self, epoch, logs=None):
            try:
                with open(config_file_realtime, 'r') as json_file:
                    data = json.load(json_file)

                    if data['epoch_compute_cf_train'] == 1:
                        compute_cf_train = True
                    else:
                        compute_cf_train = False

                    if data['epoch_compute_cf_valid'] == 1:
                        compute_cf_valid = True
                    else:
                        compute_cf_valid = False

                    if data['epoch_compute_cf_test'] == 1:
                        compute_cf_test = True
                    else:
                        compute_cf_test = False
            except:
                print('read realtime helper file error!')
                compute_cf_train = True
                compute_cf_valid = True
                compute_cf_test = True

            if compute_cf_train:
                print('calculate confusion matrix of training dataset...')
                generator_cf_train = My_images_generator_2d(
                    train_files,
                    train_labels,
                    num_output=num_classes,
                    batch_size=batch_size_train,
                    image_shape=input_shape)
                i = 0
                for x_train, y_train in generator_cf_train.gen():
                    probabilities = self.model.predict(x_train)
                    if i == 0:
                        probs = probabilities
                    else:
                        probs = np.vstack((probs, probabilities))

                    i += 1
                    if i == math.ceil(len(train_files) / batch_size_train):
                        break

                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()

                from sklearn.metrics import confusion_matrix as sk_confusion_matrix
                labels = [x for x in range(0, num_classes)]
                confusion_matrix_train = sk_confusion_matrix(train_labels,
                                                             y_preds,
                                                             labels=labels)

                print(confusion_matrix_train)

            if compute_cf_valid:
                print('calculate confusion matrix of validation dataset...')
                generator_cf_valid = My_images_generator_2d(
                    valid_files,
                    valid_labels,
                    num_output=num_classes,
                    batch_size=batch_size_valid,
                    image_shape=input_shape)
                i = 0
                for x_valid, y_valid in generator_cf_valid.gen():
                    probabilities = self.model.predict(x_valid)
                    if i == 0:
                        probs = probabilities
                    else:
                        probs = np.vstack((probs, probabilities))

                    i += 1
                    if i == math.ceil(len(valid_files) / batch_size_valid):
                        break

                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()

                from sklearn.metrics import confusion_matrix as sk_confusion_matrix
                labels = [x for x in range(0, num_classes)]
                confusion_matrix_valid = sk_confusion_matrix(valid_labels,
                                                             y_preds,
                                                             labels=labels)
                print(confusion_matrix_valid)

            if compute_cf_test:
                print('calculate confusion matrix of test dataset...')
                generator_cf_test = My_images_generator_2d(
                    test_files,
                    test_labels,
                    num_output=num_classes,
                    batch_size=batch_size_valid,
                    image_shape=input_shape)
                i = 0
                for x_test, y_test in generator_cf_test.gen():
                    probabilities = self.model.predict(x_test)
                    if i == 0:
                        probs = probabilities
                    else:
                        probs = np.vstack((probs, probabilities))

                    i += 1
                    if i == math.ceil(len(test_files) / batch_size_valid):
                        break

                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()

                from sklearn.metrics import confusion_matrix as sk_confusion_matrix
                labels = [x for x in range(0, num_classes)]
                confusion_matrix_test = sk_confusion_matrix(test_labels,
                                                            y_preds,
                                                            labels=labels)
                print(confusion_matrix_test)

    my_callback = My_callback()

    if epoch is None:
        if len(df) > 10000:
            epoch = 20
        elif len(df) > 5000:
            epoch = 25
        elif len(df) > 2000:
            epoch = 30
        else:
            epoch = 40

    def scheduler_finetuning(epoch):
        if optimizer == 'adabound':
            return K.get_value(model1.optimizer.lr)
        try:
            with open(config_file_realtime, 'r') as json_file:
                data = json.load(json_file)
                if data['lr_rate'] > 0:
                    lr_rate = data['lr_rate']

                    print(
                        "epoch:%d, current learn rate:  %f by realtime helper file"
                        % (epoch, lr_rate))
                    K.set_value(model1.optimizer.lr, lr_rate)
                    return K.get_value(model1.optimizer.lr)
        except Exception:
            print('read realtime helper file error!')

        if dict_lr is not None:
            for (k, v) in dict_lr.items():
                if epoch >= int(k):
                    lr_rate = v

            print(
                "epoch:%d, set  learn rate:  %f according to pre-defined policy."
                % (epoch, lr_rate))
            K.set_value(model1.optimizer.lr, lr_rate)

        return K.get_value(model1.optimizer.lr)

    change_lr_finetuning = keras.callbacks.LearningRateScheduler(
        scheduler_finetuning)

    #endregion

    strategy = tf.distribute.MirroredStrategy(devices=devices)
    print("Number of devices: {} used".format(strategy.num_replicas_in_sync))
    with strategy.scope():
        if pre_define_model is None:
            print('loading model...')
            model1 = keras.models.load_model(model_file, compile=False)
            print('loading model complete!')

            if add_top:
                model1 = my_transfer_learning.add_top(
                    model1,
                    num_output=num_classes,
                    activation_function='softmax')
            if change_top:
                model1 = my_transfer_learning.convert_model_transfer(
                    model1,
                    clsss_num=num_classes,
                    change_top=change_top,
                    activation_function='SoftMax',
                    freeze_feature_extractor=False)
            model1 = my_transfer_learning.convert_trainable_all(model1)
        else:
            print('creating model...')
            if pre_define_model.lower() == 'inceptionv3':
                model1 = keras.applications.InceptionV3(include_top=False)
            elif pre_define_model.lower() == 'xception':
                model1 = keras.applications.Xception(include_top=False)
            elif pre_define_model.lower() == 'inceptionresnetv2':
                model1 = keras.applications.InceptionResNetV2(
                    include_top=False)
            else:
                raise Exception('predefine model error!')

            model1 = my_transfer_learning.add_top(
                model1, num_output=num_classes, activation_function='softmax')
            print('creating model complete!')

        assert optimizer in ['adam', 'SGD',
                             'adabound'], 'optimizer type  error'
        if optimizer == 'adam':
            op_finetuning = keras.optimizers.Adam(lr=1e-3,
                                                  beta_1=0.9,
                                                  beta_2=0.999,
                                                  epsilon=1e-08)
        if optimizer == 'SGD':
            op_finetuning = keras.optimizers.sgd(lr=1e-3,
                                                 momentum=0.9,
                                                 nesterov=True)
        if optimizer == 'adabound':
            op_finetuning = AdaBound(lr=1e-03,
                                     final_lr=0.1,
                                     gamma=1e-03,
                                     amsbound=False)

        if sensitivity is not None and specificity is not None:
            sensivity = keras.metrics.SensitivityAtSpecificity(
                specificity=sensitivity)
            specificity = keras.metrics.SpecificityAtSensitivity(
                sensitivity=specificity)
            my_metric = ['acc', sensivity, specificity]
        else:
            my_metric = ['acc']

        # loss1 = tf.keras.losses.CategoricalCrossentropy(from_logits=False, label_smoothing=label_smoothing)
        loss1 = 'categorical_crossentropy'
        model1.compile(loss=loss1, optimizer=op_finetuning, metrics=my_metric)

        if lookahead:
            lookahead = Lookahead(k=5, alpha=0.5)
            lookahead.inject(model1)

        history = model1.fit(
            data_train,
            steps_per_epoch=math.ceil(len(train_files) / batch_size_train),
            epochs=epoch,
            verbose=verbose,
            validation_data=data_valid,
            validation_steps=math.ceil(len(valid_files) / batch_size_valid),
            callbacks=[
                checkpointer_finetuning, change_lr_finetuning, my_callback
            ],
            class_weight=class_weight,
            use_multiprocessing=use_multiprocessing,
            workers=workers)

        if plt_history_image_file is not None:
            import matplotlib.pyplot as plt
            plt.plot(history.history['acc'])
            plt.plot(history.history['val_acc'])
            plt.title('model accuracy')
            plt.ylabel('accuracy')
            plt.xlabel('epoch')
            plt.legend(['train', 'test'], loc='upper left')
            plt.show()
            # summarize history for loss
            plt.plot(history.history['loss'])
            plt.plot(history.history['val_loss'])
            plt.title('model loss')
            plt.ylabel('loss')
            plt.xlabel('epoch')
            plt.legend(['train', 'test'], loc='upper left')
            plt.show()
            plt.savefig(plt_history_image_file)
            plt.close()

    K.clear_session()
Beispiel #9
0
def train_task(filename_csv_train,
               filename_csv_valid,
               num_classes,
               model_name,
               model1,
               image_size,
               add_top=False,
               change_top=True,
               freeze_layes_num=None,
               class_weights=None,
               inter_class_ratio=None,
               positive_weight_ratio=4,
               exclusion_loss_ratio=0,
               imgaug_train_seq=None,
               epoch_finetuning=15,
               dict_lr_finetuning=None,
               batch_size_train=32,
               batch_size_valid=32,
               smooth_factor=0,
               model_save_dir='/tmp'):

    #region load csv files
    print('loading csv data')
    train_files, train_labels = my_data.get_images_labels(filename_csv_train,
                                                          shuffle=True)
    valid_files, valid_labels = my_data.get_images_labels(filename_csv_valid)

    # region get the number of labels in every class
    df = pd.read_csv(filename_csv_train)
    # NUM_CLASSES = df['labels'].nunique(dropna=True) #only work for single label

    LIST_CLASS_SAMPLES_NUM = [0 for _ in range(num_classes)]
    for _, row in df.iterrows():
        labels = str(row["labels"])  # single label may be int type
        list_labels = labels.split('_')
        for label in list_labels:
            if label == '':
                continue

            assert label.isdigit(), 'Error label!'
            LIST_CLASS_SAMPLES_NUM[int(label)] += 1

    # endregion

    # region multiple labels convert to simgle label(smallest class num) in order to dynamic resampling
    train_labels_single = [0 for _ in range(len(train_labels))]

    for i, labels in enumerate(train_labels):
        labels = str(labels)  # single label may be int type
        list_labels = labels.split('_')

        label_current = None
        for label in list_labels:
            if label == '':
                continue

            if label_current is None:  # it is the first label
                label_current = label
            elif LIST_CLASS_SAMPLES_NUM[int(label)] < LIST_CLASS_SAMPLES_NUM[
                    int(label_current)]:
                label_current = label  # current label's class contain smaller number of images than before

        train_labels_single[i] = label_current

    # endregion

    print('loading csv data complete!')

    #endregion

    #region  data generator
    image_shape = (image_size, image_size, 3)
    file_weight_power = os.path.join(sys.path[0], 'weight_power.txt')

    my_gen_train = My_gen_weight_multi_labels(
        files=train_files,
        labels=train_labels,
        labels_single=train_labels_single,
        image_shape=image_shape,
        file_weight_power=file_weight_power,
        list_class_samples_num=LIST_CLASS_SAMPLES_NUM,
        num_class=num_classes,
        smooth_factor=smooth_factor,
        imgaug_seq=imgaug_train_seq,
        batch_size=batch_size_train)

    my_gen_valid = My_images_generator(files=valid_files,
                                       labels=valid_labels,
                                       image_shape=image_shape,
                                       multi_labels=True,
                                       num_output=num_classes,
                                       batch_size=batch_size_valid)
    #endregion

    #region custom loss function
    if class_weights is None:
        if inter_class_ratio is not None:
            class_positive_weights = op_class_weight(
                LIST_CLASS_SAMPLES_NUM, weight_power=inter_class_ratio)
            class_positive_weights = np.array(class_positive_weights)
            # class_samples_weights[0] /= (3)  #class0 Normal
            class_positive_weights *= positive_weight_ratio
        else:
            class_positive_weights = [1 for _ in range(num_classes)]
            class_positive_weights = np.array(class_positive_weights)

        print(np.round(class_positive_weights, 2))

        class_weights = []
        for class_weight1 in class_positive_weights:
            class_weights.append([1,
                                  class_weight1])  # sigmoid : 0:1, 1:weight1

        class_weights = np.array(class_weights)

    custom_loss_function = get_weighted_binary_crossentropy(
        class_weights, exclusion_loss_ratio)

    #endregion

    # region loading and converting model
    if isinstance(model1, str):
        print('loading model...')
        model1 = keras.models.load_model(model1, compile=False)
        print('loading model complete!')

    if add_top:
        model1 = my_transfer_learning.add_top(model1,
                                              num_output=num_classes,
                                              activation_function='Sigmoid')

    model_train_top = my_transfer_learning.convert_model_transfer(
        model1,
        change_top=change_top,
        clsss_num=num_classes,
        activation_function='Sigmoid',
        freeze_feature_extractor=True,
        freeze_layes_num=freeze_layes_num)
    model_train_top.summary()

    if GPU_NUM > 1:
        print('convert model to Multiple GPU...')
        model_train_top = ModelMGPU(model_train_top, GPU_NUM)
        print('convert  model to Multiple GPU OK')

    op_adam_train_top = keras.optimizers.Adam(lr=1e-3,
                                              beta_1=0.9,
                                              beta_2=0.999,
                                              epsilon=1e-08)
    model_train_top.compile(loss=custom_loss_function,
                            optimizer=op_adam_train_top,
                            metrics=['acc'])
    from LIBS.CNN_Models.optimization.lookahead import Lookahead
    lookahead = Lookahead(k=5, alpha=0.5)
    lookahead.inject(model_train_top)
    #endregion

    #region fine tuning all layers

    model_fine_tune = my_transfer_learning.convert_trainable_all(
        model_train_top)

    if not os.path.exists(model_save_dir):
        os.makedirs(model_save_dir)

    save_filepath_finetuning = os.path.join(
        model_save_dir, model_name + "-{epoch:03d}-{val_acc:.3f}.hdf5")
    checkpointer_finetuning = ModelCheckpoint(save_filepath_finetuning,
                                              verbose=1,
                                              save_weights_only=False,
                                              save_best_only=False)

    def scheduler_fine_tuning(epoch):
        try:
            file_object = open('lr.txt')
            line = file_object.readline()
            file_object.close()
            line = line.strip('\n')  # 删除换行符
            lr_rate = float(line)

            print("epoch:%d, current learn rate by lr.txt:  %f" %
                  (epoch, lr_rate))
            K.set_value(model_fine_tune.optimizer.lr, lr_rate)

        except Exception:
            if dict_lr_finetuning is not None:
                dict_lr_rate = dict_lr_finetuning

                for (k, v) in dict_lr_rate.items():
                    if epoch >= int(k):
                        lr_rate = v

                print("epoch:%d, current learn rate automatically:  %f" %
                      (epoch, lr_rate))
                K.set_value(model_fine_tune.optimizer.lr, lr_rate)

        return K.get_value(model_fine_tune.optimizer.lr)

    change_lr_finetuning = keras.callbacks.LearningRateScheduler(
        scheduler_fine_tuning)

    history_finetuning = model_fine_tune.fit_generator(
        my_gen_train.gen(),
        steps_per_epoch=math.ceil(len(train_files) /
                                  batch_size_train),  #number of training batch
        epochs=epoch_finetuning,
        validation_data=my_gen_valid.gen(),
        validation_steps=math.ceil(len(valid_files) / batch_size_valid),
        callbacks=[checkpointer_finetuning, change_lr_finetuning])

    #endregion

    K.clear_session()  #release GPU memory
def do_predict_batch(dicts_models,
                     all_files,
                     batch_size_test=64,
                     argmax=False,
                     cuda_visible_devices="",
                     gpu_num=1):

    os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
    os.environ["CUDA_VISIBLE_DEVICES"] = cuda_visible_devices

    if isinstance(all_files, str):  #csv file
        all_files, all_labels = my_data.get_images_labels(
            filename_csv_or_pd=all_files)

    assert len(all_files) > 0, 'No Data'

    prob_lists = [
    ]  #each element contain all probabilities  multiple batch, np.vstack
    preds_list = []

    for dict_model in dicts_models:
        if ('model' not in dict_model) or (dict_model['model'] is None):
            print('prepare load model:', dict_model['model_file'])
            model1 = keras.models.load_model(dict_model['model_file'],
                                             compile=False)
            print('load model:', dict_model['model_file'], ' complete')

            if gpu_num > 1:
                print('convert Multi-GPU model:', dict_model['model_file'])
                model1 = keras.utils.multi_gpu_model(model1, gpus=gpu_num)
                print('convert Multi-GPU model:', dict_model['model_file'],
                      ' complete')

            dict_model['model'] = model1
        else:
            model1 = dict_model['model']  # avoid loading models multiple times

        if 'image_size' in dict_model:
            image_size = dict_model['image_size']
        elif model1.input_shape[2] is not None:
            image_size = model1.input_shape[2]
        else:
            image_size = 299

        j = 0  # batch
        for x in my_images_generator.my_Generator_test(
                all_files,
                image_shape=(image_size, image_size, 3),
                batch_size=batch_size_test):

            probabilities = model1.predict_on_batch(x)

            if j == 0:  #'probs' not in locals().keys():
                probs = probabilities
            else:
                probs = np.vstack((probs, probabilities))

            j += 1
            print('batch:', j)

        prob_lists.append(probs)

        if argmax:
            y_preds = probs.argmax(axis=-1)
            y_preds = y_preds.tolist()
            preds_list.append(y_preds)

    sum_models_weights = 0
    for i, prob1 in enumerate(prob_lists):
        if 'model_weight' not in dicts_models[i]:
            model_weight = 1
        else:
            model_weight = dicts_models[i]['model_weight']

        if i == 0:
            prob_total = prob1 * model_weight
        else:
            prob_total += prob1 * model_weight

        sum_models_weights += model_weight

    prob_total /= sum_models_weights

    if argmax:
        y_pred_total = prob_total.argmax(axis=-1)
        return prob_total, y_pred_total, prob_lists, preds_list
    else:
        return prob_total, prob_lists
Beispiel #11
0
def train_task_two_steps(model1, filename_csv_train, FILENAME_CSV_VALID, filename_csv_test=None,
                         input_shape=(299, 299, 3), imgaug_train_seq=None,
                         add_top=False, change_top=True, freeze_layes_num=None,
                         optimizer="adam", lookahead=True,
                         epoch_traintop=0, epoch_finetuning=0,
                         dict_lr_traintop=None, dict_lr_finetuning=None,
                         batch_size_train=32, batch_size_valid=64,
                         label_smoothing=0, class_weight=None,
                         weight_class_start=None, weight_class_end=None, balance_ratio=None,
                         model_save_dir='/tmp', model_name='model1',
                         gpu_num=1, verbose=1,
                         config_file_realtime='config_file_realtime.json'):

    #region read csv, split train validation set
    df = pd.read_csv(filename_csv_train)
    NUM_CLASSES = df['labels'].nunique(dropna=True)

    train_files, train_labels = my_data.get_images_labels(filename_csv_train, shuffle=True)
    valid_files, valid_labels = my_data.get_images_labels(FILENAME_CSV_VALID)

    #endregion

    #region load , convert  train_top model
    if isinstance(model1, str):
        print('loading model...')
        model1 = keras.models.load_model(model1, compile=False)
        print('loading model complete!')

    if add_top:
        model1 = my_transfer_learning.add_top(model1, num_output=NUM_CLASSES, activation_function='SoftMax')

    model_traintop = my_transfer_learning.convert_model_transfer(model1, clsss_num=NUM_CLASSES,
            change_top=change_top, activation_function='SoftMax',
            freeze_feature_extractor=True, freeze_layes_num=freeze_layes_num)

    if gpu_num > 1:
        print('convert base model to Multiple GPU...')
        model_traintop = ModelMGPU(model_traintop, gpu_num)
        print('convert base top model to Multiple GPU OK')

    assert optimizer in ['adam', 'SGD', 'adabound'], 'optimizer type  error'
    #endregion

    #region data generator
    if weight_class_start is not None:
        my_gen_train = My_images_weight_generator(files=train_files, labels=train_labels, image_shape=input_shape,
                  weight_class_start=weight_class_start, weight_class_end=weight_class_end, balance_ratio=balance_ratio,
                  num_class=NUM_CLASSES, imgaug_seq=imgaug_train_seq, batch_size=batch_size_train,
                  label_smoothing=label_smoothing)
    else:
        my_gen_train = My_images_generator(files=train_files, labels=train_labels, image_shape=input_shape,
                 imgaug_seq=imgaug_train_seq, num_output=NUM_CLASSES, batch_size=batch_size_train)

    my_gen_valid = My_images_generator(files=valid_files, labels=valid_labels,
                image_shape=input_shape, num_output=NUM_CLASSES, batch_size=batch_size_valid)

    if filename_csv_test is not None:
        test_files, test_labels = my_data.get_images_labels(filename_csv_test)
        my_gen_test = My_images_generator(files=test_files, labels=test_labels,
                image_shape=input_shape, num_output=NUM_CLASSES, batch_size=batch_size_valid)

    #endregion

    # region save model dir and checkpointer
    os.makedirs(model_save_dir, exist_ok=True)

    save_filepath_traintop = os.path.join(model_save_dir, model_name + "-traintop-{epoch:03d}-{val_acc:.3f}.hdf5")
    checkpointer_traintop = ModelCheckpoint(save_filepath_traintop,
                      verbose=1, save_weights_only=False, save_best_only=False)

    save_filepath_finetuning = os.path.join(model_save_dir, model_name + "-{epoch:03d}-{val_acc:.3f}.hdf5")
    checkpointer_finetuning = ModelCheckpoint(save_filepath_finetuning,
                      verbose=1, save_weights_only=False, save_best_only=False)

    # endregion

    #region computer validation confusion matrix
    class My_callback(keras.callbacks.Callback):
       def on_epoch_end(self, epoch, logs=None):
            try:
                with open(config_file_realtime, 'r') as json_file:
                    data = json.load(json_file)

                    if data['epoch_compute_cf_train'] == 1:
                        compute_cf_train = True
                    else:
                        compute_cf_train = False

                    if data['epoch_compute_cf_valid'] == 1:
                        compute_cf_valid = True
                    else:
                        compute_cf_valid = False

                    if data['epoch_compute_cf_test'] == 1:
                        compute_cf_test = True
                    else:
                        compute_cf_test = False
            except:
                print('read realtime helper file error!')
                compute_cf_train = True
                compute_cf_valid = True
                compute_cf_test = True

            if compute_cf_train:
                print('calculate confusion matrix of training dataset...')
                # do not use img augmentation
                my_gen_train_test = My_images_generator(files=train_files, labels=train_labels,
                                                   image_shape=input_shape, num_output=NUM_CLASSES,
                                                   batch_size=batch_size_train)

                i = 0
                for x_train, y_train in my_gen_train_test.gen():
                    probabilities = self.model.predict(x_train)
                    if i == 0:
                        probs = probabilities
                    else:
                        probs = np.vstack((probs, probabilities))

                    i += 1
                    if i == math.ceil(len(train_files) / batch_size_train):
                        break

                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()

                from sklearn.metrics import confusion_matrix as sk_confusion_matrix
                labels = [x for x in range(0, NUM_CLASSES)]
                confusion_matrix_train = sk_confusion_matrix(train_labels, y_preds, labels=labels)

                print(confusion_matrix_train)

            if compute_cf_valid:
                print('calculate confusion matrix of validation dataset...')
                i = 0
                for x_valid, y_valid in my_gen_valid.gen():
                    probabilities = self.model.predict(x_valid)
                    if i == 0:
                        probs = probabilities
                    else:
                        probs = np.vstack((probs, probabilities))

                    i += 1
                    if i == math.ceil(len(valid_files) / batch_size_valid):
                        break

                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()

                from sklearn.metrics import confusion_matrix as sk_confusion_matrix
                labels = [x for x in range(0, NUM_CLASSES)]
                confusion_matrix_valid = sk_confusion_matrix(valid_labels, y_preds, labels=labels)

                print(confusion_matrix_valid)

            if compute_cf_test:
                print('calculate confusion matrix of test dataset...')
                i = 0
                for x_test, y_test in my_gen_test.gen():
                    probabilities = self.model.predict(x_test)
                    if i == 0:
                        probs = probabilities
                    else:
                        probs = np.vstack((probs, probabilities))

                    i += 1
                    if i == math.ceil(len(test_files) / batch_size_valid):
                        break

                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()

                from sklearn.metrics import confusion_matrix as sk_confusion_matrix
                labels = [x for x in range(0, NUM_CLASSES)]
                confusion_matrix_test = sk_confusion_matrix(test_labels, y_preds, labels=labels)

                print(confusion_matrix_test)

            #endregion

    my_callback = My_callback()
    #endregion

    #region train header layers
    if epoch_traintop > 0:
        if optimizer == 'adam':
            op_train_top = keras.optimizers.Adam(lr=1e-3, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
        if optimizer == 'SGD':
            op_train_top = keras.optimizers.sgd(lr=1e-3, momentum=0.9, nesterov=True)
        if optimizer == 'adabound':
            op_train_top = AdaBound(lr=1e-03, final_lr=0.1, gamma=1e-03, amsbound=False)

        model_traintop.compile(loss='categorical_crossentropy',
                               optimizer=op_train_top, metrics=['acc'])
                            # optimizer = op_train_top, metrics = ['acc', sensitivity, specificity])
        if lookahead:
            lookahead = Lookahead(k=5, alpha=0.5)
            lookahead.inject(model_traintop)

        if epoch_traintop is None:
            if len(df) > 10000:
                epoch_traintop = 5
            elif len(df) > 5000:
                epoch_traintop = 8
            elif len(df) > 2000:
                epoch_traintop = 10
            else:
                epoch_traintop = 15

        def scheduler_traintop(epoch):
            if optimizer == 'adabound':
                return K.get_value(model_traintop.optimizer.lr)

            try:
                with open(config_file_realtime, 'r') as json_file:
                    data = json.load(json_file)
                    if data['lr_rate'] > 0:
                        lr_rate = data['lr_rate']

                        print("epoch:%d, current learn rate:  %f by realtime helper file" % (epoch, lr_rate))
                        K.set_value(model_traintop.optimizer.lr, lr_rate)
                        return K.get_value(model_traintop.optimizer.lr)
            except Exception:
                print('read realtime helper file error!')

            if dict_lr_traintop is not None:
                for (k, v) in dict_lr_traintop.items():
                    if epoch >= int(k):
                        lr_rate = v

                print("epoch:%d, set  learn rate:  %f according to pre-defined policy." % (epoch, lr_rate))
                K.set_value(model_traintop.optimizer.lr, lr_rate)

            return K.get_value(model_traintop.optimizer.lr)

        change_lr_traintop = keras.callbacks.LearningRateScheduler(scheduler_traintop)

        history_top = model_traintop.fit_generator(
            my_gen_train.gen(),
            steps_per_epoch=math.ceil(len(train_files) / batch_size_train), #number of training batch
            epochs=epoch_traintop,
            verbose=verbose,
            validation_data=my_gen_valid.gen(),
            validation_steps=math.ceil(len(valid_files) / batch_size_valid),
            callbacks=[checkpointer_traintop, change_lr_traintop, my_callback],
            class_weight=class_weight)

    #endregion

    #region fine tuning all layers
    if epoch_finetuning > 0:
        model_finetuning = my_transfer_learning.convert_trainable_all(model_traintop)

        if optimizer == 'adam':
            op_finetuning = keras.optimizers.Adam(lr=1e-5, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
        if optimizer == 'SGD':
            op_finetuning = keras.optimizers.sgd(lr=1e-5, momentum=0.9, nesterov=True)
        if optimizer == 'adabound':
            op_finetuning = AdaBound(lr=1e-04, final_lr=0.01, gamma=1e-03, amsbound=False)

        model_finetuning.compile(loss='categorical_crossentropy',
               optimizer=op_finetuning, metrics=['acc'])
            # optimizer = op_finetuning, metrics = ['acc', sensitivity, specificity])

        if lookahead:
            lookahead = Lookahead(k=5, alpha=0.5)
            lookahead.inject(model_finetuning)

        if epoch_finetuning is None:
            if len(df) > 10000:
                epoch_finetuning = 20
            elif len(df) > 5000:
                epoch_finetuning = 25
            elif len(df) > 2000:
                epoch_finetuning = 30
            else:
                epoch_finetuning = 40

        def scheduler_finetuning(epoch):
            if optimizer == 'adabound':
                return K.get_value(model_finetuning.optimizer.lr)

            try:
                with open(config_file_realtime, 'r') as json_file:
                    data = json.load(json_file)
                    if data['lr_rate'] > 0:
                        lr_rate = data['lr_rate']

                        print("epoch:%d, current learn rate:  %f by realtime helper file" % (epoch, lr_rate))
                        K.set_value(model_finetuning.optimizer.lr, lr_rate)
                        return K.get_value(model_finetuning.optimizer.lr)
            except Exception:
                print('read realtime helper file error!')

            if dict_lr_finetuning is not None:
                for (k, v) in dict_lr_finetuning.items():
                    if epoch >= int(k):
                        lr_rate = v

                print("epoch:%d, set  learn rate:  %f according to pre-defined policy." % (epoch, lr_rate))
                K.set_value(model_finetuning.optimizer.lr, lr_rate)

            return K.get_value(model_finetuning.optimizer.lr)

        change_lr_finetuning = keras.callbacks.LearningRateScheduler(scheduler_finetuning)

        history_finetuning = model_finetuning.fit_generator(
            my_gen_train.gen(),
            steps_per_epoch=math.ceil(len(train_files) / batch_size_train),  # number of training batch
            epochs=epoch_finetuning,
            verbose=verbose,
            validation_data=my_gen_valid.gen(),
            validation_steps=math.ceil(len(valid_files) / batch_size_valid),
            callbacks=[checkpointer_finetuning, change_lr_finetuning, my_callback],
            class_weight=class_weight
        )

    #endregion

    K.clear_session()  #release GPU memory
def train_task_two_steps(model1,
                         filename_csv_train,
                         FILENAME_CSV_VALID,
                         filename_csv_test=None,
                         image_size=299,
                         imgaug_train_seq=None,
                         num_output=1,
                         add_top=False,
                         change_top=True,
                         freeze_layes_num=None,
                         epoch_traintop=None,
                         epoch_finetuning=None,
                         dict_lr_traintop=None,
                         dict_lr_finetuning=None,
                         batch_size_train=32,
                         batch_size_valid=64,
                         model_save_dir='/tmp',
                         model_name='model1',
                         compute_cf_train=False,
                         compute_cf_valid=False,
                         compute_cf_test=False,
                         gpu_num=1,
                         verbose=1):

    #region read csv, split train validation set
    df = pd.read_csv(filename_csv_train
                     )  #get number of train samples, set epoch automaticaly
    train_files, train_labels = my_data.get_images_labels(filename_csv_train,
                                                          shuffle=True)
    valid_files, valid_labels = my_data.get_images_labels(FILENAME_CSV_VALID)

    #endregion

    #region load , convert and compile train_top model
    if isinstance(model1, str):
        print('loading model...')
        model1 = keras.models.load_model(model1, compile=False)
        print('loading model complete!')

    if add_top:
        model1 = my_transfer_learning.add_top(model1,
                                              num_output=num_output,
                                              activation_function='SoftMax')

    model_traintop = my_transfer_learning.convert_model_transfer(
        model1,
        clsss_num=num_output,
        change_top=change_top,
        activation_function='Regression',
        freeze_feature_extractor=True,
        freeze_layes_num=freeze_layes_num)
    if gpu_num > 1:
        print('convert base model to Multiple GPU...')
        model_traintop = ModelMGPU(model_traintop, gpu_num)
        print('convert base top model to Multiple GPU OK')

    #endregion

    #region data generator
    image_shape = (image_size, image_size, 3)
    my_gen_train = My_images_generator(files=train_files,
                                       labels=train_labels,
                                       regression=True,
                                       imgaug_seq=imgaug_train_seq,
                                       image_shape=image_shape,
                                       num_output=num_output,
                                       batch_size=batch_size_train)

    my_gen_valid = My_images_generator(files=valid_files,
                                       labels=valid_labels,
                                       regression=True,
                                       image_shape=image_shape,
                                       num_output=num_output,
                                       batch_size=batch_size_valid)

    if compute_cf_test:
        test_files, test_labels = my_data.get_images_labels(filename_csv_test)
        my_gen_test = My_images_generator(files=test_files,
                                          labels=test_labels,
                                          regression=True,
                                          image_shape=image_shape,
                                          num_output=num_output,
                                          batch_size=batch_size_valid)

    #endregion

    # region save model dir and checkpointer
    os.makedirs(model_save_dir, exist_ok=True)

    save_filepath_traintop = os.path.join(
        model_save_dir, model_name +
        "-{epoch:03d}--{val_loss:.1f}---{val_mean_absolute_error:.1f}---{mean_squared_error:.1f}-{mean_absolute_error:.1f}.hdf5"
    )
    checkpointer_traintop = ModelCheckpoint(save_filepath_traintop,
                                            save_weights_only=False,
                                            save_best_only=False)

    save_filepath_finetuning = os.path.join(
        model_save_dir, model_name +
        "-{epoch:03d}--{val_loss:.1f}---{val_mean_absolute_error:.1f}---{mean_squared_error:.1f}-{mean_absolute_error:.1f}.hdf5"
    )
    checkpointer_finetuning = ModelCheckpoint(save_filepath_finetuning,
                                              save_weights_only=False,
                                              save_best_only=False)

    # endregion

    #region computer validation confusion matrix
    class My_callback(keras.callbacks.Callback):
        def on_epoch_end(self, epoch, logs=None):
            if compute_cf_train:
                print('calculate confusion matrix of training dataset...')
                my_gen_train_no_imgaug = My_images_generator(
                    files=train_files,
                    labels=train_labels,
                    regression=True,
                    imgaug_seq=imgaug_train_seq,
                    image_shape=image_shape,
                    num_output=num_output,
                    batch_size=batch_size_train)

                i = 0
                for x_train, y_train in my_gen_train_no_imgaug.gen():
                    probabilities = self.model.predict(x_train)
                    if i == 0:
                        probs = probabilities
                    else:
                        probs = np.vstack((probs, probabilities))

                    i += 1
                    if i == math.ceil(len(train_files) / batch_size_train):
                        break

                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()

            # endregion

            if compute_cf_valid:
                print('calculate confusion matrix of validation dataset...')
                #use the same my_gen_valid
                i = 0
                for x_valid, y_valid in my_gen_valid.gen():
                    probabilities = self.model.predict(x_valid)
                    if i == 0:
                        probs = probabilities
                    else:
                        probs = np.vstack((probs, probabilities))

                    i += 1
                    if i == math.ceil(len(valid_files) / batch_size_valid):
                        break

                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()

            if compute_cf_test:
                print('calculate confusion matrix of test dataset...')
                i = 0
                for x_test, y_test in my_gen_test.gen():
                    probabilities = self.model.predict(x_test)
                    if i == 0:
                        probs = probabilities
                    else:
                        probs = np.vstack((probs, probabilities))

                    i += 1
                    if i == math.ceil(len(test_files) / batch_size_valid):
                        break

                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()

            #endregion

    my_callback = My_callback()
    #endregion

    #region train header layers
    if epoch_traintop > 0:
        op_adam_train_top = keras.optimizers.Adam(lr=1e-3,
                                                  beta_1=0.9,
                                                  beta_2=0.999,
                                                  epsilon=1e-08)
        op_adam_train_top.compile(loss='mse',
                                  optimizer=op_adam_train_top,
                                  metrics=['mae', 'mse'])
        from LIBS.CNN_Models.optimization.lookahead import Lookahead
        lookahead = Lookahead(k=5, alpha=0.5)
        lookahead.inject(model_traintop)

        if epoch_traintop is None:
            if len(df) > 10000:
                epoch_traintop = 5
            elif len(df) > 5000:
                epoch_traintop = 8
            elif len(df) > 2000:
                epoch_traintop = 10
            else:
                epoch_traintop = 15

        def scheduler_traintop(epoch):
            if dict_lr_traintop is not None:
                dict_lr = dict_lr_traintop

                for (k, v) in dict_lr.items():
                    if epoch >= int(k):
                        lr_rate = v

                print(
                    "epoch:%d, set  learn rate:  %f according to pre-defined policy."
                    % (epoch, lr_rate))
                K.set_value(model_traintop.optimizer.lr, lr_rate)

            return K.get_value(model_traintop.optimizer.lr)

        change_lr_traintop = keras.callbacks.LearningRateScheduler(
            scheduler_traintop)

        history_top = model_traintop.fit_generator(
            my_gen_train.gen(),
            steps_per_epoch=math.ceil(
                len(train_files) /
                batch_size_train),  #number of training batch
            epochs=epoch_traintop,
            verbose=verbose,
            validation_data=my_gen_valid.gen(),
            validation_steps=math.ceil(len(valid_files) / batch_size_valid),
            callbacks=[checkpointer_traintop, change_lr_traintop, my_callback])

    #endregion

    #region fine tuning all layers
    if epoch_finetuning > 0:
        model_finetuning = my_transfer_learning.convert_trainable_all(
            model_traintop)

        op_adam_finetuning = keras.optimizers.Adam(lr=1e-5,
                                                   beta_1=0.9,
                                                   beta_2=0.999,
                                                   epsilon=1e-08)
        model_finetuning.compile(loss='mse',
                                 optimizer=op_adam_finetuning,
                                 metrics=['mae', 'mse'])
        from LIBS.CNN_Models.optimization.lookahead import Lookahead
        lookahead = Lookahead(k=5, alpha=0.5)
        lookahead.inject(model_finetuning)

        if epoch_finetuning is None:
            if len(df) > 10000:
                epoch_finetuning = 20
            elif len(df) > 5000:
                epoch_finetuning = 25
            elif len(df) > 2000:
                epoch_finetuning = 30
            else:
                epoch_finetuning = 40

        def scheduler_finetuning(epoch):
            try:
                file_object = open('lr.txt')
                line = file_object.readline()
                file_object.close()
                line = line.strip('\n')  #删除换行符
                lr_rate = float(line)

                print("epoch:%d, set learning rate:  %f by lr.txt" %
                      (epoch, lr_rate))
                K.set_value(model_finetuning.optimizer.lr, lr_rate)

            except Exception:
                if dict_lr_finetuning is not None:
                    dict_lr = dict_lr_finetuning

                    for (k, v) in dict_lr.items():
                        if epoch >= int(k):
                            lr_rate = v

                    print(
                        "epoch:%d, set  learn rate:  %f according to pre-defined policy."
                        % (epoch, lr_rate))
                    K.set_value(model_finetuning.optimizer.lr, lr_rate)

            return K.get_value(model_finetuning.optimizer.lr)

        change_lr_finetuning = keras.callbacks.LearningRateScheduler(
            scheduler_finetuning)

        history_finetuning = model_finetuning.fit_generator(
            my_gen_train.gen(),
            steps_per_epoch=math.ceil(
                len(train_files) /
                batch_size_train),  # number of training batch
            epochs=epoch_finetuning,
            verbose=verbose,
            validation_data=my_gen_valid.gen(),
            validation_steps=math.ceil(len(valid_files) / batch_size_valid),
            callbacks=[
                checkpointer_finetuning, change_lr_finetuning, my_callback
            ])

    #endregion

    K.clear_session()  #release GPU memory
Beispiel #13
0
def op_files_multiclass(all_files,
                        prob_total,
                        dir_preprocess,
                        dir_original='',
                        dir_dest='/tmp',
                        keep_subdir=False):

    if isinstance(all_files, str):  #csv file
        all_files, all_labels = my_data.get_images_labels(
            filename_csv_or_pd=all_files)

    for i in range(len(all_files)):
        #region  get top class, and prob of top class
        prob_list = prob_total[i].tolist()

        top_class_n = heapq.nlargest(5, range(len(prob_total[i])),
                                     prob_total[i].take)
        #top_n[0]  Softmax argmax  class no
        prob_top_class0 = round(prob_list[top_class_n[0]] * 100, 0)
        prob_top_class0 = int(prob_top_class0)
        #endregion

        img_file_source = all_files[i]

        filename = os.path.basename(img_file_source)

        if '#' in filename:  #obtain filename after #,
            filename = filename.split('#')[-1]

        filename_dest = 'prob' + str(prob_top_class0) + '#' + filename

        if keep_subdir:
            basedir = os.path.dirname(img_file_source)
            if not dir_preprocess.endswith('/'):
                dir_preprocess += '/'
            if not basedir.endswith('/'):
                basedir += '/'

            img_file_dest = os.path.join(dir_dest,
                                         basedir.replace(dir_preprocess, ''),
                                         str(top_class_n[0]), filename_dest)
        else:
            img_file_dest = os.path.join(dir_dest, str(top_class_n[0]),
                                         filename_dest)

        os.makedirs(os.path.dirname(img_file_dest), exist_ok=True)

        # copy original files instead of preprocessed images
        if dir_original != '':
            if dir_original.endswith('/'):
                dir_original = dir_original[:-1]
            if dir_preprocess.endswith('/'):
                dir_preprocess = dir_preprocess[:-1]

            img_file_source = img_file_source.replace(dir_preprocess,
                                                      dir_original)

        if not os.path.exists(img_file_source):
            raise RuntimeError(img_file_source + ' not found!')

        shutil.copy(img_file_source, img_file_dest)

        print(img_file_dest)
Beispiel #14
0
def do_predict(dicts_models, files, devices=None,
               batch_size_test=64, argmax=False,
               use_multiprocessing=True, workers=4):

    if isinstance(files, str):  #csv file
        files, _ = my_data.get_images_labels(filename_csv_or_pd=files)
    assert len(files) > 0, 'No Data'

    prob_lists = []  #each element contain all probabilities  multiple batch, np.vstack
    preds_list = []

    strategy = tf.distribute.MirroredStrategy(devices=devices)
    with strategy.scope():
        for dict_model in dicts_models:
            if ('model' not in dict_model) or (dict_model['model'] is None):
                print('prepare to load model:', dict_model['model_file'])
                model1 = keras.models.load_model(dict_model['model_file'], compile=False)
                print('load model:', dict_model['model_file'], ' complete')

                dict_model['model'] = model1
            else:
                model1 = dict_model['model']  # avoid loading models multiple times

            if 'input_shape' in dict_model:
                input_shape = dict_model['input_shape']
            elif len(model1.input_shape) == 4: #  [batch, height, width, channel]
                input_shape = model1.input_shape[1:]
            else:
                input_shape = (299, 299, 3)

            from LIBS.Generator.my_images_generator_2d import My_images_generator_2d_test
            list1 = [None] + list(input_shape)  # the last batch of an epoch may be smaller.
            shape_x = tuple(list1)  # (batch_size_train, 299, 299, 3)
            generator_test = My_images_generator_2d_test(files,
                        batch_size=batch_size_test, image_shape=input_shape)
            data_test = tf.data.Dataset.from_generator(generator=generator_test.gen,
                        output_types=(tf.float16), output_shapes=(shape_x))

            class My_callback(keras.callbacks.Callback):
                def on_predict_batch_end(self, batch, logs=None):
                    print('batch:', batch)
            probs = model1.predict(data_test,
                    callbacks=[My_callback()],
                    use_multiprocessing=use_multiprocessing, workers=workers)

            ''' #old version
            j = 0 # batch
            for x in generator_test.gen():
                probabilities = model1.predict_on_batch(x)
                if j == 0:    #'probs' not in locals().keys():
                    probs = probabilities
                else:
                    probs = np.vstack((probs, probabilities))
                j += 1
                print('batch:', j)
            '''

            prob_lists.append(probs)
            if argmax:
                y_preds = probs.argmax(axis=-1)
                y_preds = y_preds.tolist()
                preds_list.append(y_preds)

    sum_models_weights = 0
    for i, prob1 in enumerate(prob_lists):
        if 'model_weight' not in dicts_models[i]:
            model_weight = 1
        else:
            model_weight = dicts_models[i]['model_weight']

        if i == 0:
            prob_total = prob1 * model_weight
        else:
            prob_total += prob1 * model_weight

        sum_models_weights += model_weight

    prob_total /= sum_models_weights

    if argmax:
        y_pred_total = prob_total.argmax(axis=-1)
        return prob_total, y_pred_total, prob_lists, preds_list
    else:
        return prob_total, prob_lists