def seg_im_mask_paths(tiny_seg_data_path) -> str: """ Returns path to images and their corresponding masks. """ im_dir = Path(tiny_seg_data_path) / "images" mask_dir = Path(tiny_seg_data_path) / "segmentation-masks" im_paths = sorted(get_image_files(im_dir)) mask_paths = sorted(get_image_files(mask_dir)) return im_paths, mask_paths
def __init__(self): self.x = "hello" path = untar_data(URLs.PETS) path_anno = path / 'annotations' path_images = path / 'images' fnames = get_image_files(path_images) np.random.seed(2) pat = re.compile(r'/([^/]+)_\d+.jpg$') bs = 6 # create data loaderi self.data = ImageDataBunch.from_name_re( path, fnames, pat, ds_tfms=get_transforms(), size=224, bs=bs).normalize(imagenet_stats) self.learner = create_cnn(self.dataloader, models.resnet34, metrics=error_rate)
def get_databunch(data_dir, batch_sz=8, num_workers=4, sample_pct=1.0, seed=1234): def get_y_fn(x): return join(str(x.parent) + 'annot', x.name) fnames = get_image_files(join(data_dir, 'test')) img = open_image(fnames[0]) src_size = np.array(img.data.shape[1:]) size = src_size // 2 data = (SegmentationItemList.from_folder(data_dir).use_partial_data( sample_pct, seed).split_by_folder(valid='val').label_from_func( get_y_fn, classes=codes).transform( get_transforms(), size=size, tfm_y=True).databunch( bs=batch_sz, num_workers=num_workers).normalize(imagenet_stats)) return data
from os import path import pandas as pd import numpy as np from fastai import vision, metrics BATCH_SIZE = 64 EPOCHS = 5 PATH_ROOT = path.sep.join(['..', 'datasets', 'oxford-iiit-pet']) IMAGE_PATHS_ROOT = path.sep.join([PATH_ROOT, 'images']) ANNO_PATHS = path.sep.join([PATH_ROOT, 'annotations']) # Get all image names image_paths = vision.get_image_files(IMAGE_PATHS_ROOT) # Extract names for image paths pattern = r'.*images\/(.*)_' # ImageDataBunch automatically create val set np.random.seed(42) data = vision.ImageDataBunch.from_name_re(IMAGE_PATHS_ROOT, image_paths, pattern, ds_tfms=vision.get_transforms(), size=224, bs=BATCH_SIZE).normalize( vision.imagenet_stats) # Show some samples print('[INFO] Show sample images...') data.show_batch(rows=3, figsize=(6, 6)) print(f'[INFO] All classes: {data.classes}')
print('CAMVID paths:') print(fastai_path.ls()) BATCH_SIZE = 64 WD = 1e-2 LR = 1e-4 PCT_START_FINETUNE = 0.9 # given the default of 0.3, it means that your LR is going up for 30% of your iterations and then decreasing over the last 70% PCT_START = 0.8 EPOCHS_FINETUNE = 12 EPOCHS = 12 # Define images and label path LABEL_PATH = path.sep.join([PATH, 'labels']) IMAGE_PATH = path.sep.join([PATH, 'images']) # Define paths of image and label image_paths = vision.get_image_files(IMAGE_PATH) label_paths = vision.get_image_files(LABEL_PATH) # Load some samples to see what's inside rand_indx = np.random.randint(0, len(image_paths)) sample_image_path = image_paths[rand_indx] sample_image = vision.open_image(sample_image_path) sample_image.show(figsize=(6, 6)) # Function to match between image and its label path. E.g. image path: /root/.fastai/data/camvid/images/0006R0_f02910.png; label path: /root/.fastai/data/camvid/labels/0006R0_f02910_P.png segment_name_fn = lambda image_path: path.sep.join( [LABEL_PATH, f'{image_path.stem}_P{image_path.suffix}']) # Load image segmentation by defaults (segment image given in dataset) and vision.open_mask() sample_label_path = segment_name_fn(sample_image_path) sample_label = vision.open_image(sample_label_path) sample_label.show(figsize=(6, 6)) # Note sample segment after preprocess based on vision.open_mask just has 1 depth instead of 3 depth as origin segment
learn.fit_one_cycle(10, slice(1e-5, lr), pct_start=0.9) learn.save("second2") #%% learn.fit_one_cycle(5, slice(1e-5, lr), pct_start=0.9) learn.save("third-d") # %% learn.show_results(rows=1, imgsize=5) # %% learn.load("first") # %% for test_file in fv.get_image_files("data/test/x"): img = fv.open_image(test_file) predicted = learn.predict(img)[1] predicted = predicted.mean(0) predicted[predicted < 0] = 0 predicted[predicted > 1] = 1 transforms.ToPILImage()(predicted).save( f"data/test/y_hat/{test_file.name}") # %%
# Pre-process BDD dataset: https://deepdrive.berkeley.edu/ # Segmentation mask code for "Void" updated from 255 to 19 for continuous sequence # This script must only be run once on downloaded dataset from pathlib import Path from tqdm import tqdm from fastai.vision import get_image_files import PIL # Load label images path_data = Path('../data/bdd100k/seg') path_lbl = path_data / 'labels' lbl_names = get_image_files(path_lbl, recurse=True) # Replace "Void" mask from 255 to 19 (for better data display) # TODO: Process should be *much* faster with cv2 but had issues with conversion for lbl_name in tqdm(lbl_names): img = PIL.Image.open(lbl_name) pixels = img.load() for i in range(img.size[0]): for j in range(img.size[1]): if pixels[i, j] == 255: pixels[i, j] = 19 img.save(lbl_name)
def train(test, s3_data, batch): """Train a segmentation model using fastai and PyTorch on the Camvid dataset. This will write to a CSV log after each epoch, sync output to S3, and resume training from a checkpoint. Note: This is an adaptation of https://github.com/fastai/course-v3/blob/master/nbs/dl1/lesson3-camvid-tiramisu.ipynb and uses the Camvid Tiramisu-subset dataset described in the fast.ai course at half-resolution. This takes about a minute to get to around 90% accuracy on a p3.2xlarge. """ if batch: run_on_batch() # Setup hyperparams. bs = 8 wd = 1e-2 lr = 2e-3 num_epochs = 10 sample_pct = 1.0 model_arch = models.resnet34 fp16 = False sync_interval = 20 # Don't sync during training for such a small job. seed = 1234 if test: bs = 1 num_epochs = 2 sample_pct = 0.01 model_arch = models.resnet18 # Setup paths. data_uri = Path('/opt/data/camvid/CamVid') train_uri = Path('/opt/data/camvid/train') data_dir = data_uri train_dir = train_uri if s3_data: temp_dir_obj = tempfile.TemporaryDirectory() data_uri = 's3://raster-vision-lf-dev/camvid/CamVid.zip' train_uri = 's3://raster-vision-lf-dev/camvid/train' train_dir = Path(temp_dir_obj.name) / 'train' data_dir = Path(temp_dir_obj.name) / 'data' make_dir(train_dir) make_dir(data_dir) # Retrieve data and remote training directory. if s3_data: print('Downloading data...') data_zip = Path(temp_dir_obj.name) / 'CamVid.zip' s3_utils.copy_from(data_uri, str(data_zip)) zip_ref = zipfile.ZipFile(data_zip, 'r') zip_ref.extractall(data_dir) zip_ref.close() data_dir = data_dir / 'CamVid' if s3_utils.list_paths(train_uri): print('Syncing train dir...') s3_utils.sync_to_dir(train_uri, str(train_dir)) # Setup data loader. def get_y_fn(x): return Path(str(x.parent) + 'annot') / x.name fnames = get_image_files(data_dir / 'val') img = open_image(fnames[0]) src_size = np.array(img.data.shape[1:]) size = src_size // 2 data = (SegmentationItemList.from_folder(data_dir).use_partial_data( sample_pct, seed).split_by_folder(valid='val').label_from_func( get_y_fn, classes=codes).transform( get_transforms(), size=size, tfm_y=True).databunch(bs=bs).normalize(imagenet_stats)) # Setup metrics, callbacks, and then train model. metrics = [acc_camvid] model_path = train_dir / 'stage-1' log_path = train_dir / 'log' learn = unet_learner(data, model_arch, metrics=metrics, wd=wd, bottle=True) learn.unfreeze() if fp16 and torch.cuda.is_available(): # This loss_scale works for Resnet 34 and 50. You might need to adjust this # for other models. learn = learn.to_fp16(loss_scale=256) start_epoch = 1 if os.path.isfile(str(model_path) + '.pth'): print('Loading saved model...') start_epoch = get_last_epoch(str(log_path) + '.csv') + 1 if start_epoch > num_epochs: print( 'Training already done. If you would like to re-train, delete ' 'previous results of training in {}.'.format(train_dir)) exit() learn.load(model_path) print('Resuming from epoch {}'.format(start_epoch)) print('Note: fastai does not support a start_epoch, so epoch 1 below ' 'corresponds to {}'.format(start_epoch)) callbacks = [ SaveModelCallback(learn, name=model_path), MyCSVLogger(learn, filename=log_path, start_epoch=start_epoch) ] if s3_data: callbacks.append(S3SyncCallback(train_dir, train_uri, sync_interval)) epochs_left = num_epochs - start_epoch + 1 lrs = slice(lr / 100, lr) learn.fit_one_cycle(epochs_left, lrs, pct_start=0.8, callbacks=callbacks) if s3_data: s3_utils.sync_from_dir(train_dir, train_uri)