biomedisa 2024.5.14__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. biomedisa/__init__.py +53 -0
  2. biomedisa/__main__.py +18 -0
  3. biomedisa/biomedisa_features/DataGenerator.py +299 -0
  4. biomedisa/biomedisa_features/DataGeneratorCrop.py +121 -0
  5. biomedisa/biomedisa_features/PredictDataGenerator.py +87 -0
  6. biomedisa/biomedisa_features/PredictDataGeneratorCrop.py +74 -0
  7. biomedisa/biomedisa_features/__init__.py +0 -0
  8. biomedisa/biomedisa_features/active_contour.py +434 -0
  9. biomedisa/biomedisa_features/amira_to_np/__init__.py +0 -0
  10. biomedisa/biomedisa_features/amira_to_np/amira_data_stream.py +980 -0
  11. biomedisa/biomedisa_features/amira_to_np/amira_grammar.py +369 -0
  12. biomedisa/biomedisa_features/amira_to_np/amira_header.py +290 -0
  13. biomedisa/biomedisa_features/amira_to_np/amira_helper.py +72 -0
  14. biomedisa/biomedisa_features/assd.py +167 -0
  15. biomedisa/biomedisa_features/biomedisa_helper.py +801 -0
  16. biomedisa/biomedisa_features/create_slices.py +286 -0
  17. biomedisa/biomedisa_features/crop_helper.py +586 -0
  18. biomedisa/biomedisa_features/curvop_numba.py +149 -0
  19. biomedisa/biomedisa_features/django_env.py +172 -0
  20. biomedisa/biomedisa_features/keras_helper.py +1219 -0
  21. biomedisa/biomedisa_features/nc_reader.py +179 -0
  22. biomedisa/biomedisa_features/pid.py +52 -0
  23. biomedisa/biomedisa_features/process_image.py +253 -0
  24. biomedisa/biomedisa_features/pycuda_test.py +84 -0
  25. biomedisa/biomedisa_features/random_walk/__init__.py +0 -0
  26. biomedisa/biomedisa_features/random_walk/gpu_kernels.py +183 -0
  27. biomedisa/biomedisa_features/random_walk/pycuda_large.py +826 -0
  28. biomedisa/biomedisa_features/random_walk/pycuda_large_allx.py +806 -0
  29. biomedisa/biomedisa_features/random_walk/pycuda_small.py +414 -0
  30. biomedisa/biomedisa_features/random_walk/pycuda_small_allx.py +493 -0
  31. biomedisa/biomedisa_features/random_walk/pyopencl_large.py +760 -0
  32. biomedisa/biomedisa_features/random_walk/pyopencl_small.py +441 -0
  33. biomedisa/biomedisa_features/random_walk/rw_large.py +390 -0
  34. biomedisa/biomedisa_features/random_walk/rw_small.py +310 -0
  35. biomedisa/biomedisa_features/remove_outlier.py +399 -0
  36. biomedisa/biomedisa_features/split_volume.py +274 -0
  37. biomedisa/deeplearning.py +519 -0
  38. biomedisa/interpolation.py +371 -0
  39. biomedisa/mesh.py +406 -0
  40. biomedisa-2024.5.14.dist-info/LICENSE +191 -0
  41. biomedisa-2024.5.14.dist-info/METADATA +306 -0
  42. biomedisa-2024.5.14.dist-info/RECORD +44 -0
  43. biomedisa-2024.5.14.dist-info/WHEEL +5 -0
  44. biomedisa-2024.5.14.dist-info/top_level.txt +1 -0
@@ -0,0 +1,519 @@
1
+ #!/usr/bin/python3
2
+ ##########################################################################
3
+ ## ##
4
+ ## Copyright (c) 2024 Philipp Lösel. All rights reserved. ##
5
+ ## ##
6
+ ## This file is part of the open source project biomedisa. ##
7
+ ## ##
8
+ ## Licensed under the European Union Public Licence (EUPL) ##
9
+ ## v1.2, or - as soon as they will be approved by the ##
10
+ ## European Commission - subsequent versions of the EUPL; ##
11
+ ## ##
12
+ ## You may redistribute it and/or modify it under the terms ##
13
+ ## of the EUPL v1.2. You may not use this work except in ##
14
+ ## compliance with this Licence. ##
15
+ ## ##
16
+ ## You can obtain a copy of the Licence at: ##
17
+ ## ##
18
+ ## https://joinup.ec.europa.eu/page/eupl-text-11-12 ##
19
+ ## ##
20
+ ## Unless required by applicable law or agreed to in ##
21
+ ## writing, software distributed under the Licence is ##
22
+ ## distributed on an "AS IS" basis, WITHOUT WARRANTIES ##
23
+ ## OR CONDITIONS OF ANY KIND, either express or implied. ##
24
+ ## ##
25
+ ## See the Licence for the specific language governing ##
26
+ ## permissions and limitations under the Licence. ##
27
+ ## ##
28
+ ##########################################################################
29
+
30
+ import sys, os
31
+ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
32
+ sys.path.append(BASE_DIR)
33
+ import biomedisa
34
+ import biomedisa_features.crop_helper as ch
35
+ from biomedisa_features.keras_helper import *
36
+ from biomedisa_features.biomedisa_helper import _error_
37
+ from tensorflow.python.framework.errors_impl import ResourceExhaustedError
38
+ import tensorflow as tf
39
+ import numpy as np
40
+ import traceback
41
+ import argparse
42
+ import h5py
43
+ import time
44
+ import subprocess
45
+ import glob
46
+
47
+ class Biomedisa(object):
48
+ pass
49
+
50
+ def get_gpu_memory():
51
+ try:
52
+ result = subprocess.check_output(['nvidia-smi', '--query-gpu=memory.free', '--format=csv,nounits,noheader'], encoding='utf-8')
53
+ # Convert lines to list
54
+ gpu_memory = [int(x) for x in result.strip().split('\n')]
55
+ return gpu_memory
56
+ except:
57
+ return None
58
+
59
+ def deep_learning(img_data, label_data=None, val_img_data=None, val_label_data=None,
60
+ path_to_images=None, path_to_labels=None, val_images=None, val_labels=None,
61
+ path_to_model=None, predict=False, train=False, header_file=None,
62
+ balance=False, crop_data=False, flip_x=False, flip_y=False, flip_z=False,
63
+ swapaxes=False, train_dice=False, val_dice=True, no_compression=False, ignore='none', only='all',
64
+ network_filters='32-64-128-256-512', resnet=False, debug_cropping=False,
65
+ save_cropped=False, epochs=100, no_normalization=False, rotate=0.0, validation_split=0.0,
66
+ learning_rate=0.01, stride_size=32, validation_stride_size=32, validation_freq=1,
67
+ batch_size=None, x_scale=256, y_scale=256, z_scale=256, no_scaling=False, early_stopping=0,
68
+ pretrained_model=None, fine_tune=False, workers=1, cropping_epochs=50,
69
+ x_range=None, y_range=None, z_range=None, header=None, extension='.tif',
70
+ img_header=None, img_extension='.tif', average_dice=False, django_env=False,
71
+ path=None, success=True, return_probs=False, patch_normalization=False,
72
+ z_patch=64, y_patch=64, x_patch=64, path_to_logfile=None, img_id=None, label_id=None,
73
+ remote=False, queue=0, username=None, shortfilename=None, dice_loss=False,
74
+ acwe=False, acwe_alpha=1.0, acwe_smooth=1, acwe_steps=3, clean=None, fill=None):
75
+
76
+ # create biomedisa
77
+ bm = Biomedisa()
78
+ bm.process = 'deep_learning'
79
+ results = None
80
+
81
+ # time
82
+ TIC = time.time()
83
+
84
+ # transfer arguments
85
+ key_copy = tuple(locals().keys())
86
+ for arg in key_copy:
87
+ bm.__dict__[arg] = locals()[arg]
88
+
89
+ # compression
90
+ if bm.no_compression:
91
+ bm.compression = False
92
+ else:
93
+ bm.compression = True
94
+
95
+ # normalization
96
+ if bm.no_normalization:
97
+ bm.normalize = 0
98
+ else:
99
+ bm.normalize = 1
100
+
101
+ # django environment
102
+ if bm.django_env:
103
+ from biomedisa_app.views import unique_file_path
104
+ from biomedisa_features.django_env import create_pid_object
105
+
106
+ # path to image data
107
+ if bm.train:
108
+
109
+ # training files
110
+ bm.path_to_images = bm.path_to_images.split(',')[:-1]
111
+ bm.path_to_labels = bm.path_to_labels.split(',')[:-1]
112
+
113
+ # validation files
114
+ if bm.val_images is not None:
115
+ bm.val_images = bm.val_images.split(',')[:-1]
116
+ bm.val_labels = bm.val_labels.split(',')[:-1]
117
+ else:
118
+ bm.val_images = [None]
119
+ bm.val_labels = [None]
120
+
121
+ # project name
122
+ project = os.path.splitext(bm.shortfilename)[0]
123
+
124
+ # path to model
125
+ bm.path_to_model = BASE_DIR + f'/private_storage/images/{bm.username}/{project}.h5'
126
+ if not bm.remote:
127
+ bm.path_to_model = unique_file_path(bm.path_to_model)
128
+
129
+ if bm.predict:
130
+ project = os.path.splitext(os.path.basename(bm.path_to_model))[0]
131
+
132
+ # create pid object
133
+ create_pid_object(os.getpid(), bm.remote, bm.queue, bm.img_id, (bm.path_to_model if bm.train else ''))
134
+
135
+ # write in log file
136
+ with open(bm.path_to_logfile, 'a') as logfile:
137
+ print('%s %s %s %s' %(time.ctime(), bm.username, bm.shortfilename, 'Process was started.'), file=logfile)
138
+ print(f'PROJECT:{project} PREDICT:{bm.predict} IMG:{bm.shortfilename}', file=logfile)
139
+ if bm.train:
140
+ print(f'IMG_LIST:{bm.path_to_images} LABEL_LIST:{bm.path_to_labels} VAL_IMG_LIST:{bm.val_images} VAL_LABEL_LIST:{bm.val_labels}', file=logfile)
141
+
142
+ # path to model
143
+ if bm.train and not bm.path_to_model:
144
+ current_time = time.strftime("%d-%m-%Y_%H-%M-%S", time.localtime())
145
+ bm.path_to_model = os.getcwd() + f'/biomedisa_{current_time}.h5'
146
+ if bm.predict and not bm.path_to_model:
147
+ raise Exception("'path_to_model' must be specified")
148
+
149
+ # disable file saving when called as a function
150
+ if img_data is not None:
151
+ bm.path_to_images = None
152
+ bm.path_to_cropped_image = None
153
+
154
+ # adapt scaling to stride size and patch size
155
+ bm.stride_size = max(1, min(bm.stride_size, 64))
156
+ bm.x_scale = bm.x_scale - (bm.x_scale - bm.x_patch) % bm.stride_size
157
+ bm.y_scale = bm.y_scale - (bm.y_scale - bm.y_patch) % bm.stride_size
158
+ bm.z_scale = bm.z_scale - (bm.z_scale - bm.z_patch) % bm.stride_size
159
+
160
+ # adapt batch size to available gpu memory
161
+ if bm.batch_size is None:
162
+ bm.batch_size = 6
163
+ gpu_memory = get_gpu_memory()
164
+ if gpu_memory:
165
+ if bm.predict:
166
+ gpu_memory = gpu_memory[:1]
167
+ if 14000 < np.sum(gpu_memory) < 28000:
168
+ bm.batch_size = 12
169
+ elif 28000 <= np.sum(gpu_memory):
170
+ bm.batch_size = 24
171
+
172
+ if bm.train:
173
+
174
+ # path to results
175
+ bm.path_to_final = None
176
+ bm.path_to_cropped_image = None
177
+
178
+ # get number of GPUs
179
+ strategy = tf.distribute.MirroredStrategy()
180
+ ngpus = int(strategy.num_replicas_in_sync)
181
+
182
+ # batch size must be divisible by the number of GPUs and two
183
+ rest = bm.batch_size % (2*ngpus)
184
+ if 2*ngpus - rest < rest:
185
+ bm.batch_size = bm.batch_size + 2*ngpus - rest
186
+ else:
187
+ bm.batch_size = bm.batch_size - rest
188
+
189
+ if not bm.django_env:
190
+ bm.path_to_images, bm.path_to_labels = [bm.path_to_images], [bm.path_to_labels]
191
+ bm.val_images, bm.val_labels = [bm.val_images], [bm.val_labels]
192
+
193
+ # train automatic cropping
194
+ bm.cropping_weights, bm.cropping_config, bm.cropping_norm = None, None, None
195
+ if bm.crop_data:
196
+ bm.cropping_weights, bm.cropping_config, bm.cropping_norm = ch.load_and_train(
197
+ bm.normalize, bm.path_to_images, bm.path_to_labels, bm.path_to_model,
198
+ bm.cropping_epochs, bm.batch_size, bm.validation_split,
199
+ bm.flip_x, bm.flip_y, bm.flip_z, bm.rotate, bm.only, bm.ignore,
200
+ bm.val_images, bm.val_labels, img_data, label_data,
201
+ val_img_data, val_label_data)
202
+
203
+ # train automatic segmentation
204
+ train_semantic_segmentation(bm, bm.path_to_images, bm.path_to_labels,
205
+ bm.val_images, bm.val_labels,
206
+ img_data, label_data,
207
+ val_img_data, val_label_data,
208
+ header, extension)
209
+
210
+ if bm.predict:
211
+
212
+ # get meta data
213
+ hf = h5py.File(bm.path_to_model, 'r')
214
+ meta = hf.get('meta')
215
+ configuration = meta.get('configuration')
216
+ channels, bm.x_scale, bm.y_scale, bm.z_scale, normalize, mu, sig = np.array(configuration)[:]
217
+ channels, bm.x_scale, bm.y_scale, bm.z_scale, normalize, mu, sig = int(channels), int(bm.x_scale), \
218
+ int(bm.y_scale), int(bm.z_scale), int(normalize), float(mu), float(sig)
219
+ if '/meta/normalization' in hf:
220
+ normalization_parameters = np.array(meta.get('normalization'), dtype=float)
221
+ else:
222
+ normalization_parameters = np.array([[mu],[sig]])
223
+ allLabels = np.array(meta.get('labels'))
224
+ # check if amira header is available in the network
225
+ if header is None and meta.get('header') is not None:
226
+ header = [np.array(meta.get('header'))]
227
+ extension = '.am'
228
+ crop_data = True if 'cropping_weights' in hf else False
229
+ hf.close()
230
+
231
+ # extract image files
232
+ bm.tmp_dir = None
233
+ if bm.path_to_images is not None and (os.path.splitext(bm.path_to_images)[1]=='.tar' or bm.path_to_images[-7:]=='.tar.gz'):
234
+ path_to_dir = os.path.dirname(bm.path_to_images) + '/final.'+os.path.basename(bm.path_to_images)
235
+ if path_to_dir[-3:]=='.gz':
236
+ path_to_dir = path_to_dir[:-3]
237
+ if bm.django_env and not bm.remote:
238
+ path_to_dir = unique_file_path(path_to_dir)
239
+ bm.tmp_dir = BASE_DIR + '/tmp/' + id_generator(40)
240
+ tar = tarfile.open(bm.path_to_images)
241
+ tar.extractall(path=bm.tmp_dir)
242
+ tar.close()
243
+ bm.path_to_images = bm.tmp_dir
244
+ bm.save_cropped, bm.acwe = False, False
245
+ bm.clean, bm.fill = None, None
246
+
247
+ # list of images
248
+ path_to_finals = []
249
+ if bm.path_to_images is not None and os.path.isdir(bm.path_to_images):
250
+ files = glob.glob(bm.path_to_images+'/**/*', recursive=True)
251
+ bm.path_to_images = [f for f in files if os.path.isfile(f)]
252
+ else:
253
+ bm.path_to_images = [bm.path_to_images]
254
+
255
+ # loop over all images
256
+ for bm.path_to_image in bm.path_to_images:
257
+
258
+ # create path_to_final
259
+ if bm.path_to_image:
260
+ filename = os.path.basename(bm.path_to_image)
261
+ filename = os.path.splitext(filename)[0]
262
+ if filename[-4:] == '.nii':
263
+ filename = filename[:-4]
264
+ bm.path_to_cropped_image = os.path.dirname(bm.path_to_image) + '/' + filename + '.cropped.tif'
265
+ if bm.django_env and not bm.remote and not bm.tmp_dir:
266
+ bm.path_to_cropped_image = unique_file_path(bm.path_to_cropped_image)
267
+ filename = 'final.' + filename
268
+ bm.path_to_final = os.path.dirname(bm.path_to_image) + '/' + filename + extension
269
+ if bm.django_env and not bm.remote and not bm.tmp_dir:
270
+ bm.path_to_final = unique_file_path(bm.path_to_final)
271
+
272
+ # crop data
273
+ region_of_interest, cropped_volume = None, None
274
+ if crop_data:
275
+ region_of_interest, cropped_volume = ch.crop_data(bm.path_to_image, bm.path_to_model, bm.path_to_cropped_image,
276
+ bm.batch_size, bm.debug_cropping, bm.save_cropped, img_data, bm.x_range, bm.y_range, bm.z_range)
277
+
278
+ # load prediction data
279
+ img, img_header, z_shape, y_shape, x_shape, region_of_interest, img_data = load_prediction_data(bm.path_to_image,
280
+ channels, bm.x_scale, bm.y_scale, bm.z_scale, bm.no_scaling, normalize, normalization_parameters,
281
+ region_of_interest, img_data, img_header)
282
+
283
+ # make prediction
284
+ results, bm = predict_semantic_segmentation(bm, img, bm.path_to_model,
285
+ bm.z_patch, bm.y_patch, bm.x_patch, z_shape, y_shape, x_shape, bm.compression, header,
286
+ img_header, bm.stride_size, allLabels, bm.batch_size, region_of_interest,
287
+ bm.no_scaling, extension, img_data)
288
+
289
+ # results
290
+ if cropped_volume is not None:
291
+ results['cropped_volume'] = cropped_volume
292
+
293
+ # path to results
294
+ if bm.path_to_image:
295
+ path_to_finals.append(bm.path_to_final)
296
+
297
+ # write tar file and delete extracted image files
298
+ if bm.tmp_dir is not None and os.path.exists(bm.tmp_dir):
299
+ with tarfile.open(path_to_dir, 'w') as tar:
300
+ for file_path in path_to_finals:
301
+ file_name = os.path.basename(file_path)
302
+ tar.add(file_path, arcname=file_name)
303
+ shutil.rmtree(bm.tmp_dir)
304
+ bm.path_to_final = path_to_dir
305
+ bm.path_to_cropped_image = None
306
+
307
+ # computation time
308
+ t = int(time.time() - TIC)
309
+ if t < 60:
310
+ time_str = str(t) + " sec"
311
+ elif 60 <= t < 3600:
312
+ time_str = str(t // 60) + " min " + str(t % 60) + " sec"
313
+ elif 3600 < t:
314
+ time_str = str(t // 3600) + " h " + str((t % 3600) // 60) + " min " + str(t % 60) + " sec"
315
+ print('Total calculation time:', time_str)
316
+
317
+ # django environment
318
+ if bm.django_env:
319
+ from biomedisa_app.config import config
320
+ from biomedisa_features.django_env import post_processing
321
+ validation=True if bm.validation_split or (bm.val_images is not None and bm.val_images[0] is not None) else False
322
+ post_processing(bm.path_to_final, time_str, config['SERVER_ALIAS'], bm.remote, bm.queue,
323
+ img_id=bm.img_id, label_id=bm.label_id, path_to_model=bm.path_to_model,
324
+ path_to_cropped_image=(bm.path_to_cropped_image if crop_data else None),
325
+ train=bm.train, predict=bm.predict, validation=validation)
326
+
327
+ # write in log file
328
+ path_to_time = BASE_DIR + '/log/time.txt'
329
+ with open(path_to_time, 'a') as timefile:
330
+ if predict:
331
+ message = 'Successfully segmented ' + bm.shortfilename
332
+ else:
333
+ message = 'Successfully trained ' + project
334
+ print('%s %s %s %s on %s' %(time.ctime(), bm.username, message, time_str, config['SERVER_ALIAS']), file=timefile)
335
+
336
+ return results
337
+
338
+ if __name__ == '__main__':
339
+
340
+ # initialize arguments
341
+ parser = argparse.ArgumentParser(description='Biomedisa deeplearning.',
342
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter)
343
+
344
+ # mutually exclusive group
345
+ g = parser.add_mutually_exclusive_group()
346
+
347
+ # required arguments
348
+ parser.add_argument('path_to_images', type=str, metavar='PATH_TO_IMAGES',
349
+ help='Location of image data (tarball, directory, or file)')
350
+ parser.add_argument('path', type=str, metavar='PATH',
351
+ help='Location of label data during training (tarball, directory, or file) or model for prediction (h5)')
352
+
353
+ # optional arguments
354
+ g.add_argument('-p','--predict', action='store_true', default=False,
355
+ help='Automatic/predict segmentation')
356
+ g.add_argument('-t','--train', action='store_true', default=False,
357
+ help='Train neural network')
358
+ parser.add_argument('-v', '--version', action='version', version=f'{biomedisa.__version__}',
359
+ help='Biomedisa version')
360
+ parser.add_argument('-b','--balance', action='store_true', default=False,
361
+ help='Balance foreground and background training patches')
362
+ parser.add_argument('-cd','--crop_data', action='store_true', default=False,
363
+ help='Crop data automatically to region of interest')
364
+ parser.add_argument('--acwe', action='store_true', default=False,
365
+ help='Post-processing with active contour')
366
+ parser.add_argument('--acwe_alpha', metavar='ALPHA', type=float, default=1.0,
367
+ help='Pushing force of active contour')
368
+ parser.add_argument('--acwe_smooth', metavar='SMOOTH', type=int, default=1,
369
+ help='Smoothing steps of active contour')
370
+ parser.add_argument('--acwe_steps', metavar='STEPS', type=int, default=3,
371
+ help='Iterations of active contour')
372
+ parser.add_argument('-c','--clean', nargs='?', type=float, const=0.1, default=None,
373
+ help='Remove outliers, e.g. 0.5 means that objects smaller than 50 percent of the size of the largest object will be removed')
374
+ parser.add_argument('-f','--fill', nargs='?', type=float, const=0.9, default=None,
375
+ help='Fill holes, e.g. 0.5 means that all holes smaller than 50 percent of the entire label will be filled')
376
+ parser.add_argument('--flip_x', action='store_true', default=False,
377
+ help='Randomly flip x-axis during training')
378
+ parser.add_argument('--flip_y', action='store_true', default=False,
379
+ help='Randomly flip y-axis during training')
380
+ parser.add_argument('--flip_z', action='store_true', default=False,
381
+ help='Randomly flip z-axis during training')
382
+ parser.add_argument('-sa','--swapaxes', action='store_true', default=False,
383
+ help='Randomly swap two axes during training')
384
+ parser.add_argument('-td','--train_dice', action='store_true', default=False,
385
+ help='Monitor Dice score on training data')
386
+ parser.add_argument('-nvd','--no-val_dice', dest='val_dice', action='store_false',
387
+ help='Disable monitoring of Dice score on validation data')
388
+ parser.add_argument('-dl','--dice_loss', action='store_true', default=False,
389
+ help='Dice loss function')
390
+ parser.add_argument('-ad','--average_dice', action='store_true', default=False,
391
+ help='Use averaged dice score of each label')
392
+ parser.add_argument('-nc', '--no_compression', action='store_true', default=False,
393
+ help='Disable compression of segmentation results')
394
+ parser.add_argument('-i', '--ignore', type=str, default='none',
395
+ help='Ignore specific label(s), e.g. 2,5,6')
396
+ parser.add_argument('-o', '--only', type=str, default='all',
397
+ help='Segment only specific label(s), e.g. 1,3,5')
398
+ parser.add_argument('-nf', '--network_filters', type=str, default='32-64-128-256-512',
399
+ help='Number of filters per layer up to the deepest, e.g. 32-64-128-256-512')
400
+ parser.add_argument('-rn','--resnet', action='store_true', default=False,
401
+ help='Use U-resnet instead of standard U-net')
402
+ parser.add_argument('-dc','--debug_cropping', action='store_true', default=False,
403
+ help='Debug cropping')
404
+ parser.add_argument('-sc','--save_cropped', action='store_true', default=False,
405
+ help='Save automatically cropped image')
406
+ parser.add_argument('-e','--epochs', type=int, default=100,
407
+ help='Epochs the network is trained')
408
+ parser.add_argument('-ce','--cropping_epochs', type=int, default=50,
409
+ help='Epochs the network for auto-cropping is trained')
410
+ parser.add_argument('-nn','--no_normalization', action='store_true', default=False,
411
+ help='Disable image normalization')
412
+ parser.add_argument('-r','--rotate', type=float, default=0.0,
413
+ help='Randomly rotate during training')
414
+ parser.add_argument('-vs','--validation_split', type=float, default=0.0,
415
+ help='Percentage of data used for validation')
416
+ parser.add_argument('-lr','--learning_rate', type=float, default=0.01,
417
+ help='Learning rate')
418
+ parser.add_argument('-ss','--stride_size', metavar="[1-64]", type=int, choices=range(1,65), default=32,
419
+ help='Stride size for patches')
420
+ parser.add_argument('-vss','--validation_stride_size', metavar="[1-64]", type=int, choices=range(1,65), default=32,
421
+ help='Stride size for validation patches')
422
+ parser.add_argument('-vf','--validation_freq', type=int, default=1,
423
+ help='Epochs performed before validation')
424
+ parser.add_argument('-bs','--batch_size', type=int, default=None,
425
+ help='Number of samples processed in a batch')
426
+ parser.add_argument('-vi','--val_images', type=str, metavar='PATH', default=None,
427
+ help='Location of validation image data (tarball, directory, or file)')
428
+ parser.add_argument('-vl','--val_labels', type=str, metavar='PATH', default=None,
429
+ help='Location of validation label data (tarball, directory, or file)')
430
+ parser.add_argument('-xs','--x_scale', type=int, default=256,
431
+ help='Images and labels are scaled at x-axis to this size before training')
432
+ parser.add_argument('-ys','--y_scale', type=int, default=256,
433
+ help='Images and labels are scaled at y-axis to this size before training')
434
+ parser.add_argument('-zs','--z_scale', type=int, default=256,
435
+ help='Images and labels are scaled at z-axis to this size before training')
436
+ parser.add_argument('-ns','--no_scaling', action='store_true', default=False,
437
+ help='Do not resize image and label data')
438
+ parser.add_argument('-es','--early_stopping', type=int, default=0,
439
+ help='Training is terminated when the accuracy has not increased in the epochs defined by this')
440
+ parser.add_argument('-pm','--pretrained_model', type=str, metavar='PATH', default=None,
441
+ help='Location of pretrained model (only encoder will be trained if specified)')
442
+ parser.add_argument('-ft','--fine_tune', action='store_true', default=False,
443
+ help='Fine-tune the entire pretrained model. Choose a smaller learning rate, e.g. 0.0001')
444
+ parser.add_argument('-w','--workers', type=int, default=1,
445
+ help='Parallel workers for batch processing')
446
+ parser.add_argument('-xr','--x_range', nargs="+", type=int, default=None,
447
+ help='Manually crop x-axis of image data for prediction, e.g. -xr 100 200')
448
+ parser.add_argument('-yr','--y_range', nargs="+", type=int, default=None,
449
+ help='Manually crop y-axis of image data for prediction, e.g. -xr 100 200')
450
+ parser.add_argument('-zr','--z_range', nargs="+", type=int, default=None,
451
+ help='Manually crop z-axis of image data for prediction, e.g. -xr 100 200')
452
+ parser.add_argument('-rp','--return_probs', action='store_true', default=False,
453
+ help='Return prediction probabilities for each label')
454
+ parser.add_argument('-pn','--patch_normalization', action='store_true', default=False,
455
+ help='Scale each patch to mean zero and standard deviation')
456
+ parser.add_argument('-xp','--x_patch', type=int, default=64,
457
+ help='X-dimension of patch')
458
+ parser.add_argument('-yp','--y_patch', type=int, default=64,
459
+ help='Y-dimension of patch')
460
+ parser.add_argument('-zp','--z_patch', type=int, default=64,
461
+ help='Z-dimension of patch')
462
+ parser.add_argument('-iid','--img_id', type=str, default=None,
463
+ help='Image ID within django environment/browser version')
464
+ parser.add_argument('-lid','--label_id', type=str, default=None,
465
+ help='Label ID within django environment/browser version')
466
+ parser.add_argument('-re','--remote', action='store_true', default=False,
467
+ help='The interpolation is carried out on a remote server. Must be set up in config.py')
468
+ parser.add_argument('-q','--queue', type=int, default=0,
469
+ help='Processing queue when using a remote server')
470
+ parser.add_argument('-hf','--header_file', type=str, metavar='PATH', default=None,
471
+ help='Location of header file')
472
+ bm = parser.parse_args()
473
+
474
+ bm.success = True
475
+ if bm.predict:
476
+ bm.path_to_labels = None
477
+ bm.path_to_model = bm.path
478
+ if bm.train:
479
+ bm.path_to_labels = bm.path
480
+ bm.path_to_model = bm.path_to_images + '.h5'
481
+
482
+ # django environment
483
+ if bm.img_id is not None:
484
+ bm.django_env = True
485
+ if bm.train:
486
+ reference_image_path = bm.path_to_images.split(',')[:-1][-1]
487
+ else:
488
+ reference_image_path = bm.path_to_images
489
+ bm.username = os.path.basename(os.path.dirname(reference_image_path))
490
+ bm.shortfilename = os.path.basename(reference_image_path)
491
+ bm.path_to_logfile = BASE_DIR + '/log/logfile.txt'
492
+ else:
493
+ bm.django_env = False
494
+
495
+ kwargs = vars(bm)
496
+
497
+ # train or predict segmentation
498
+ try:
499
+ deep_learning(None, **kwargs)
500
+ except InputError:
501
+ if any(InputError.img_names):
502
+ remove_extracted_data(InputError.img_names, InputError.label_names)
503
+ print(traceback.format_exc())
504
+ bm = _error_(bm, f'{InputError.message}')
505
+ except ch.InputError:
506
+ if any(ch.InputError.img_names):
507
+ remove_extracted_data(ch.InputError.img_names, ch.InputError.label_names)
508
+ print(traceback.format_exc())
509
+ bm = _error_(bm, f'{ch.InputError.message}')
510
+ except MemoryError:
511
+ print(traceback.format_exc())
512
+ bm = _error_(bm, 'MemoryError')
513
+ except ResourceExhaustedError:
514
+ print(traceback.format_exc())
515
+ bm = _error_(bm, 'GPU out of memory. Reduce your batch size')
516
+ except Exception as e:
517
+ print(traceback.format_exc())
518
+ bm = _error_(bm, e)
519
+