def configure_networks_multi(self): #—————————————— step:1 ——————————————# # 设置X\Y的容器;把标签转换成one-hot形式,为了下一步计算loss时使用; self.inputs = tf.placeholder(tf.float32, self.input_shape, name='inputs') self.annotations = tf.placeholder(tf.int64, self.output_shape, name='annotations') self.is_train = tf.placeholder(tf.bool, name='is_train') expand_annotations = tf.expand_dims(self.annotations, -1, name='annotations/expand_dims') one_hot_annotations = tf.squeeze(expand_annotations, axis=[self.channel_axis], name='annotations/squeeze') one_hot_annotations = tf.one_hot(one_hot_annotations, depth=self.conf.class_num, axis=self.channel_axis, name='annotations/one_hot') #—————————————— step:2 ——————————————# # 利用list记录每个GPU上的指标,然后concat成一个batch后再计算; tower_grads = [] tower_predictions = [] tower_rate = [] #—————————————— step:3 ——————————————#——设置优化器———# optimizer = tf.train.AdamOptimizer( learning_rate=self.conf.learning_rate, beta1=self.conf.beta1, beta2=self.conf.beta2, epsilon=self.conf.epsilon) #—————————————— step:4 ——————————————#——多个GPU的计算———# # tf.variable_scope 作用:指定变量的作用域,用于变量共享 with tf.variable_scope(tf.get_variable_scope()): for i in range(self.conf.gpu_num): print("this is %d gpu" % i) with tf.device("/gpu:%d" % i): with tf.name_scope("tower_%d" % i): # 拆分数据给每个GPU;并把标签转换成one-hot形式,为了下一步计算loss时使用; self.x = self.inputs[i * self.conf.batch:(i + 1) * self.conf.batch] self.y = self.annotations[i * self.conf.batch:(i + 1) * self.conf.batch] expand_y = tf.expand_dims(self.y, -1, name='y/expand_dims') one_hot_y = tf.squeeze(expand_y, axis=[self.channel_axis], name='y/squeeze') one_hot_y = tf.one_hot(one_hot_y, depth=self.conf.class_num, axis=self.channel_axis, name='y/one_hot') # 计算预测出来的Y if self.conf.network_name == "ascnet": model = Ascnet(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference( self.inputs) if self.conf.network_name == "segnet": model = Segnet(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference( self.inputs) if self.conf.network_name == "deeplabv3": model = Deeplabv3(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference( self.inputs) if self.conf.network_name == "deeplabv3plus": model = Deeplabv3plus(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference( self.inputs) if self.conf.network_name == "unet": model = Unet(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference( self.inputs) if self.conf.network_name == "pspnet": model = Pspnet(self.sess, self.conf, self.is_train) self.predictions, self.rates, self.pred2 = model.inference( self.inputs) # 计算loss # Camvid 数据集的weight #weights = [0.01,0.007,0.161,0.007,0.02,0.016,0.18, 0.15,0.04,0.29,1.0,0.04] #weights = tf.convert_to_tensor(weights) #将list转成tensor, shape为[50, ] #weights = tf.reduce_sum(tf.multiply(one_hot_annotations, weights), -1, name='loss/weights') # 采用有weights的loss #losses = tf.losses.softmax_cross_entropy(one_hot_y, prediction, weights=weights, scope='loss/losses') # 采用普通的loss losses = tf.losses.softmax_cross_entropy( one_hot_y, prediction, scope='loss/losses') loss_each = tf.reduce_mean(losses, name='loss/loss_each') if self.conf.network_name == "pspnet": # 采用有weights的loss #losses2 = tf.losses.softmax_cross_entropy(one_hot_annotations, self.pred2, weights=weights, scope='loss/losses2') # 采用普通的loss losses2 = tf.losses.softmax_cross_entropy( one_hot_annotations, self.pred2, scope='loss/losses2') loss_each2 = tf.reduce_mean(losses2, name='loss/loss_op2') loss_each = loss_each + loss_each2 * 0.4 # 共享变量:在第一次声明变量之后,将控制变量重用的参数设置为True,这样可以让不同的GPU更新同一组参数 # 注意tf.name_scope函数并不会影响tf.get_variable的命名空间,它只影响tf.variable的 tf.get_variable_scope().reuse_variables() # 计算梯度;并保存当前GPU上的指标; grads = optimizer.compute_gradients(loss_each) tower_grads.append(grads) tower_predictions.append(prediction) tower_rate.append(rate) #—————————————— step:5 ——————————————# # 计算平均梯度;并设置训练OP grads = self.average_gradients(tower_grads) # 添加一些需要训练的变量作为train_op依赖项 # optimizer.apply_gradients作用:在计算完梯度后,最小化梯度的操作,相当于optimizer.minimize的第二步 # 添加一些需要训练的变量作为train_op依赖项,主要是为了使用BN update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) with tf.control_dependencies(update_ops): self.train_op = optimizer.apply_gradients(grads, name='train_op') #—————————————— step:6 ——————————————# # 计算评价指标 # 1)计算self.predictions 和 self.rates for i in range(self.conf.gpu_num): if i == 0: preds = tower_predictions[i] r = tower_rate[i] else: preds = tf.concat([preds, tower_predictions[i]], self.batch_axis, name='preds/concat' + str(i)) r = tf.concat([r, tower_rate[i]], self.batch_axis, name='r/concat' + str(i)) self.predictions = preds self.rates = r # 2)计算loss loss_merge = tf.losses.softmax_cross_entropy(one_hot_annotations, self.predictions, scope='loss/loss_merge') self.loss_op = tf.reduce_mean(loss_merge, name='loss/loss_op') # 3)计算accuracy self.decoded_predictions = tf.argmax(self.predictions, self.channel_axis, name='accuracy/decode_pred') correct_prediction = tf.equal(self.annotations, self.decoded_predictions, name='accuracy/correct_pred') self.accuracy_op = tf.reduce_mean(tf.cast(correct_prediction, tf.float32, name='accuracy/cast'), name='accuracy/accuracy_op') # 4)计算miou weights = tf.cast(tf.greater(self.decoded_predictions, 0, name='m_iou/greater'), tf.int32, name='m_iou/weights') self.m_iou, self.miou_op = tf.metrics.mean_iou( self.annotations, self.decoded_predictions, self.conf.class_num, weights, name='m_iou/m_ious') # 5)计算dice self.out = self.decoded_predictions self.gt = self.annotations #—————————————— step:7 ——————————————#——初始化全局变量———# tf.set_random_seed(self.conf.random_seed) self.sess.run(tf.global_variables_initializer()) for v in tf.global_variables(): print(v.name) #—————————————— step:8 ——————————————# # 用于保存模型和summary # 保存BN中不可训练的参数,自己去找那些参数 trainable_vars = tf.trainable_variables() #可训练的参数 g_list = tf.global_variables() bn_moving_vars = [ g for g in g_list if 'batch_norm/moving_mean' in g.name ] bn_moving_vars += [ g for g in g_list if 'batch_norm/moving_variance' in g.name ] trainable_vars += bn_moving_vars self.saver = tf.train.Saver(var_list=trainable_vars, max_to_keep=0) self.writer = tf.summary.FileWriter(self.conf.logdir, self.sess.graph)
def configure_networks_single(self): #—————————————— step:1 ——————————————# # 设置X\Y的容器;把标签转换成one-hot形式,为了下一步计算loss时使用; self.inputs = tf.placeholder(tf.float32, self.input_shape, name='inputs') self.annotations = tf.placeholder(tf.int64, self.output_shape, name='annotations') self.is_train = tf.placeholder(tf.bool, name='is_train') expand_annotations = tf.expand_dims(self.annotations, -1, name='annotations/expand_dims') one_hot_annotations = tf.squeeze(expand_annotations, axis=[self.channel_axis], name='annotations/squeeze') one_hot_annotations = tf.one_hot(one_hot_annotations, depth=self.conf.class_num, axis=self.channel_axis, name='annotations/one_hot') #—————————————— step:2 ——————————————# # 根据搭建的模型计算预测出来的Y;除了预测值可能还包括一些其他想输出的参数; if self.conf.network_name == "ascnet": model = Ascnet(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference(self.inputs) if self.conf.network_name == "segnet": model = Segnet(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference(self.inputs) if self.conf.network_name == "deeplabv3": model = Deeplabv3(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference(self.inputs) if self.conf.network_name == "deeplabv3plus": model = Deeplabv3plus(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference(self.inputs) if self.conf.network_name == "unet": model = Unet(self.sess, self.conf, self.is_train) self.predictions, self.rates = model.inference(self.inputs) if self.conf.network_name == "pspnet": model = Pspnet(self.sess, self.conf, self.is_train) self.predictions, self.rates, self.pred2 = model.inference( self.inputs) #—————————————— step:3 ——————————————# # 根据预测值和one-hot的标签计算loss,选择softmax_cross_entropy损失函数; # Camvid 数据集的weight #weights = [0.01,0.007,0.161,0.007,0.02,0.016,0.18, 0.15,0.04,0.29,1.0,0.04] #weights = tf.convert_to_tensor(weights) #将list转成tensor, shape为[50, ] #weights = tf.reduce_sum(tf.multiply(one_hot_annotations, weights), -1, name='loss/weights') # 采用有weights的loss #losses = tf.losses.softmax_cross_entropy(one_hot_annotations, self.predictions, weights=weights, scope='loss/losses') # 采用普通的loss losses = tf.losses.softmax_cross_entropy(one_hot_annotations, self.predictions, scope='loss/losses') self.loss_op = tf.reduce_mean(losses, name='loss/loss_op') # PSPnet有特殊的辅助loss if self.conf.network_name == "pspnet": # 采用有weights的loss #losses2 = tf.losses.softmax_cross_entropy(one_hot_annotations, self.pred2, weights=weights, scope='loss/losses2') # 采用普通的loss losses2 = tf.losses.softmax_cross_entropy(one_hot_annotations, self.pred2, scope='loss/losses2') self.loss_op2 = tf.reduce_mean(losses2, name='loss/loss_op2') self.loss_op = self.loss_op + self.loss_op2 * 0.4 #—————————————— step:4 ——————————————# # 选择优化器和学习率,设置训练使用的 train_op optimizer = tf.train.AdamOptimizer( learning_rate=self.conf.learning_rate, beta1=self.conf.beta1, beta2=self.conf.beta2, epsilon=self.conf.epsilon) # 添加一些需要训练的变量作为train_op依赖项,主要是为了使用BN update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) with tf.control_dependencies(update_ops): self.train_op = optimizer.minimize(self.loss_op, name='train_op') #—————————————— step:5 ——————————————# # 计算三个评价指标:accuracy、miou、dice,因为没有直接计算dice的函数, # 所以保存的是预测值和标签,在验证时再用他们计算dice # 1)计算accuracy self.decoded_predictions = tf.argmax(self.predictions, self.channel_axis, name='accuracy/decode_pred') correct_prediction = tf.equal(self.annotations, self.decoded_predictions, name='accuracy/correct_pred') self.accuracy_op = tf.reduce_mean(tf.cast(correct_prediction, tf.float32, name='accuracy/cast'), name='accuracy/accuracy_op') # 2)计算miou weights = tf.cast(tf.greater(self.decoded_predictions, 0, name='m_iou/greater'), tf.int32, name='m_iou/weights') self.m_iou, self.miou_op = tf.metrics.mean_iou( self.annotations, self.decoded_predictions, self.conf.class_num, weights, name='m_iou/m_ious') # 3)计算dice----保存需要用的gt和out self.out = tf.cast(self.decoded_predictions, tf.float32) self.gt = tf.cast(self.annotations, tf.float32) #—————————————— step:6 ——————————————# # 初始化全局变量,这一步需要在session运行训练之前做 tf.set_random_seed(self.conf.random_seed) self.sess.run(tf.global_variables_initializer()) #—————————————— step:7 ——————————————# # 用于保存模型和summary # 保存BN中不可训练的参数,自己去找那些参数 trainable_vars = tf.trainable_variables() #可训练的参数 g_list = tf.global_variables() bn_moving_vars = [ g for g in g_list if 'batch_norm/moving_mean' in g.name ] bn_moving_vars += [ g for g in g_list if 'batch_norm/moving_variance' in g.name ] trainable_vars += bn_moving_vars self.saver = tf.train.Saver(var_list=trainable_vars, max_to_keep=0) self.writer = tf.summary.FileWriter(self.conf.logdir, self.sess.graph)
def train_model(constants, model_index, frame, repeat_index, history_path): model_name = constants.model_names[model_index] dataset_folder = constants.dataset_folders[model_index] dataset_name = constants.dataset_names[model_index] img_folder = constants.img_folders[model_index] img_path = dataset_folder + dataset_name + img_folder print(' round_num:', constants.round_num, ' model name:', model_name, ' frame:', frame, ' repeat_index:', repeat_index) args = constants.get_train_args() # get hyper parameters # leave-one-movie-out cross validation, don't use test movie train_val_dataset_names = [ x for i, x in enumerate(constants.dataset_names) if i != model_index ] print('train_val_dataset_names:', train_val_dataset_names) if 'paxillin_TIRF' in train_val_dataset_names[0] and \ ('specialist' in constants.strategy_type or 'single_micro' in constants.strategy_type): process_type = 'normalize' else: process_type = 'standardize' # dataset_train_generator, dataset_validation_generator = get_data_generators(constants.round_num, train_val_dataset_names, # model_name, frame, repeat_index, constants.img_format, args.batch_size, process_type, img_path, history_path) train_x, train_y, valid_x, valid_y = get_data_generators( constants.round_num, train_val_dataset_names, model_name, frame, repeat_index, constants.img_format, args.batch_size, process_type, history_path) # ------------------- Model Creation --------------------------- pretrained_weights_path = constants.get_pretrained_weights_path( frame, model_name) if "Res50V2" == str(constants.strategy_type): model = ResNet50V2Keras(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "InceptionResV2" == str(constants.strategy_type): model = InceptionResV2(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "Dense201" == str(constants.strategy_type): model = DenseNet201Keras(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "deeplabv3" == str(constants.strategy_type): K.set_image_data_format('channels_last') dataset_train = np.moveaxis(dataset_train, 1, -1) # first channel to last channel dataset_mask = np.moveaxis(dataset_mask, 1, -1) print(dataset_train.dtype, dataset_train.shape) print(dataset_mask.dtype, dataset_mask.shape) model = Deeplabv3(input_shape=(args.input_size, args.input_size, 3), output_shape=(68, 68), right_crop=0, bottom_crop=0) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_dropout" == str(constants.strategy_type): model = VGG16_dropout(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_batchnorm" == str(constants.strategy_type): model = VGG16_batchnorm(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_instancenorm" == str(constants.strategy_type): model = VGG16_instancenorm(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_movie3" == str(constants.strategy_type): model = VGG16_movie(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=loss.temporal_cross_entropy, metrics=[loss.dice_coef]) elif "VGG16_dice" == str(constants.strategy_type): model = VGG16(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=[loss.dice_coef], metrics=['binary_crossentropy']) elif "VGG16_l2" == str(constants.strategy_type): model = VGG16_l2(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_dac_input256" == constants.strategy_type: model = VGG16_dac(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_spp_input256" == constants.strategy_type: model = VGG16_spp(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_no_pretrain" == str(constants.strategy_type): model = VGG16(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path, encoder_weights=None) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16" in str(constants.strategy_type): model = VGG16(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_dropout_dac_input256" == str(constants.strategy_type): model = VGG19_dropout_dac(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_dropout_feature_extractor" in str(constants.strategy_type): model = VGG19_dropout_feature_extractor( args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy', loss.zero_loss], metrics=[loss.dice_coef, loss.zero_loss]) elif "VGG19_batchnorm_dropout" in str(constants.strategy_type): model = VGG19_batchnorm_dropout(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_dropout" in str(constants.strategy_type): model = VGG19_dropout(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_batchnorm" == str(constants.strategy_type): model = VGG19_batchnorm(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_no_pretrain" == str(constants.strategy_type): model = VGG19(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path, encoder_weights=None) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19" in str(constants.strategy_type): model = VGG19(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "EFF_B7" == str( constants.strategy_type) or "EFF_B7_no_preprocessing" == str( constants.strategy_type): K.set_image_data_format('channels_last') dataset_train = np.moveaxis(dataset_train, 1, -1) # first channel to last channel dataset_mask = np.moveaxis(dataset_mask, 1, -1) print(dataset_train.dtype, dataset_train.shape) print(dataset_mask.dtype, dataset_mask.shape) model = EFF_B7(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "unet_feature_extractor" in str(constants.strategy_type): model = UNet_feature_extractor(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy', loss.zero_loss], metrics=[loss.dice_coef, loss.zero_loss]) elif "unet" in str(constants.strategy_type): model = UNet(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) # ------------ Sanity Check the Model ------------ print(model.summary()) print('Num of layers: ', len(model.layers)) # print('FLOPS: ', get_flops()) # run this after model compilation # check_loaded_weights(constants) if repeat_index == 0: plot_model(model, to_file='model_plots/model_round{}_{}_train.png'.format( constants.round_num, constants.strategy_type), show_shapes=True, show_layer_names=True, dpi=144) # ------------ Fit the Model ------------ print('Fit Model...', args.epochs, args.patience) earlyStopping = EarlyStopping(monitor='val_loss', patience=args.patience, verbose=0, mode='auto') # args.patience model_checkpoint = ModelCheckpoint( 'results/model_round{}_{}/model_frame{}_{}_repeat{}.hdf5'.format( constants.round_num, constants.strategy_type, str(frame), model_name, str(repeat_index)), monitor='val_loss', save_best_only=True) time_callback = TimeHistory() logdir = 'results/history_round{}_{}/tensorboard_frame{}_{}_repeat{}_{}'.format( constants.round_num, constants.strategy_type, str(frame), model_name, str(repeat_index), datetime.now().strftime("%Y%m%d-%H%M%S")) # reference https://github.com/tensorflow/tensorflow/blob/v2.4.1/tensorflow/python/keras/engine/training.py#L1823-L1861 # hist = model.fit(dataset_train_generator, # epochs=args.epochs, # verbose=1, # workers=1, # validation_data=dataset_validation_generator, # callbacks=[model_checkpoint, earlyStopping, time_callback, TensorBoard(log_dir=logdir)]) hist = model.fit(train_x, train_y, epochs=args.epochs, verbose=1, workers=1, validation_data=(valid_x, valid_y), callbacks=[ model_checkpoint, earlyStopping, time_callback, TensorBoard(log_dir=logdir) ]) # ------------ Save the History ------------ hist.history['times'] = time_callback.times print('Save History...') np.save( 'results/history_round{}_{}/history_frame{}_{}_repeat{}.npy'.format( constants.round_num, constants.strategy_type, str(frame), model_name, str(repeat_index)), hist.history) K.clear_session() return
def predict(model_name, mask_save=False, combine_save=True, crf_treat=True, keep_path_struct=True): ''' 参数说明: mask_save:设定是否单独保存预测结果 combine_save:设定是否保存与原图的融合结果 crf_treat:设定是否将预测结果进行CRF后处理---该处理目的是使得预测边缘平滑化,减少误判 keep_path_struct:设定预测结果的保存,是否遵循原预测文件的架构。False代表统一存放到设定的文件夹下 ''' def real_pred(imgs): for nums, jpg in enumerate(imgs): img_name = os.path.basename(jpg) img_dir = os.path.dirname(jpg) if keep_path_struct: save_path = img_dir.replace(test_path, result_path) + "/" if not os.path.exists(save_path): os.makedirs(save_path) else: save_path = result_path + "/" img = cv2.imread(jpg) img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) #通道转换 old_img = copy.deepcopy(img) orininal_h, orininal_w = old_img.shape[:2] img = letterbox_image(img, (HEIGHT, WIDTH)) #先处理成原始模型训练的尺寸大小 img = img / 255 img = img.reshape(-1, HEIGHT, WIDTH, 3) pr = model.predict(img)[0] if crf_treat: pr = pr.reshape((-1, HEIGHT, WIDTH, NCLASSES)) temp_img = letterbox_image( old_img, (HEIGHT, WIDTH)) #原图需要先转成训练时指定的图片大小 temp_img = temp_img[np.newaxis, ...] #需增加一个维度,方便输入CRF处理 pr = dense_crf(pr, img=temp_img, n_classes=NCLASSES) #增加CRF后处理 pr = pr.reshape( (HEIGHT, WIDTH, NCLASSES)).argmax(axis=-1) #将刚检测出来的图片,转成单通道的标签图片大小的数据格式 pr = np.uint8(pr) pr = cv2.resize(pr, (orininal_w, orininal_h)) for num in range(1, NCLASSES): #逐个将每个类别的像素值,计入各自的列表中 num_cal = Counter( pr[pr == num])[num] #Counter的结果类似一个字典,直接取其键值 areas[classes[num]].append(num_cal) if mask_save: mask = label2rgb(pr, n_labels=len(classes), colormap=colors, mask_save=mask_save) #给mask上色, 注释掉则变单通道图 B, G, R = cv2.split(mask) A = np.zeros(B.shape, dtype=B.dtype) #增加alpha通道,方便前端调用 A[B > 0] = 255 mask = cv2.merge((B, G, R, A)) cv2.imwrite(save_path + img_name[:-4] + ".png", mask) if combine_save: image = draw_label(pr, old_img, classes, colormap=colors) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) cv2.imwrite(save_path + img_name, image) print('文件夹%s的第%d张图片检测完毕' % (img_dir, nums + 1)) if model_name == "deeplabv3": model = Deeplabv3(input_shape=(HEIGHT, WIDTH, 3), classes=NCLASSES, bone_name=bone_name) elif model_name == 'unet': model = Unet(input_shape=(HEIGHT, WIDTH, 3), classes=NCLASSES, bone_name=bone_name) elif model_name == 'pspnet': model = PSPnet(input_shape=(HEIGHT, WIDTH, 3), classes=NCLASSES, bone_name=bone_name) log_name = os.path.basename(find_last(log_path)) print('-' * 100) print('Loading log_name of %s' % log_name) print('-' * 100) model.load_weights(find_last(log_path), by_name=True) #需要根据类别数,来随机设定不同类别的mask对应的颜色 colors = label_colormap(NCLASSES) #定义函数来确定不同类别的颜色,相对颜色识别度较高。 total_area = 0 #初始化总面积 areas = {} #设置空字典,用于存放每张图片各个类别的面积,并最终求和 for num in range(1, NCLASSES): #先初始化每个类别,用于存放每张图得到的各类别像素点个数 areas[classes[num]] = [] print('开始检测...') for roots, _, _ in os.walk(test_path): #递归遍历多级子目录 imgs = glob.glob(roots + "/*.jpg") #这里需注意,如果原图片是png格式的,需更改成.png real_pred(imgs) #统计各类别的面积 f = open(result_path + '/area.txt', 'w') for num in range(1, NCLASSES): area = sum(areas[classes[num]]) total_area += area f.write('%s area is : %.2f m2 \n' % (classes[num], area * area_per_pixel)) f.write('total area is : %.2f m2' % (total_area * area_per_pixel)) f.close() t_end = time.time() time_total = pd.to_timedelta(t_end - t_start, unit='s') print('%s_%s模型检测结束, 检测图片%s张, 结束时间为%s, 总耗时%s秒' % (bone_name, model_name, len(areas[classes[num]]), time.strftime('%Y-%m-%d %H:%M:%S'), time_total.round('s')))
def train_model(constants, model_index, frame, repeat_index): print(constants.model_names[model_index], ' frame:', frame, ' round_num:', constants.round_num, ' repeat_index:', repeat_index) training_dataset = get_training_dataset(constants, model_index, frame, repeat_index) comb_train = training_dataset['arr_0'] comb_mask = training_dataset['arr_1'] # ------------ process dataset ---------------- comb_train, comb_mask = unison_shuffled_copies(comb_train, comb_mask) # if frame == 1 and repeat_index == 0: # img_path = constants.dataset_folder + '/' + constants.dataset_names[model_index] + constants.img_folder # show_cropped_image(comb_train, comb_mask, img_path, constants.img_format, constants.strategy_type, # f'results/debugger/round{constants.round_num}_{constants.strategy_type}/{constants.dataset_names[model_index]}_frame{frame}_repeat{repeat_index}/') print(comb_train.dtype, comb_train.shape) print(comb_mask.dtype, comb_mask.shape) print('----------') # ------------------- Model Creation --------------------------- # Set Model Hyper Parameters args = constants.get_train_args() pretrained_weights_path = constants.get_pretrained_weights_path( frame, constants.model_names[model_index]) print('Load Model...') if "Res50V2" == str(constants.strategy_type): model = ResNet50V2Keras(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "InceptionResV2" == str(constants.strategy_type): model = InceptionResV2(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "Dense201" == str(constants.strategy_type): model = DenseNet201Keras(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "deeplabv3" == str(constants.strategy_type): K.set_image_data_format('channels_last') comb_train = np.moveaxis(comb_train, 1, -1) # first channel to last channel comb_mask = np.moveaxis(comb_mask, 1, -1) print(comb_train.dtype, comb_train.shape) print(comb_mask.dtype, comb_mask.shape) model = Deeplabv3(input_shape=(args.input_size, args.input_size, 3), output_shape=(68, 68), right_crop=0, bottom_crop=0) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_dropout" == str(constants.strategy_type): model = VGG16_dropout(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_batchnorm" == str(constants.strategy_type): model = VGG16_batchnorm(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_instancenorm" == str(constants.strategy_type): model = VGG16_instancenorm(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_movie3" == str(constants.strategy_type): model = VGG16_movie(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=loss.temporal_cross_entropy, metrics=[loss.dice_coef]) elif "VGG16_dice" == str(constants.strategy_type): model = VGG16(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=[loss.dice_coef], metrics=['binary_crossentropy']) elif "VGG16_l2" == str(constants.strategy_type): model = VGG16_l2(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_dac_input256" == constants.strategy_type: model = VGG16_dac(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_spp_input256" == constants.strategy_type: model = VGG16_spp(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16_no_pretrain" == str(constants.strategy_type): model = VGG16(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path, encoder_weights=None) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG16" in str(constants.strategy_type): model = VGG16(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_dropout_dac_input256" == str(constants.strategy_type): model = VGG19_dropout_dac(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_dropout_feature_extractor" in str(constants.strategy_type): model = VGG19_dropout_feature_extractor( args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy', loss.zero_loss], metrics=[loss.dice_coef, loss.zero_loss]) elif "VGG19_batchnorm_dropout" in str(constants.strategy_type): model = VGG19_batchnorm_dropout(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_dropout" in str(constants.strategy_type): model = VGG19_dropout(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_batchnorm" == str(constants.strategy_type): model = VGG19_batchnorm(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19_no_pretrain" == str(constants.strategy_type): model = VGG19(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path, encoder_weights=None) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "VGG19" in str(constants.strategy_type): model = VGG19(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "EFF_B7" == str( constants.strategy_type) or "EFF_B7_no_preprocessing" == str( constants.strategy_type): K.set_image_data_format('channels_last') comb_train = np.moveaxis(comb_train, 1, -1) # first channel to last channel comb_mask = np.moveaxis(comb_mask, 1, -1) print(comb_train.dtype, comb_train.shape) print(comb_mask.dtype, comb_mask.shape) model = EFF_B7(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) elif "unet_feature_extractor" in str(constants.strategy_type): model = UNet_feature_extractor(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy', loss.zero_loss], metrics=[loss.dice_coef, loss.zero_loss]) elif "unet" in str(constants.strategy_type): model = UNet(args.input_size, args.input_size, args.cropped_boundary, 0, 0, weights_path=pretrained_weights_path) model.compile(optimizer=Adam(lr=1e-5), loss=['binary_crossentropy'], metrics=[loss.dice_coef]) # ------------ Sanity Check the Model ------------ print(model.summary()) print('Num of layers: ', len(model.layers)) # print('FLOPS: ', get_flops()) # run this after model compilation # check_loaded_weights(constants) if repeat_index == 0: plot_model(model, to_file='model_plots/model_round{}_{}_train.png'.format( constants.round_num, constants.strategy_type), show_shapes=True, show_layer_names=True, dpi=144) # ------------ Fit the Model ------------ print('Fit Model...', args.patience) earlyStopping = EarlyStopping(monitor='val_loss', patience=args.patience, verbose=0, mode='auto') model_checkpoint = ModelCheckpoint( 'results/model_round{}_{}/model_frame{}_{}_repeat{}.hdf5'.format( constants.round_num, constants.strategy_type, str(frame), constants.model_names[model_index], str(repeat_index)), monitor='val_loss', save_best_only=True) time_callback = TimeHistory() if "feature_extractor" in str(constants.strategy_type): hist = model.fit( comb_train, [comb_mask, []], batch_size=args.batch_size, epochs=args.epochs, validation_split=args.validation_split, verbose=1, shuffle=True, callbacks=[model_checkpoint, earlyStopping, time_callback]) else: hist = model.fit( comb_train, comb_mask, batch_size=args.batch_size, epochs=args.epochs, validation_split=args.validation_split, verbose=1, shuffle=True, callbacks=[model_checkpoint, earlyStopping, time_callback]) # ------------ Save the History ------------ hist.history['times'] = time_callback.times print('Save History...') np.save( 'results/history_round{}_{}/history_frame{}_{}_repeat{}.npy'.format( constants.round_num, constants.strategy_type, str(frame), constants.model_names[model_index], str(repeat_index)), hist.history) K.clear_session() return
def build_train_model(self): return Deeplabv3(weights='pascal_voc',input_shape=(500, 500, 3), classes=21,activation='softmax')
def prediction(constants, model_name, dataset_folder, dataset_name, frame, repeat_index, img_folder, save_path): img_path = dataset_folder + dataset_name + img_folder if constants.self_training_type is None: save_path = save_path + '{}/frame{}_{}_repeat{}/'.format( dataset_name, str(frame), model_name, str(repeat_index)) else: save_path = save_path + '{}_{}/frame{}_repeat{}/'.format( model_name, dataset_name, str(frame), str(repeat_index)) print('save_path:', save_path) if os.path.isdir(save_path) == 0: os.makedirs(save_path) # ------------------- Data loading ------------------- a_strategy = constants.strategy_type if 'TIRF' in dataset_name and 'specialist' in constants.strategy_type: a_strategy = constants.strategy_type + '_normalize' prediction_data_generator = DataGenerator(img_path, frame, 128, 68, a_strategy, img_format=constants.img_format) imgs_val, namelist, image_cols, image_rows, orig_cols, orig_rows = prediction_data_generator.get_expanded_whole_frames( ) print('img size:', image_rows, image_cols) print('orig img size:', orig_rows, orig_cols) print('imgs_val: ', imgs_val.dtype, imgs_val.shape) # ------------------- Load trained Model ------------------- weights_path = constants.get_trained_weights_path(str(frame), model_name, str(repeat_index)) # print(debugger.check_loaded_weights(weights_path)) if "Res50V2" == str(constants.strategy_type): model = ResNet50V2Keras(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "Dense201" == str(constants.strategy_type): model = DenseNet201Keras(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "InceptionResV2" == str(constants.strategy_type): model = InceptionResV2(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "deeplabv3" == str(constants.strategy_type): K.set_image_data_format('channels_last') imgs_val = np.moveaxis(imgs_val, 1, -1) # first channel to last channel print(imgs_val.dtype, imgs_val.shape) model = Deeplabv3(input_shape=(image_rows, image_cols, 3), output_shape=(orig_rows, orig_cols)) model.load_weights(weights_path, by_name=True) elif "VGG16_dropout" == str(constants.strategy_type): model = VGG16_dropout(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG16_batchnorm" == str(constants.strategy_type): model = VGG16_batchnorm(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG16_instancenorm" == str(constants.strategy_type): model = VGG16_instancenorm(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "movie3" in str(constants.strategy_type): model = VGG16_movie(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG16_dac_input256" == constants.strategy_type: model = VGG16_dac(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG16_spp_input256" == constants.strategy_type: model = VGG16_spp(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG16" in str(constants.strategy_type): model = VGG16(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG19_dropout_dac" in str(constants.strategy_type): model = VGG19_dropout_dac(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG19_dropout_feature_extractor" in str(constants.strategy_type): model = VGG19_dropout_feature_extractor(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG19_batchnorm_dropout" == str(constants.strategy_type): model = VGG19_batchnorm_dropout(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG19_batchnorm" == str(constants.strategy_type): model = VGG19_batchnorm(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG19_dropout" in str(constants.strategy_type): model = VGG19_dropout(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "VGG19" in str(constants.strategy_type): model = VGG19(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path, encoder_weights=None) elif "EFF_B7" == str( constants.strategy_type) or "EFF_B7_no_preprocessing" == str( constants.strategy_type): K.set_image_data_format('channels_last') imgs_val = np.moveaxis(imgs_val, 1, -1) # first channel to last channel print(imgs_val.dtype, imgs_val.shape) model = EFF_B7(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "unet_feature_extractor" in str(constants.strategy_type): model = UNet_feature_extractor(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) elif "unet" in str(constants.strategy_type): model = UNet(image_rows, image_cols, 0, image_cols - orig_cols, image_rows - orig_rows, weights_path=weights_path) print('model layers: ', len(model.layers)) plot_model(model, to_file='model_plots/model_round{}_{}_predict.png'.format( constants.round_num, constants.strategy_type), show_shapes=True, show_layer_names=True, dpi=144) # ------------------- predict segmented images and save them ------------------- if "feature_extractor" in str(constants.strategy_type): segmented_output, style_output = model.predict(imgs_val, batch_size=1, verbose=1) np.save(save_path + 'style_feature_vector.npy', style_output) else: segmented_output = model.predict(imgs_val, batch_size=1, verbose=1) segmented_output = 255 * segmented_output # 0=black color and 255=white color if "deeplabv3" == str(constants.strategy_type) or "EFF_B7" == str( constants.strategy_type) or "EFF_B7_no_preprocessing" == str( constants.strategy_type): # move last channel to first channel segmented_output = np.moveaxis(segmented_output, -1, 1) print(segmented_output.shape) for f in range(len(namelist)): if constants.strategy_type == 'movie3' or constants.strategy_type == 'movie3_loss': out = segmented_output[f, 1, :, :] else: out = segmented_output[f, 0, :, :] cv2.imwrite(save_path + namelist[f], out) K.clear_session()
import cv2 import numpy as np from deeplabv3 import Deeplabv3 deeplab_model = Deeplabv3() vid = cv2.VideoCapture(0) blurValue = (41,41) while True: ret, frame = vid.read() w, h, _ = frame.shape ratio = 512. / np.max([w,h]) resized = cv2.resize(frame,(int(ratio*h),int(ratio*w))) resized = resized / 127.5 - 1. pad_x = int(512 - resized.shape[0]) resized2 = np.pad(resized,((0,pad_x),(0,0),(0,0)),mode='constant') res = deeplab_model.predict(np.expand_dims(resized2,0)) labels = np.argmax(res.squeeze(),-1) labels = labels[:-pad_x-25] mask = labels == 0 resizedFrame = cv2.resize(frame, (labels.shape[1],labels.shape[0])) blur = cv2.GaussianBlur(resizedFrame,blurValue,0) cv2.imshow("resized", resizedFrame) resizedFrame[mask] = 0 cv2.imshow("result",resizedFrame) if cv2.waitKey(1) & 0xFF == ord('q'): break
def train_model(train_data, val_data, num_train, num_val, epochs, callback=True): #callback用于是否记录训练。 if model_name == "deeplabv3": model = Deeplabv3((HEIGHT, WIDTH, 3), NCLASSES, bone_name) elif model_name == 'unet': model = Unet((HEIGHT, WIDTH, 3), NCLASSES, bone_name) elif model_name == 'pspnet': model = PSPnet((HEIGHT, WIDTH, 3), NCLASSES, bone_name) epoch = 0 if init_with == 'first': #init_with selection = ['first', 'last'] 选择模型的训练模式 print('-' * 100) # model.load_weights(weights_path, by_name=True, skip_mismatch=True) #加载预训练模型 print('开始从头训练模型...') else: model.load_weights(find_last(log_path), by_name=True) epoch = int( os.path.basename(find_last(log_path))[:-3].split('_')[-1]) epochs = epoch + epochs #这样可以确保重新训练时,设置的epochs为实际训练的轮数。 print('-' * 100) print('成功加载最新模型, 重新从第%s轮开始训练...' % epoch) #保存训练过程 tbCallBack = TensorBoard(log_dir=log_path + "records/", histogram_freq=0, write_graph=True, write_images=True) # 保存的方式,1次epoch保存一次 checkpoint_path = os.path.join( log_path, '%s_%s_*epoch*.h5' % (model_name, bone_name)) checkpoint_path = checkpoint_path.replace("*epoch*", "{epoch:04d}") checkpoint_period = ModelCheckpoint(checkpoint_path, monitor='val_loss', save_weights_only=True, save_best_only=True, period=1) # 学习率下降的方式,val_loss五次不下降就下降学习率继续训练 reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=5, verbose=1) # 是否需要早停,当val_loss一直不下降的时候意味着模型基本训练完毕,可以停止 early_stopping = EarlyStopping(monitor='val_loss', min_delta=0, patience=15, verbose=1) callbacks = [checkpoint_period, reduce_lr, early_stopping] if callback: tbCallBack.set_model(model) callbacks.append(tbCallBack) print('训练的样本量为:{} 张图片, 验证集的样本量为:{} 张图片,'.format(num_train, num_val)) print('每份数据集大小为:{} 张图片, 图片大小为: {}'.format(batch_size, (HEIGHT, WIDTH))) print('以%s为主干的%s模型正式开始训练,请耐心等待,并注意提示...' % (bone_name, model_name)) #开始训练 print('-' * 100) model.compile(loss=focal_loss, optimizer=Adam(lr=1e-3), metrics=['accuracy']) model.fit_generator(generate_arrays_from_file(train_data, batch_size), steps_per_epoch=max(1, num_train // batch_size), validation_data=generate_arrays_from_file( val_data, batch_size), validation_steps=max(1, num_val // batch_size), epochs=epochs, initial_epoch=epoch, shuffle=True, callbacks=callbacks)