<jupyter_start><jupyter_text>Prediction on new data (Legacy Version)> Notebook to predict the segmentation masks on new data using pretrained or customized models. This notebook is optmizied to be executed on [Google Colab](https://colab.research.google.com).* If youre new on _Google Colab_, try out the [tutorial](https://colab.research.google.com/notebooks/intro.ipynb).* Use Firefox or Google Chrome if you want to upload and download files<jupyter_code>#@title Set up environment
#@markdown Please run this cell to get started.
%load_ext autoreload
%autoreload 2
try:
    from google.colab import files, drive
except ImportError:
    pass
try:
    import deepflash2
except ImportError:
    !pip install -q deepflash2==0.0.14
import zipfile
import shutil
import imageio
from fastai.vision.all import *
from deepflash2.all import *
from scipy.stats import entropy<jupyter_output><empty_output><jupyter_text>Provide Data __Required data structure: One folder for images__ (different from training image folder!)_Examplary structure:_[folder] images_new* [file] 0001.tif* [file] 0002.tif  Option A: Upload via _Google Drive_ (recommended, Colab only) - The folder in your drive must contain all images in one folder.- See [here](https://support.google.com/drive/answer/2375091?co=GENIE.Platform%3DDesktop&hl=en) how to organize your files in _Google Drive_.- See this [stackoverflow post](https://stackoverflow.com/questions/46986398/import-data-into-google-colaboratory) for browsing files with the file browser<jupyter_code>#@markdown Provide the path to the folder on your _Google Drive_
try:
    drive.mount('/content/drive')
    path = "/content/drive/My Drive/data" #@param {type:"string"}
    path = Path(path)
    print('Path contains the following files and folders: \n', L(os.listdir(path)))
    #@markdown Follow the instructions and press Enter after copying and pasting the key.
except:
    print("Warning: Connecting to Google Drive only works on Google Colab.")
    pass<jupyter_output><empty_output><jupyter_text>Option B: Upload via _zip_ file (Colab only) - The *zip* file must contain all images in one folder- See [here](https://www.hellotech.com/guide/for/how-to-zip-a-file-mac-windows-pc) how to _zip_ files on Windows or Mac.<jupyter_code>#@markdown Run to upload a *zip* file
path = Path('data')
try:
    u_dict = files.upload()
    for key in u_dict.keys():
        unzip(path, key)
    print('Path contains the following files and folders: \n', L(os.listdir(path)))
except:
    print("Warning: File upload only works on Google Colab.")
    pass<jupyter_output><empty_output><jupyter_text>Option C: Provide path (Local installation) If you're working on your local machine or server, provide a path to the correct folder.<jupyter_code>#@markdown Provide path (either relative to notebook or absolute) and run cell
path = "data" #@param {type:"string"}
path = Path(path)
print('Path contains the following files and folders: \n', L(os.listdir(path)))<jupyter_output><empty_output><jupyter_text>Option D: Try with sample data (Testing only) If you don't have any data available yet, try our sample data [Description]<jupyter_code>#@markdown Run to use sample files
path = Path('sample_data_cFOS')
url = "https://github.com/matjesg/deepflash2/releases/download/model_library/wue1_cFOS_small.zip"
urllib.request.urlretrieve(url, 'sample_data_cFOS.zip')
unzip(path, 'sample_data_cFOS.zip')
_ = shutil.move(path/'images', path/'images_new')<jupyter_output><empty_output><jupyter_text>Load data<jupyter_code>#@markdown Provide your parameters according to your provided data
image_folder = "images_new" #@param {type:"string"}
f_names = get_image_files(path/image_folder)
print(f'Found {len(f_names)} images in "{path}".')
#@markdown Number of classes: e.g., 2 for binary segmentation (foreground and background class)
n_classes = 2 #@param {type:"integer"}
ds = TileDataset(f_names, n_classes=n_classes)
#@markdown Run to show data. { run: "auto" }
#@markdown Use the slider to control the number of displayed images
first_n = 3 #@param {type:"slider", min:1, max:100, step:1}
ds.show_data(max_n=first_n, figsize=(5,5), overlay=False)<jupyter_output><empty_output><jupyter_text>Model Defintion - Select the same [model architecture](https://matjesg.github.io/deepflash2/models.htmlU-Net-architectures) as used during [Model Training](https://matjesg.github.io/deepflash2/train.html)<jupyter_code>#@title { run: "auto" }
model_arch = 'unet_deepflash2' #@param ["unet_deepflash2",  "unet_falk2019", "unet_ronnberger2015"]
n_channels = ds.get_data(max_n=1)[0].shape[-1]
model = torch.hub.load('matjesg/deepflash2', model_arch, pretrained=False, n_classes=ds.c, in_channels=n_channels, force_reload=True)
model_list = L()<jupyter_output><empty_output><jupyter_text>Option A: Load customized weights (recommended) - Works with _Google Drive_ connection or local installation.- If you haven't already done it, train your own models in the [Model Training Notebook](https://colab.research.google.com/github/matjesg/deepflash2/blob/master/nbs/train.ipynb)<jupyter_code>#@title { run: "auto" }
#@markdown Run to select models from `models_folder`. 
#@markdown Models should be saved in the 'models' folder of your provided path.
models_folder = "models" #@param {type:"string"}
model_list = get_files(path/models_folder, extensions='.pth')
print('Found models', model_list)<jupyter_output><empty_output><jupyter_text>Option B: Upload customized weights (Colab only)<jupyter_code>#@markdown Run to upload models. **CAN BE VERY SLOW**. { run: "auto" }
try:
    u_dict = files.upload()
    model_list += [Path(u) for u in u_dict]
except:
    print("Warning: File upload only works on Google Colab.")
    pass
print('Found models', model_list)<jupyter_output><empty_output><jupyter_text>Option C: Use pretrained weights from deepflash2 (dangerous) - Out-of-the-box prediction without prior validation can lead to invalid results.- See [Model Libray](https://matjesg.github.io/deepflash2/model_library.html) for more information.<jupyter_code>#@title { run: "auto" }
pretrained_weights = "wue_cFOS" #@param ["wue_cFOS", "wue_Parv", "wue_GFAP", "wue_GFP", "wue_OPN3"]
model = torch.hub.load('matjesg/deepflash2', model_arch, pretrained=True, dataset=pretrained_weights, n_classes=ds.c, in_channels=n_channels)
model_list = L(Path(f'{torch.hub.get_dir()}/checkpoints/{pretrained_weights}.pth'))<jupyter_output><empty_output><jupyter_text>Prediction<jupyter_code>#@markdown Run to predict segmentation masks for new images.
res, res_mc = {}, {}
for m in progress_bar(model_list):
    print(f'Model {m.stem}')
    dls = DataLoaders.from_dsets(ds, batch_size=4 ,shuffle=False, drop_last=False)
    state_dict = torch.load(m)
    model.load_state_dict(state_dict, strict=False)
    if torch.cuda.is_available(): dls.cuda(), model.cuda()
    learn = Learner(dls, model, loss_func=0)#.to_fp16()
    
    print(f'Predicting segmentation masks')
    smxs, segs, _ = learn.predict_tiles(dl=dls.train)   
    print(f'Predicting uncertainty maps')
    smxs_mc, segs_mc, std = learn.predict_tiles(dl=dls.train, mc_dropout=True, n_times=10)
    
    #TODO Save results not using RAM
    for i, file in enumerate(f_names):
        res[(m.stem, file)] = smxs[i], segs[i]
        res_mc[(m.stem, file)] = smxs_mc[i], segs_mc[i], std[i]<jupyter_output><empty_output><jupyter_text>Ensembling In this section you can ensemble (combine) the single model outputs.<jupyter_code>#@markdown Create folders to save the resuls. They will be created at your provided 'path'.
pred_dir = 'preds' #@param {type:"string"}
pred_path = path/pred_dir/'ensemble'
pred_path.mkdir(parents=True, exist_ok=True)
uncertainty_dir = 'uncertainties' #@param {type:"string"}
uncertainty_path = path/uncertainty_dir/'ensemble'
uncertainty_path.mkdir(parents=True, exist_ok=True)
result_path = path/'results'
result_path.mkdir(exist_ok=True)

#@markdown Define `filetype` to save the predictions and uncertainties. All common filetypes are supported.
filetype = 'png' #@param {type:"string"}
#@markdown Show and save ensemble results
res_list = []
for file in f_names:
    img = ds.get_data(file)[0]
    pred = ensemble_results(res, file)
    pred_std = ensemble_results(res_mc, file, std=True)
    df_tmp = pd.Series({'file' : file.name, 'entropy': entropy(pred_std, axis=None)})
    plot_results(img, pred, pred_std, df=df_tmp)
    res_list.append(df_tmp)
    imageio.imsave(pred_path/f'{file.name}_pred.{filetype}', pred.astype(np.uint8) if np.max(pred)>1 else pred.astype(np.uint8)*255)
    imageio.imsave(uncertainty_path/f'{file.name}_uncertainty.{filetype}', pred_std.astype(np.uint8)*255)
df_res = pd.DataFrame(res_list)
df_res.to_csv(result_path/'ensemble_results.csv', index=False)
#@markdown Show and save single model results
res_list = []
for file in f_names:
    print(f'###### File {file.name} ######')
    img = ds.get_data(file)[0]
    for model_path in model_list:
        model_name = model_path.stem
        val_files = [f for mod , f in res.keys() if mod == model_name]
        print(f'{model_name}')
        pred_path = path/pred_dir/model_name
        pred_path.mkdir(parents=True, exist_ok=True)
        uncertainty_path = path/uncertainty_dir/model_name
        uncertainty_path.mkdir(parents=True, exist_ok=True)
        pred = res[(model_name,file)][1]
        pred_std = res_mc[(model_name,file)][2][...,0]
        df_tmp = pd.Series({'file' : file.name,
                            'model' : model_name,
                            'entropy': entropy(pred_std, axis=None)})
        plot_results(img, pred, pred_std, df=df_tmp)
        res_list.append(df_tmp)
        imageio.imsave(pred_path/f'{file.stem}_pred.{filetype}', pred.astype(np.uint8) if np.max(pred)>1 else pred.astype(np.uint8)*255)
        imageio.imsave(uncertainty_path/f'{file.stem}_uncertainty.{filetype}', pred_std.astype(np.uint8)*255)
pd.DataFrame(res_list).to_csv(result_path/'model_results.csv', index=False)<jupyter_output><empty_output><jupyter_text>Download Section To download validation predictions and uncertainties, you first need to execute Section _Validate models and ensembles_._Note: If you're connected to *Google Drive*, the models are automatically saved to your drive._<jupyter_code>#@markdown Download predicitions { run: "auto" }
out_name = 'predictions'
shutil.make_archive(path/out_name, 'zip', path/pred_dir)
try:
    files.download(path/f'{out_name}.zip')
except:
    print("Warning: File download only works on Google Colab.")
    pass
#@markdown Download uncertainties
out_name = 'uncertainties'
shutil.make_archive(path/out_name, 'zip', path/uncertainty_dir)
try:
    files.download(path/f'{out_name}.zip')
except:
    print("Warning: File download only works on Google Colab.")
    pass
#@markdown Download ensemble result analysis '.csv' files
try:
    files.download(result_path/f'ensemble_results.csv')
except:
    print("Warning: File download only works on Google Colab.")
    pass
#@markdown Download model result analysis '.csv' files
try:
    files.download(result_path/'model_results.csv')
except:
    print("Warning: File download only works on Google Colab.")
    pass<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12282268870031264, 'fraction_numerical': 0.008575256811076373, 'mean_word_length': 5.361363636363636, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 56, 'https://': 10, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '240955', 'license': 'Apache-2.0', 'n_tokens_mistral': 3829, 'n_tokens_neox': 3699, 'n_words': 951, 'path': 'nbs/predict.ipynb', 'repo_name': 'adriHei/deepflash2', 'size': '11195'}