def restore_tf_checkpoint(conf, sess, path_to_model): sess.run(tf.compat.v1.initialize_all_variables()) model = tf.keras.models.load_model( path_to_model, custom_objects={ 'PriorBox': PriorBox, 'compute_loss': MultiboxLoss(21, neg_pos_ratio=2.0).compute_loss }) # print('tf version: {}'.format(tf.__version__)) # # predictions_target # sess.run(tf.compat.v1.initialize_all_variables()) # tf_meta_path = glob('{}/*.meta'.format(conf['tf_model_path']))[0] # saver = tf.compat.v1.train.import_meta_graph(tf_meta_path) # saver.restore(sess, tf.compat.v1.train.latest_checkpoint(conf['tf_model_path'])) # graph = tf.compat.v1.get_default_graph() # # input_placeholder = graph.get_tensor_by_name(conf['input_node']) # output_placeholder = graph.get_tensor_by_name(conf['output_node']) # # return { # 'sess': sess, # 'in': input_placeholder, # 'out': output_placeholder # } return model
def restore_tf_checkpoint(conf, sess, checkpoint=None): if not checkpoint: print('tf version: {}'.format(tf.__version__)) sess.run(tf.compat.v1.initialize_all_variables()) model = tf.keras.models.load_model( conf['tf_model_path'] + '/saved_model.h5', custom_objects={ 'PriorBox': PriorBox, 'compute_loss': MultiboxLoss(21, neg_pos_ratio=2.0).compute_loss }) return model else: # predictions_target sess.run(tf.compat.v1.initialize_all_variables()) tf_meta_path = glob('{}/*.meta'.format(checkpoint))[0] saver = tf.compat.v1.train.import_meta_graph(tf_meta_path) saver.restore(sess, tf.compat.v1.train.latest_checkpoint(checkpoint)) graph = tf.compat.v1.get_default_graph() input_placeholder = graph.get_tensor_by_name(conf['input_node']) output_placeholder = graph.get_tensor_by_name(conf['output_node']) return { 'sess': sess, 'in': input_placeholder, 'out': output_placeholder }
def __init__( self, class_number=21, input_shape=(300, 300, 3), priors_file='prior_boxes_ssd300.pkl', train_file='VOC2007.pkl', path_prefix='./VOCdevkit/VOC2007/JPEGImages/', model=None, weight_file='weights_SSD300.hdf5', freeze=('input_1', 'conv1_1', 'conv1_2', 'pool1', 'conv2_1', 'conv2_2', 'pool2', 'conv3_1', 'conv3_2', 'conv3_3', 'pool3'), save_weight_file='/src/resource/checkpoints/weights.{epoch:02d}-{val_loss:.2f}.hdf5', # noqa optim=None, batch_size=20, nb_worker=1): """ Setting below parameter :param class_number(int): class number :param input_shape(set): set input shape :param priors_file(str): set prior file name :param train_file(str): train file name :param path_prefix(str): path prefix :param model(keras model): set the keras model such as the ssd :param weight_file(str): weight file name :param freeze(set): set untraining layer """ self.input_shape = input_shape priors = pickle.load(open(priors_file, 'rb')) self.bbox_utils = BBoxUtility(class_number, priors) self.train_data = pickle.load(open(train_file, 'rb')) keys = sorted(self.train_data.keys()) num_train = int(round(0.8 * len(keys))) self.train_keys = keys[:num_train] self.val_keys = keys[num_train:] self.num_val = len(self.val_keys) self.batch_size = batch_size self.gen = Generator(self.train_data, self.bbox_utils, batch_size, path_prefix, self.train_keys, self.val_keys, (self.input_shape[0], self.input_shape[1]), do_crop=True) self.model = model model.load_weights(weight_file, by_name=True) self.freeze = list(freeze) self.save_weight_file = save_weight_file self.optim = optim self.nb_worker = nb_worker self.model.compile(optimizer=optim, metrics=['accuracy'], loss=MultiboxLoss(class_number, neg_pos_ratio=2.0).compute_loss)
from ssd import SSD300 from ssd_utils import BBoxUtility from ssd_training import MultiboxLoss from pycocotools.coco import COCO import numpy as np from scipy.misc import imread from scipy.misc import imresize import pickle model = SSD300(num_classes=81) mbLoss = MultiboxLoss(num_classes=81) model.compile(loss=mbLoss.compute_loss, optimizer='adam') ssd300_priors = pickle.load(open('prior_boxes_ssd300.pkl')) bboxer = BBoxUtility(num_classes=81, priors=ssd300_priors) cocodata = COCO('/DATA/COCO/annotations/instances_train2017.json') cocoDir = '/DATA/COCO/train2017/' catsToIds = {} for i, catid in enumerate(cocodata.getCatIds()): catsToIds[catid] = i def generator(batch_size=4): imgList = cocodata.imgs.keys() imgcount = len(imgList) n = 0 while True: X = np.zeros((batch_size, 300, 300, 3), dtype=np.float)
def train(NUM_CLASSES, nb_epoch, base_lr=3e-4, path_prefix='data/train/', dev="cpu"): import keras import tensorflow as tf from keras.backend.tensorflow_backend import set_session import os import matplotlib.pyplot as plt import numpy as np import pickle from sklearn.model_selection import train_test_split from ssd import SSD300 from ssd_training import MultiboxLoss from ssd_training import Generator from ssd_utils import BBoxUtility from keras.callbacks import TensorBoard plt.rcParams['figure.figsize'] = (8, 8) plt.rcParams['image.interpolation'] = 'nearest' np.set_printoptions(suppress=True) if dev == "cpu": os.environ['CUDA_VISIBLE_DEVICES'] = '-1' # for multi GPUs else: os.environ['CUDA_VISIBLE_DEVICES'] = '0' config = tf.ConfigProto() config.gpu_options.per_process_gpu_memory_fraction = 0.9 set_session(tf.Session(config=config)) # some constants NUM_CLASSES = NUM_CLASSES + 1 # 1 means mask input_shape = (300, 300, 3) # nb_epoch = 5 # base_lr = 3e-4 # path_prefix = 'data/train/' # path to your data priors = pickle.load(open('data/prior_boxes_ssd300.pkl', 'rb')) bbox_util = BBoxUtility(NUM_CLASSES, priors) gt = pickle.load(open('data/train.pkl', 'rb'), encoding='iso-8859-1') # for python3.x lable = pickle.load(open('data/label.pkl', 'rb'), encoding='iso-8859-1') # for python3.x # gt = pickle.load(open('data_convert/train.pkl', 'rb')) # keys = sorted(gt.keys()) # num_train = int(round(0.85 * len(keys))) # train_keys = keys[:num_train] # val_keys = keys[num_train:] # num_val = len(val_keys) train_keys, val_keys, train_label, val_label = train_test_split(sorted(lable.keys()), sorted(lable.values()), test_size=0.1, random_state=0) num_train = len(train_keys) num_val = len(val_keys) print(train_keys) print(val_keys) gen = Generator(gt, bbox_util, 1, path_prefix, train_keys, val_keys, (input_shape[0], input_shape[1]), do_crop=False) model = SSD300(input_shape, num_classes=NUM_CLASSES) model.load_weights('data/weights_SSD300.hdf5', by_name=True) freeze = ['input_1', 'conv1_1', 'conv1_2', 'pool1', 'conv2_1', 'conv2_2', 'pool2', 'conv3_1', 'conv3_2', 'conv3_3', 'pool3',] # 'conv4_1', 'conv4_2', 'conv4_3', 'pool4'] # freeze = ['input_1', 'conv1_1', 'conv1_2', 'pool1', # 'conv2_1', 'conv2_2', 'pool2', # 'conv3_1', 'conv3_2', 'conv3_3', 'pool3', # 'conv4_1', 'conv4_2', 'conv4_3', 'pool4', 'conv4_3_norm', # 'conv5_1', 'conv5_2', 'conv5_3', 'pool5', 'fc6', 'fc7', # 'conv6_1', 'conv6_2', # 'conv7_1', 'conv7_1z', 'conv7_2', # 'conv8_1', 'conv8_2', # 'pool6' # ] for L in model.layers: if L.name in freeze: L.trainable = False def schedule(epoch, decay=0.9): return base_lr * decay ** (epoch) # checkpoints/weights.{epoch:02d}-{val_loss:.2f}.hdf5 callbacks = [keras.callbacks.ModelCheckpoint('checkpoints/weights.hdf5', verbose=1, save_weights_only=True, save_best_only=True, mode='auto', period=1), keras.callbacks.LearningRateScheduler(schedule),TensorBoard(log_dir='logs')] optim = keras.optimizers.Adam(lr=base_lr) # optim = keras.optimizers.RMSprop(lr=base_lr) # optim = keras.optimizers.SGD(lr=base_lr, momentum=0.9, decay=decay, nesterov=True) model.compile(optimizer=optim, loss=MultiboxLoss(NUM_CLASSES, neg_pos_ratio=2.0).compute_loss) a=0 history = model.fit_generator(gen.generate(True), steps_per_epoch=num_train, epochs=nb_epoch, verbose=1, callbacks=callbacks, validation_data=gen.generate(False), validation_steps=num_val, nb_worker=1)
def do_kucheat_training(): plt.rcParams['figure.figsize'] = (8, 8) plt.rcParams['image.interpolation'] = 'nearest' np.set_printoptions(suppress=True) pkl_path = './data/pickles/' weight_path = './data/weights/' checkpoints_path = './checkpoints/' path_prefix = './data/images/' # for hatena batch_size = 10 NUM_CLASSES = 21 input_shape = (300, 300, 3) priors = pickle.load(open(pkl_path + 'prior_boxes_ssd300.pkl', 'rb')) bbox_util = BBoxUtility(NUM_CLASSES, priors) gt = pickle.load(open(pkl_path + 'mawile.pkl', 'rb')) keys = sorted(gt.keys()) num_train = int(round(0.8 * len(keys))) train_keys = keys[:num_train] val_keys = keys[num_train:] num_val = len(val_keys) gen = Generator(gt, bbox_util, batch_size, path_prefix, train_keys, val_keys, (input_shape[0], input_shape[1]), do_crop=False) model = SSD300(input_shape, num_classes=NUM_CLASSES) model.load_weights(weight_path + 'weights_SSD300.hdf5', by_name=True) freeze = [ 'input_1', 'conv1_1', 'conv1_2', 'pool1', 'conv2_1', 'conv2_2', 'pool2', 'conv3_1', 'conv3_2', 'conv3_3', 'pool3' ] for L in model.layers: if L.name in freeze: L.trainable = False callbacks = [ keras.callbacks.ModelCheckpoint( checkpoints_path + 'weights.{epoch:02d}-{val_loss:.2f}.hdf5', verbose=1, save_weights_only=True), keras.callbacks.LearningRateScheduler(schedule) ] optim = keras.optimizers.Adam(lr=base_lr) model.compile(optimizer=optim, loss=MultiboxLoss(NUM_CLASSES, neg_pos_ratio=2.0).compute_loss) nb_epoch = 50 history = model.fit_generator(gen.generate(True), gen.train_batches, nb_epoch, verbose=1, callbacks=callbacks, validation_data=gen.generate(False), nb_val_samples=gen.val_batches, nb_worker=4) model.save_weights('mawile_ssd_keras_weight.hdf5') model.save('mawile_ssd_keras_model.hdf5')
def train_proc(dirName="VOC2007"): plt.rcParams['figure.figsize'] = (8, 8) plt.rcParams['image.interpolation'] = 'nearest' np.set_printoptions(suppress=True) # 21 NUM_CLASSES = 21 #4 input_shape = (300, 300, 3) priors = pickle.load(open('prior_boxes_ssd300.pkl', 'rb')) bbox_util = BBoxUtility(NUM_CLASSES, priors) # gt = pickle.load(open('gt_pascal.pkl', 'rb')) pascal_file = './PASCAL_VOC/%s.pkl' % dirName print("loading ", pascal_file) gt = pickle.load( open( pascal_file, 'rb') ) keys = sorted(gt.keys()) num_train = int(round(0.8 * len(keys))) train_keys = keys[:num_train] val_keys = keys[num_train:] num_val = len(val_keys) BATCH_SIZES = 4 logging.info(" training number: %d validation number: %d " % (num_train, num_val) ) steps_per_epoch = num_train / BATCH_SIZES validation_steps = num_val / BATCH_SIZES path_prefix = './VOCdevkit/%s/JPEGImages/' % dirName gen = Generator(gt, bbox_util, BATCH_SIZES, path_prefix, train_keys, val_keys, (input_shape[0], input_shape[1]), do_crop=False) image_path = [] for train_key in train_keys: im = os.path.join(path_prefix, train_key) image_path.append(im) #logging.info("tainable filenames %s" % (image_path,) ) model = SSD300(input_shape, num_classes=NUM_CLASSES) print( model.summary() ) model.load_weights('weights_SSD300.hdf5', by_name=True) freeze = ['input_1', 'conv1_1', 'conv1_2', 'pool1', 'conv2_1', 'conv2_2', 'pool2', 'conv3_1', 'conv3_2', 'conv3_3', 'pool3']#, # 'conv4_1', 'conv4_2', 'conv4_3', 'pool4'] for L in model.layers: if L.name in freeze: L.trainable = False callbacks = [keras.callbacks.ModelCheckpoint('./checkpoints/weights.{epoch:02d}-{val_loss:.2f}.hdf5', verbose=1, save_weights_only=True), keras.callbacks.LearningRateScheduler(schedule)] optim = keras.optimizers.Adam(lr=base_lr) model.compile(optimizer=optim, loss=MultiboxLoss(NUM_CLASSES, neg_pos_ratio=2.0).compute_loss) nb_epoch = 10 # keras 1 #history = model.fit_generator(gen.generate(True), gen.train_batches, # nb_epoch, verbose=1, # callbacks=callbacks, # validation_data=gen.generate(False), # nb_val_samples=gen.val_batches, # nb_worker=1) # keras 2 history = model.fit_generator(generator = gen.generate(True), steps_per_epoch = steps_per_epoch, epochs=nb_epoch , verbose=1, callbacks=callbacks, validation_data = gen.generate(False), validation_steps = validation_steps )
keras.callbacks.ModelCheckpoint('./checkpoints/weights.{epoch:02d}.hdf5', verbose=1, save_weights_only=True), keras.callbacks.TensorBoard(), keras.callbacks.LearningRateScheduler(schedule) ] base_lr = 3e-4 optim = keras.optimizers.Adam(lr=base_lr) # optim = keras.optimizers.RMSprop(lr=base_lr) # optim = keras.optimizers.SGD(lr=base_lr, momentum=0.9, decay=decay, nesterov=True) import keras.backend as K import numpy as np tf_session = K.get_session() ml = MultiboxLoss(NUM_CLASSES, neg_pos_ratio=2.0) model.compile(optimizer=optim, loss=ml.compute_loss) # gen_batch = gen.batch(False) # ml.compute_loss_tf(tf_session, gen_batch[1].astype(np.float32), gen_batch[1].astype(np.float32)) nb_epoch = 30 history = model.fit_generator( gen.generate(True), gen.train_batches, nb_epoch, verbose=1, callbacks=callbacks, # validation_data=gen.generate(False), # nb_val_samples=gen.val_batches,
def autoannotate(dataset, import_datasets, input_shape, image_shape, batch_size, batch_size2, epochs, frozen_layers): soft = False input_shape = parse_resolution(input_shape) image_shape = parse_resolution(image_shape) print_flush("Loading ground truth...") load_detections = LoadDetections() datasets = [dataset] if import_datasets: datasets.extend(import_datasets.split(',')) detections = load_detections.custom(datasets) detections = detections.reset_index(drop=True) image_props = get_image_props(detections) detections = detections_add_ytrue(detections, image_props, dataset) detections.index = detections.image_file print_flush('Ground truth object counts:') print_flush(detections.type.value_counts()) classes = get_classnames(dataset) num_classes = len(classes) + 1 keys = sorted(detections.image_file.unique()) shuffle(keys) num_train = int(round(0.9 * len(keys))) train_keys = keys[:num_train] val_keys = keys[num_train:] print_flush('Loading model...') model = SSD300((input_shape[1],input_shape[0],input_shape[2]), num_classes=num_classes) model.load_weights(ssd_path+'weights_SSD300.hdf5', by_name=True) print_flush("Making priors...") im_in = np.random.random((1,input_shape[1],input_shape[0],input_shape[2])) priors = model.predict(im_in,batch_size=1)[0, :, -8:] bbox_util = BBoxUtility(num_classes, priors) generator_kwargs = { 'saturation_var': 0.5, 'brightness_var': 0.5, 'contrast_var': 0.5, 'lighting_std': 0.5, 'hflip_prob': 0.5, 'vflip_prob': 0, 'do_crop': True, 'crop_area_range': [0.1, 1.0], 'aspect_ratio_range': [0.5, 2] } path_prefix = '' gen = Generator(detections, bbox_util, batch_size, path_prefix, train_keys, val_keys, (input_shape[1], input_shape[0]), **generator_kwargs) # freeze several layers freeze = [ ['input_1', 'conv1_1', 'conv1_2', 'pool1'], ['conv2_1', 'conv2_2', 'pool2'], ['conv3_1', 'conv3_2', 'conv3_3', 'pool3'], ['conv4_1', 'conv4_2', 'conv4_3', 'pool4'], ['conv5_1', 'conv5_2', 'conv5_3', 'pool5'], ][:min(frozen_layers, 5)] for L in model.layers: if L.name in freeze: L.trainable = False callbacks = [LearningRateScheduler(schedule)] optim = keras.optimizers.Adam(lr=BASE_LR / 10) model.compile(optimizer=optim, loss=MultiboxLoss(num_classes, neg_pos_ratio=2.0).compute_loss) print_flush("Training...") history = model.fit_generator(gen.generate(True), steps_per_epoch=gen.train_batches, epochs=epochs, verbose=2, callbacks=callbacks, validation_data=gen.generate(False), validation_steps=gen.val_batches, workers=1) print_flush("Auto-annotating...") masker = Masker(dataset) inputs = [] impaths = [] to_annotate = get_images_to_autoannotate(dataset) # rep_last needed since we use large batches, for speed, to make sure we run on all images for impath in rep_last(to_annotate, batch_size2): im = iio.imread(impath) im = masker.mask(im) resized = cv2.resize(im, (input_shape[0], input_shape[1])) inputs.append(resized) impaths.append(impath) if len(inputs) == batch_size2: inputs = np.array(inputs).astype(np.float64) inputs = preprocess_input(inputs) preds = model.predict(inputs, batch_size=batch_size, verbose=0) results = bbox_util.detection_out(preds, soft=soft) for result, res_path in zip(results, impaths): result = [r if len(r) > 0 else np.zeros((1, 6)) for r in result] raw_detections = pd.DataFrame(np.vstack(result), columns=['class_index', 'confidence', 'xmin', 'ymin', 'xmax', 'ymax']) auto_path = res_path.replace('.jpg','.auto') # Sort detections by confidence, keeping the top ones # This seems to be more robust than a hard-coded confidence threshold # Note that a confidence threshold can be chosen in the annotation web UI n = 128 dets = [x for x in pandas_loop(raw_detections)] dets.sort(key=lambda x: 1.0-x['confidence']) if len(dets) > n: dets = dets[:n] with open(auto_path, 'w') as f: for det in dets: conf = round(det['confidence'],4) line = "{index} {cx} {cy} {w} {h} conf:{conf} {cn}\n".format(index=int(det['class_index']), cx = round((det['xmin']+det['xmax'])/2,4), cy = round((det['ymin']+det['ymax'])/2,4), w = round(det['xmax']-det['xmin'],4), h = round(det['ymax']-det['ymin'],4), conf=conf, cn = classes[int(det['class_index'])-1]) f.write(line) print_flush("Wrote {}".format(auto_path)) inputs = [] impaths = [] assert(not inputs) # If this fails, not all images were processed! print_flush("Done!")
def schedule(epoch, decay=0.9): return base_lr * decay**(epoch) callbacks = [ keras.callbacks.ModelCheckpoint( './checkpoints/weights.{epoch:02d}-{val_loss:.2f}.hdf5', verbose=1, save_weights_only=True), keras.callbacks.LearningRateScheduler(schedule) ] base_lr = cf.BASE_LR optim = keras.optimizers.Adam(lr=base_lr) model.compile(optimizer=optim, loss=MultiboxLoss(NUM_CLASSES, neg_pos_ratio=cf.NEG_POS_RATIO).compute_loss) nb_epoch = cf.EPOCHS history = model.fit_generator(gen.generate(True), gen.train_batches, nb_epoch, verbose=1, callbacks=callbacks, validation_data=gen.generate(False), nb_val_samples=gen.val_batches, nb_worker=1) model.save_weights(cf.WEIGHTS, overwrite=True) """ inputs = [] images = []
def main(batch_size, max_images, epochs, name, import_datasets, frozen_layers, experiment, train_data_dir, input_shape, image_shape, memory_fraction, do_crop): from keras.backend.tensorflow_backend import set_session config = tf.ConfigProto() config.gpu_options.per_process_gpu_memory_fraction = memory_fraction set_session(tf.Session(config=config)) run_name = "{}_{}".format(name, experiment) input_shape = parse_resolution(input_shape) image_shape = parse_resolution(image_shape) load_detections = LoadDetections() session = tf.Session() K.set_session(session) log('Started TensorFlow session') log('Chosen input_shape is {}'.format(input_shape)) detections_file = runs_path / run_name / "detections.pickle" mkdir(runs_path / run_name) logging.basicConfig(filename=str(runs_path / run_name / "trainlog.log"), level=logging.INFO) try: githash = subprocess.check_output(['git', 'rev-parse', 'HEAD' ]).strip()[0:6].decode('utf-8') log("Git hash: {}".format(githash)) except subprocess.CalledProcessError: pass log('Loading detections') datasets = [name] if import_datasets: datasets.extend(import_datasets.split(',')) log('Using these datasets: ' + str(datasets)) detections = load_detections.custom(datasets) log('Detections loaded') log('Calculating image properties') detections = detections.reset_index(drop=True) image_props = get_image_props(detections) log('Image properties created') log('Adding y_true to detections') detections = detections_add_ytrue(detections, image_props, name) detections.index = detections.image_file print(' ') print('Detection frequencies:') print(detections.type.value_counts()) print(' ') classes = get_classnames(name) #sorted(detections.type.unique()) num_classes = len(classes) + 1 log('Loading priors') keys = sorted(detections.image_file.unique()) random.shuffle(keys) if max_images > 0: keys = keys[:max_images] shuffle(keys) num_train = int(round(0.9 * len(keys))) if num_train == len(keys): num_train -= 1 train_keys = keys[:num_train] val_keys = keys[num_train:] train_keys_file = runs_path / run_name / "train_keys.pickle" log('Saving training keys to: {}'.format(train_keys_file)) pickle.dump(str(train_keys), train_keys_file.open('wb')) val_keys_file = runs_path / run_name / "val_keys.pickle" log('Saving validation keys to: {}'.format(val_keys_file)) pickle.dump(str(val_keys), val_keys_file.open('wb')) log('Loading model') model = SSD300((input_shape[1], input_shape[0], input_shape[2]), num_classes=num_classes) model.load_weights(ssd_path / "weights_SSD300.hdf5", by_name=True) log('Generating priors') im_in = np.random.random( (1, input_shape[1], input_shape[0], input_shape[2])) priors = model.predict(im_in, batch_size=1)[0, :, -8:] bbox_util = BBoxUtility(num_classes, priors) generator_kwargs = { 'saturation_var': 0.5, 'brightness_var': 0.5, 'contrast_var': 0.5, 'lighting_std': 0.5, 'hflip_prob': 0.5, 'vflip_prob': 0, 'do_crop': do_crop, 'crop_area_range': [0.1, 1.0], 'aspect_ratio_range': [0.5, 2] } path_prefix = '' gen = Generator(detections, bbox_util, batch_size, path_prefix, train_keys, val_keys, (input_shape[1], input_shape[0]), **generator_kwargs) # freeze several layers # freeze = [] freeze = [ ['input_1', 'conv1_1', 'conv1_2', 'pool1'], ['conv2_1', 'conv2_2', 'pool2'], ['conv3_1', 'conv3_2', 'conv3_3', 'pool3'], ['conv4_1', 'conv4_2', 'conv4_3', 'pool4'], ['conv5_1', 'conv5_2', 'conv5_3', 'pool5'], ][:min(frozen_layers, 5)] for L in model.layers: if L.name in freeze: L.trainable = False mkdir(runs_path / run_name / "checkpoints") shutil.rmtree(str(runs_path / run_name / "logs"), ignore_errors=True) mkdir(runs_path / run_name / "logs") callbacks = [ ModelCheckpoint(str(runs_path / run_name / 'checkpoints') + '/weights.{epoch:02d}-{val_loss:.2f}.hdf5', verbose=2, save_weights_only=True), TensorBoard(log_dir=str(runs_path / run_name / "logs"), write_graph=False), LearningRateScheduler(schedule) ] optim = keras.optimizers.Adam(lr=BASE_LR / 10) # optim = keras.optimizers.RMSprop(lr=BASE_LR / 10) model.compile(optimizer=optim, loss=MultiboxLoss(num_classes, neg_pos_ratio=2.0).compute_loss) log('Running model') history = model.fit_generator(gen.generate(True), steps_per_epoch=gen.train_batches, epochs=epochs, verbose=2, callbacks=callbacks, validation_data=gen.generate(False), validation_steps=gen.val_batches, workers=1) log('Done training model') session.close() log('Session closed, starting with writing results') results = pd.DataFrame(history.history).unstack().reset_index(0) results = results.rename(columns={'level_0': 'type', 0: 'value'}) x1 = [] y1 = [] x2 = [] y2 = [] for row in pandas_loop(results): if row['type'] == 'loss': x1.append(row['_']) y1.append(row['value']) elif row['type'] == 'val_loss': x2.append(row['_']) y2.append(row['value']) plot_path = runs_path / run_name / "training.png" multi_plot([x1, x2], [y1, y2], plot_path, xlabel='epochs', ylabel='loss', title='Training', legend=['loss', 'validation loss']) results.to_csv(runs_path / run_name / "results.csv") log('Cleaning up non-optimal weights...') cleanup(name, experiment) log('Finished TensorFlow session') print_flush('Done!')
def run_training(): file_io.create_dir(FLAGS.model_dir) np.set_printoptions(suppress=True) input_shape = (300, 300, 3) prior_filename = os.path.basename(FLAGS.prior_path) file_io.copy(FLAGS.prior_path, prior_filename) priors = pickle.load(open(prior_filename, 'rb')) bbox_util = BBoxUtility(FLAGS.num_classes, priors) annotation_filename = os.path.basename(FLAGS.annotation_path) file_io.copy(FLAGS.annotation_path, annotation_filename) gt = pickle.load(open(annotation_filename, 'rb')) keys = sorted(gt.keys()) num_train = int(round(0.8 * len(keys))) train_keys = keys[:num_train] val_keys = keys[num_train:] num_val = len(val_keys) images_filename = os.path.basename(FLAGS.images_path) file_io.copy(FLAGS.images_path, images_filename) tar = tarfile.open(images_filename) tar.extractall() tar.close() path_prefix = images_filename.split('.')[0] + '/' gen = Generator(gt, bbox_util, 4, path_prefix, train_keys, val_keys, (input_shape[0], input_shape[1]), do_crop=False) net, model = SSD300(input_shape, num_classes=FLAGS.num_classes) weight_filename = os.path.basename(FLAGS.weight_path) file_io.copy(FLAGS.weight_path, weight_filename) model.load_weights(weight_filename, by_name=True) freeze = ['input_1', 'conv1_1', 'conv1_2', 'pool1', 'conv2_1', 'conv2_2', 'pool2', 'conv3_1', 'conv3_2', 'conv3_3', 'pool3', 'conv4_1', 'conv4_2', 'conv4_3', 'pool4'] for L in model.layers: if L.name in freeze: L.trainable = False base_lr = 3e-4 optim = keras.optimizers.Adam(lr=base_lr) model.compile(optimizer=optim, loss=MultiboxLoss(FLAGS.num_classes, neg_pos_ratio=2.0).compute_loss) # train model.fit_generator(gen.generate(True), gen.train_batches, FLAGS.epoch, validation_data=gen.generate(False), nb_val_samples=gen.val_batches, nb_worker=1) # define prediction layer keys_placeholder = tf.placeholder(tf.string, shape=[None]) keep_top_k_placeholder = tf.placeholder(dtype='int32', shape=(None)) original_size_placeholder = tf.placeholder(dtype='float32', shape=(None, 2)) confidence_threshold_placeholder = tf.placeholder(dtype='float32', shape=(None)) detection_out = Lambda(bbox_util.detection_out, arguments={ 'keep_top_k': keep_top_k_placeholder, 'confidence_threshold': confidence_threshold_placeholder, 'original_size': original_size_placeholder })(net['predictions']) # export inputs = {'key': keys_placeholder, 'data': model.input, 'keep_top_k': keep_top_k_placeholder, 'confidence_threshold': confidence_threshold_placeholder, 'original_size': original_size_placeholder} outputs = {'key': tf.identity(keys_placeholder), 'objects': detection_out} export(get_session(), inputs, outputs, FLAGS.model_dir)
'conv3_1', 'conv3_2', 'conv3_3', 'pool3'] for L in model.layers: if L.name in freeze: L.trainable = False def schedule(epoch, decay=0.9): return base_lr * decay**(epoch) callbacks = [keras.callbacks.ModelCheckpoint('./checkpoints/weights.{epoch:02d}-{val_loss:.2f}.hdf5', verbose=1, save_weights_only=True), keras.callbacks.LearningRateScheduler(schedule)] base_lr = 3e-6 optim = keras.optimizers.Adam(lr=base_lr) # optim = keras.optimizers.RMSprop(lr=base_lr) # optim = keras.optimizers.SGD(lr=base_lr, momentum=0.9, decay=decay, nesterov=True) model.compile(optimizer=optim, loss=MultiboxLoss(NUM_CLASSES, neg_pos_ratio=2.0).compute_loss) history = model.fit_generator(gen.generate(True), gen.train_batches, epochs=100, verbose=1, callbacks=callbacks, validation_data=gen.generate(False), validation_steps=gen.val_batches, workers=1)
parser.add_argument( '--output_model_path', type=str, default='checkpoint', required=False, help='Where to save the converted model.' ) args = parser.parse_args() tf.keras.backend.set_learning_phase(0) from ssd_layers import PriorBox from ssd_training import MultiboxLoss model = tf.keras.models.load_model(args.input_model_path, custom_objects={'PriorBox': PriorBox, 'compute_loss': MultiboxLoss(21, neg_pos_ratio=2.0).compute_loss}) #model = keras.models.load_model(args.input_model_path) model.save('tmp.h5', include_optimizer=False) tf.keras.backend.clear_session() tf.keras.backend.set_learning_phase(0) model2 = keras.models.load_model('tmp.h5', custom_objects={'PriorBox': PriorBox, 'compute_loss': MultiboxLoss(21, neg_pos_ratio=2.0).compute_loss}) os.remove('tmp.h5') sess = tf.compat.v1.keras.backend.get_session() saver = tf.compat.v1.train.Saver() os.makedirs(args.output_model_path, exist_ok=True) if os.path.exists(args.input_class_names_path) and os.path.isfile(args.input_class_names_path): shutil.copyfile(args.input_class_names_path, os.path.join(args.output_model_path, 'class_names.txt')) else:
def train_SSD300_NAG( master_file, train_dir, test_dir, model_path, load_weights_path=r'C:\Users\shingo\jupyter_notebook\tfgpu_py36_work\AI_Edge_Contest\object_detection\SSD_classes_py\all_SSD_module\SSD\weights_SSD300.hdf5', epochs=20, batch_size=32, base_lr=1e-3, num_classes=6 + 1, callback=[]): """ dtc_train.py のパラメータなどを引数にした関数 ラベル情報のcsvファイルから訓練画像の領域情報ロードし、SSDのモデル作成する ※csvファイルからラベル情報読めるのが良いところ(一般的な物体検出モデルのラベル情報は1画像1xmlファイル) 画像のサイズは300x300に変換される(ssd_vgg.pyより) 分類器はVGG16のfine-tuning オプティマイザは ネステロフ+モメンタム+SGD(decayあり). 学習率はLearningRateScheduler でも下げる Args: master_file : 正解の座標(ファイル名, x, y, width, height, ラベルid)一覧のcsvファイルパス. SSDの「背景」ラベルとして使われるため、ラベルidは0を使わないこと!!! train_dir : 訓練用画像が入っているフォルダパス test_dir : 評価用画像が入っているフォルダパス model_path : モデルファイルの保存先パス load_weights_path : 重みファイルのパス epochs : エポック数 batch_size : バッチサイズ base_lr : 学習率初期値 num_classes : クラス数。クラス数は「背景(class_id=0固定)」と「分類したいクラス」の数(要するにクラス数+1)にしないと正しくできない!!!! callback: 追加するcallbackのリスト。空なら ModelCheckpoint と LearningRateScheduler だけの callback にになる Return: なし(モデルファイルweight_ssd_best.hdf5 出力) """ #epochs = 20 # エポック数 #batch_size = 32 # バッチサイズ #base_lr = 1e-3 # 学習率初期値 #num_classes = 11 # 最適化関数 # optimizer = keras.optimizers.Adam(lr=base_lr) # optimizer = keras.optimizers.RMSprop(lr=base_lr) optimizer = keras.optimizers.SGD(lr=base_lr, momentum=0.9, decay=1e-6, nesterov=True) # 学習率のスケジュール関数 def schedule(epoch, decay=0.90): return base_lr * decay**(epoch) # 正解の座標(ファイル名, x, y, width, height)一覧のcsvファイル #master_file = "xywh_train.csv" # 訓練用画像が入っているフォルダ #train_dir = "ssd_train" # 評価用画像が入っているフォルダ #test_dir = "ssd_test" # 画像ファイル名を指定すると正解座標が返ってくる辞書を作成 correct_boxes = get_correct_boxes(master_file, train_dir, test_dir, num_classes=num_classes) # 画像ファイルパス一覧取得 train_path_list = glob.glob(os.path.join(train_dir, "*.*")) test_path_list = glob.glob(os.path.join(test_dir, "*.*")) ## 画像ファイルパス一覧取得 #train_path_list = [] #test_path_list = [] #for folder in glob.glob(os.path.join(train_dir, "*")): # for file in glob.glob(os.path.join(folder, "*.jpg")): # train_path_list.append(file) #for folder in glob.glob(os.path.join(test_dir, "*")): # for file in glob.glob(os.path.join(folder, "*.jpg")): # test_path_list.append(file) # モデル作成 model = create_model(num_classes=num_classes) print('create_model ok') model.load_weights(load_weights_path, by_name=True) print('load_weights ok') # 入力付近の層をフリーズ freeze_layers(model, depth_level=1) print('freeze_layers ok') model.compile(optimizer=optimizer, loss=MultiboxLoss(num_classes).compute_loss) #model.summary() plot_model(model, os.path.join(os.path.dirname(model_path), "model_ssd.png")) # デフォルトボックス作成 priors = create_prior_box() # 画像データのジェネレータ作成 bbox_util = BBoxUtility(num_classes, priors) gen = Generator(correct_boxes, bbox_util, train_path_list, test_path_list, (input_shape[0], input_shape[1]), batch_size) print("Train Items : {}".format(gen.train_batches)) print("Test Items : {}".format(gen.val_batches)) # コールバック設定 callbacks = [ ModelCheckpoint(model_path, verbose=1, save_weights_only=True, save_best_only=True) ] #, LearningRateScheduler(schedule)] if len(callback) != 0: callbacks.extend(callback) #print(model.summary()) # 学習開始 start_time = time.time() history = model.fit_generator(gen.generate(True), gen.train_batches // batch_size, epochs=epochs, verbose=2, callbacks=callbacks, validation_data=gen.generate(False), validation_steps=gen.val_batches // batch_size) end_time = time.time() # 経過時間表示 elapsed_time = end_time - start_time print("Elapsed Time : {0:d} hr {1:d} min {2:d} sec".format( int(elapsed_time // 3600), int((elapsed_time % 3600) // 60), int(elapsed_time % 60))) return history
callbacks = [keras.callbacks.ModelCheckpoint('./checkpoints/weights.{epoch:02d}-{val_loss:.2f}.hdf5', verbose=1, save_weights_only=True), keras.callbacks.LearningRateScheduler(schedule)] # In[10]: base_lr = 3e-4 optim = keras.optimizers.Adam(lr=base_lr) # optim = keras.optimizers.RMSprop(lr=base_lr) # optim = keras.optimizers.SGD(lr=base_lr, momentum=0.9, decay=decay, nesterov=True) model.compile(optimizer=optim, loss=MultiboxLoss(NUM_CLASSES, neg_pos_ratio=2.0).compute_loss,metrics=['acc']) # In[11]: nb_epoch = 30 history = model.fit_generator(gen.generate(True), gen.train_batches, nb_epoch, verbose=1, callbacks=callbacks, validation_data=gen.generate(False), nb_val_samples=gen.val_batches, nb_worker=1) # In[12]:
'./checkpoints/weights.{epoch:02d}-{val_loss:.2f}.hdf5', verbose=1, save_weights_only=True) learnRateSchedule = keras.callbacks.LearningRateScheduler(schedule) callbacks = [weights_save, csv_logger, learnRateSchedule] base_lr = 0.0001 #3e-4 optim = keras.optimizers.Adam(lr=base_lr, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.) #optim = keras.optimizers.Adam(lr=base_lr) model.compile(optimizer=optim, loss=MultiboxLoss(NUM_CLASSES, neg_pos_ratio=2.0).compute_loss) for j in range(1): nb_epoch = 30 history = model.fit_generator(gen.generate(True), gen.train_batches, nb_epoch, verbose=1, callbacks=callbacks, validation_data=gen.generate(False), nb_val_samples=gen.val_batches, nb_worker=1) model.save_weights('params_SSD_epoch_{0:03d}.hdf5'.format(j), True) # 学習履歴を保存 save_history(history, os.path.join("./checkpoints/", 'history_SSD.txt'), j)
def train(dataset, import_datasets, input_shape, batch_size, epochs, frozen_layers, train_amount=0.9): print_flush("Loading ground truth...") load_detections = LoadDetections() datasets = [dataset] if import_datasets: datasets.extend(import_datasets.split(',')) detections = load_detections.custom(datasets) detections = detections.reset_index(drop=True) image_props = get_image_props(detections) detections = detections_add_ytrue(detections, image_props, dataset) detections.index = detections.image_file print_flush('Ground truth object counts:') print_flush(detections.type.value_counts()) classes = get_classnames(dataset) num_classes = len(classes) + 1 keys = sorted(detections.image_file.unique()) shuffle(keys) if train_amount < 1.0: num_train = int(round(train_amount * len(keys))) train_keys = keys[:num_train] val_keys = keys[num_train:] else: train_keys = keys # Not a very good validation set, but whatever. # The ability to train on all the images is important when annotations are sparse, # like when doing autoannotation val_keys = [keys[0]] print_flush('Loading model...') model = SSD300((input_shape[1], input_shape[0], input_shape[2]), num_classes=num_classes) model.load_weights(ssd_path / 'weights_SSD300.hdf5', by_name=True) print_flush("Making priors...") im_in = np.random.random( (1, input_shape[1], input_shape[0], input_shape[2])) priors = model.predict(im_in, batch_size=1)[0, :, -8:] bbox_util = BBoxUtility(num_classes, priors) generator_kwargs = { 'saturation_var': 0.5, 'brightness_var': 0.5, 'contrast_var': 0.5, 'lighting_std': 0.5, 'hflip_prob': 0.5, 'vflip_prob': 0, 'do_crop': True, 'crop_area_range': [0.1, 1.0], 'aspect_ratio_range': [0.5, 2] } path_prefix = '' gen = Generator(detections, bbox_util, batch_size, path_prefix, train_keys, val_keys, (input_shape[1], input_shape[0]), **generator_kwargs) # freeze several layers freeze = [ ['input_1', 'conv1_1', 'conv1_2', 'pool1'], ['conv2_1', 'conv2_2', 'pool2'], ['conv3_1', 'conv3_2', 'conv3_3', 'pool3'], ['conv4_1', 'conv4_2', 'conv4_3', 'pool4'], ['conv5_1', 'conv5_2', 'conv5_3', 'pool5'], ][:min(frozen_layers, 5)] for L in model.layers: if L.name in freeze: L.trainable = False callbacks = [LearningRateScheduler(schedule)] optim = keras.optimizers.Adam(lr=BASE_LR / 10) model.compile(optimizer=optim, loss=MultiboxLoss(num_classes, neg_pos_ratio=2.0).compute_loss) print_flush("Training...") history = model.fit_generator(gen.generate(True), steps_per_epoch=gen.train_batches, epochs=epochs, verbose=2, callbacks=callbacks, validation_data=gen.generate(False), validation_steps=gen.val_batches, workers=1) return model, bbox_util