├── .gitignore ├── NiftiDataManager.py ├── main.py └── train.prototxt /.gitignore: -------------------------------------------------------------------------------- 1 | /data 2 | /__pycache__ -------------------------------------------------------------------------------- /NiftiDataManager.py: -------------------------------------------------------------------------------- 1 | import SimpleITK as sitk 2 | import numpy as np 3 | import os 4 | import glob 5 | import torch 6 | import math 7 | 8 | class NifitDataSet(torch.utils.data.Dataset): 9 | def __init__(self, data_folder, transform=None): 10 | self.data_folder = data_folder 11 | self.transform = transform 12 | self.dirlist = os.listdir(data_folder) 13 | 14 | # self.volume_files = glob.glob(data_folder+'volume*.nii') 15 | # self.seg_files = glob.glob(data_folder+'segmentation*.nii') 16 | # for filename in self.volume_files: 17 | # print filename 18 | # for filename in self.seg_files: 19 | # print filename 20 | 21 | def __checkexist__(self,path): 22 | if os.path.exists(path): 23 | return True 24 | else: 25 | return False 26 | 27 | def __getitem__(self, index): 28 | img_name = os.path.join(self.data_folder,self.dirlist[index],'volume.nii') 29 | seg_name = os.path.join(self.data_folder,self.dirlist[index],'segmentation.nii') 30 | 31 | # check file existence 32 | if not self.__checkexist__(img_name): 33 | print(img_name+' not exist!') 34 | return 35 | if not self.__checkexist__(seg_name): 36 | print(seg_name+' not exist!') 37 | return 38 | 39 | img_reader = sitk.ImageFileReader() 40 | img_reader.SetFileName(img_name) 41 | img = img_reader.Execute() 42 | 43 | seg_reader = sitk.ImageFileReader() 44 | seg_reader.SetFileName(seg_name) 45 | seg = seg_reader.Execute() 46 | 47 | sample = {'image':img, 'segmentation': seg} 48 | 49 | # apply transform to the data if necessary 50 | if self.transform: 51 | sample = self.transform(sample) 52 | 53 | return sample 54 | 55 | def __len__(self): 56 | return len(self.dirlist) 57 | 58 | class Resample(object): 59 | """Resample the volume in a sample to a given voxel size 60 | 61 | Args: 62 | voxel_size (float or tuple): Desired output size. 63 | If float, output volume is isotropic. 64 | If tuple, output voxel size is matched with voxel size 65 | Currently only support linear interpolation method 66 | """ 67 | 68 | def __init__(self, voxel_size): 69 | assert isinstance(voxel_size, (float, tuple)) 70 | if isinstance(voxel_size, float): 71 | self.voxel_size = (voxel_size,voxel_size,voxel_size) 72 | else: 73 | assert len(voxel_size) == 3 74 | self.voxel_size = voxel_size 75 | 76 | def __call__(self, sample): 77 | img, seg = sample['image'], sample['segmentation'] 78 | 79 | old_spacing = img.GetSpacing() 80 | old_size = img.GetSize() 81 | 82 | new_spacing = self.voxel_size 83 | 84 | new_size = [] 85 | for i in range(3): 86 | new_size.append(int(math.ceil(old_spacing[i]*old_size[i]/new_spacing[i]))) 87 | new_size = tuple(new_size) 88 | 89 | resampler = sitk.ResampleImageFilter() 90 | resampler.SetInterpolator(1) 91 | resampler.SetOutputSpacing(new_spacing) 92 | resampler.SetSize(new_size) 93 | 94 | # resample on image 95 | resampler.SetOutputOrigin(img.GetOrigin()) 96 | resampler.SetOutputDirection(img.GetDirection()) 97 | print("Resampling image...") 98 | img = resampler.Execute(img) 99 | 100 | # resample on segmentation 101 | resampler.SetOutputOrigin(seg.GetOrigin()) 102 | resampler.SetOutputDirection(seg.GetDirection()) 103 | print("Resampling segmentation...") 104 | seg = resampler.Execute(seg) 105 | 106 | return {'image': img, 'segmentation': seg} 107 | 108 | class Normalization(object): 109 | """Normalize an image by setting its mean to zero and variance to one.""" 110 | 111 | def __call__(self, sample): 112 | self.normalizeFilter = sitk.NormalizeImageFilter() 113 | print("Normalizing image...") 114 | img, seg = sample['image'], sample['segmentation'] 115 | img = self.normalizeFilter.Execute(img) 116 | 117 | return {'image': img, 'segmentation': seg} 118 | 119 | class SitkToTensor(object): 120 | """Convert sitk image to Tensors""" 121 | 122 | def __call__(self, sample): 123 | img, seg = sample['image'], sample['segmentation'] 124 | img_np = sitk.GetArrayFromImage(img) 125 | seg_np = sitk.GetArrayFromImage(seg) 126 | 127 | print(img_np) 128 | print(seg_np) 129 | 130 | img_np = np.float32(img_np) 131 | seg_np = np.uint8(seg_np) 132 | 133 | return {'image': torch.from_numpy(img_np), \ 134 | 'segmentation': torch.from_numpy(seg_np)} 135 | 136 | class RandomCrop(object): 137 | """Crop randomly the image in a sample. This is usually used for datat augmentation 138 | 139 | Args: 140 | output_size (tuple or int): Desired output size. If int, cubic crop 141 | is made. 142 | """ 143 | 144 | def __init__(self, output_size): 145 | assert isinstance(output_size, (int, tuple)) 146 | if isinstance(output_size, int): 147 | self.output_size = (output_size, output_size, output_size) 148 | else: 149 | assert len(output_size) == 3 150 | self.output_size = output_size 151 | 152 | def __call__(self,sample): 153 | img, seg = sample['image'], sample['segmentation'] 154 | size_old = img.GetSize() 155 | size_new = self.output_size 156 | 157 | contain_label = False 158 | 159 | roiFilter = sitk.RegionOfInterestImageFilter() 160 | roiFilter.SetSize([size_new[0],size_new[1],size_new[2]]) 161 | 162 | while not contain_label: 163 | # get the start crop coordinate in ijk 164 | start_i = np.random.randint(0, size_old[0]-size_new[0]) 165 | start_j = np.random.randint(0, size_old[1]-size_new[1]) 166 | start_k = np.random.randint(0, size_old[2]-size_new[2]) 167 | 168 | roiFilter.SetIndex([start_i,start_j,start_k]) 169 | 170 | seg_crop = roiFilter.Execute(seg) 171 | statFilter = sitk.StatisticsImageFilter() 172 | statFilter.Execute(seg_crop) 173 | 174 | # will iterate until a sub volume containing label is extracted 175 | if statFilter.GetSum()>=1: 176 | contain_label = True 177 | 178 | img_crop = roiFilter.Execute(img) 179 | 180 | return {'image': img_crop, 'segmentation': seg_crop} 181 | 182 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import torch 2 | import torchvision 3 | import torchvision.transforms as transforms 4 | import numpy as np 5 | import glob 6 | import os 7 | import SimpleITK as sitk 8 | import matplotlib.pyplot as plt 9 | import math 10 | import NiftiDataManager as NDM 11 | 12 | def load_data(data_path,batch_size): 13 | # apply transform to input data 14 | transform = transforms.Compose([NDM.Normalization(),\ 15 | NDM.Resample(0.7),\ 16 | NDM.RandomCrop(64),\ 17 | NDM.SitkToTensor()]) 18 | 19 | # load data 20 | train_set = NDM.NifitDataSet(os.path.join(data_path,'train'),transform=transform) 21 | train_loader = torch.utils.data.DataLoader(train_set, batch_size=batch_size,shuffle=True,num_workers=0,pin_memory=True) 22 | 23 | test_set = NDM.NifitDataSet(os.path.join(data_path,'test'),transform=transform) 24 | test_loader = torch.utils.data.DataLoader(train_set, batch_size=batch_size,shuffle=True,num_workers=0,pin_memory=True) 25 | 26 | return [train_loader,test_loader] 27 | 28 | def main(): 29 | #load data 30 | batch_size = 1 31 | data_folder = './data' 32 | load_data(data_folder, batch_size) 33 | [train_loader, test_loader] = load_data(data_folder, batch_size) 34 | 35 | print(train_loader.dataset[0]['image']) 36 | 37 | 38 | # sample = dataset[0] # get one sample from dataset 39 | 40 | # # img_np0 = sitk.GetArrayFromImage(sample['image']) 41 | # # # print img_np0.shape 42 | # # middle_slice_num_0 = int(img_np0.shape[2]/2) 43 | # # middle_slice_0 = img_np0[:,:,middle_slice_num_0] 44 | 45 | 46 | 47 | # sample_transformed = composed(sample) 48 | 49 | # img_np1 = sitk.GetArrayFromImage(sample_transformed['image']) 50 | # middle_slice_num_1 = int(img_np1.shape[2]/2) 51 | # middle_slice_1 = img_np1[:,:,middle_slice_num_1] 52 | 53 | # seg_np1 = sitk.GetArrayFromImage(sample_transformed['segmentation']) 54 | # middle_slice_num_1 = int(img_np1.shape[2]/2) 55 | # middle_slice_1_seg = seg_np1[:,:,middle_slice_num_1] 56 | 57 | # fig = plt.figure() 58 | # ax1 = plt.subplot(1,2,1) 59 | # plt.imshow(middle_slice_1, cmap='gray') 60 | # plt.axis('off') 61 | # ax2 = plt.subplot(1,2,2) 62 | # plt.imshow(middle_slice_1_seg, cmap='gray') 63 | # plt.axis('off') 64 | # plt.show() 65 | 66 | 67 | if __name__ == '__main__': 68 | main() -------------------------------------------------------------------------------- /train.prototxt: -------------------------------------------------------------------------------- 1 | layer { 2 | name: "data" 3 | type: "Input" 4 | top: "data" 5 | input_param { 6 | shape { 7 | dim: 5 8 | dim: 1 9 | dim: 156 10 | dim: 156 11 | dim: 8 12 | } 13 | } 14 | } 15 | layer { 16 | name: "label" 17 | type: "Input" 18 | top: "label" 19 | input_param { 20 | shape { 21 | dim: 5 22 | dim: 1 23 | dim: 156 24 | dim: 156 25 | dim: 8 26 | } 27 | } 28 | } 29 | layer { 30 | name: "d0b_conv" 31 | type: "Convolution" 32 | bottom: "data" 33 | top: "d0b_conv" 34 | param { 35 | lr_mult: 1.0 36 | decay_mult: 1.0 37 | } 38 | param { 39 | lr_mult: 2.0 40 | decay_mult: 0.0 41 | } 42 | convolution_param { 43 | num_output: 32 44 | pad: 1 45 | kernel_size: 3 46 | stride: 1 47 | weight_filler { 48 | type: "msra" 49 | } 50 | bias_filler { 51 | type: "constant" 52 | value: 0.0 53 | } 54 | engine: CAFFE 55 | } 56 | } 57 | layer { 58 | name: "d0b_bn" 59 | type: "BatchNorm" 60 | bottom: "d0b_conv" 61 | top: "d0b_conv" 62 | param { 63 | lr_mult: 0.0 64 | } 65 | param { 66 | lr_mult: 0.0 67 | } 68 | param { 69 | lr_mult: 0.0 70 | } 71 | batch_norm_param { 72 | use_global_stats: false 73 | } 74 | } 75 | layer { 76 | name: "d0b_scale" 77 | type: "Scale" 78 | bottom: "d0b_conv" 79 | top: "d0b_conv" 80 | scale_param { 81 | axis: 1 82 | filler { 83 | type: "constant" 84 | value: 1.0 85 | } 86 | bias_term: true 87 | bias_filler { 88 | type: "constant" 89 | value: 0.0 90 | } 91 | } 92 | } 93 | layer { 94 | name: "d0b_relu" 95 | type: "ReLU" 96 | bottom: "d0b_conv" 97 | top: "d0b_conv" 98 | relu_param { 99 | engine: CAFFE 100 | } 101 | } 102 | layer { 103 | name: "d0c_conv" 104 | type: "Convolution" 105 | bottom: "d0b_conv" 106 | top: "d0c_conv" 107 | param { 108 | lr_mult: 1.0 109 | decay_mult: 1.0 110 | } 111 | param { 112 | lr_mult: 2.0 113 | decay_mult: 0.0 114 | } 115 | convolution_param { 116 | num_output: 32 117 | pad: 1 118 | kernel_size: 3 119 | stride: 1 120 | weight_filler { 121 | type: "msra" 122 | } 123 | bias_filler { 124 | type: "constant" 125 | value: 0.0 126 | } 127 | engine: CAFFE 128 | } 129 | } 130 | layer { 131 | name: "d0c_bn" 132 | type: "BatchNorm" 133 | bottom: "d0c_conv" 134 | top: "d0c_conv" 135 | param { 136 | lr_mult: 0.0 137 | } 138 | param { 139 | lr_mult: 0.0 140 | } 141 | param { 142 | lr_mult: 0.0 143 | } 144 | batch_norm_param { 145 | use_global_stats: false 146 | } 147 | } 148 | layer { 149 | name: "d0c_scale" 150 | type: "Scale" 151 | bottom: "d0c_conv" 152 | top: "d0c_conv" 153 | scale_param { 154 | axis: 1 155 | filler { 156 | type: "constant" 157 | value: 1.0 158 | } 159 | bias_term: true 160 | bias_filler { 161 | type: "constant" 162 | value: 0.0 163 | } 164 | } 165 | } 166 | layer { 167 | name: "d0c_relu" 168 | type: "ReLU" 169 | bottom: "d0c_conv" 170 | top: "d0c_conv" 171 | relu_param { 172 | engine: CAFFE 173 | } 174 | } 175 | layer { 176 | name: "d1a_pool" 177 | type: "PoolingND" 178 | bottom: "d0c_conv" 179 | top: "d1a_pool" 180 | pooling_nd_param { 181 | pool: MAX 182 | pad: 0 183 | kernel_size: 2 184 | stride: 2 185 | engine: CAFFE 186 | } 187 | } 188 | layer { 189 | name: "d1b_conv" 190 | type: "Convolution" 191 | bottom: "d1a_pool" 192 | top: "d1b_conv" 193 | param { 194 | lr_mult: 1.0 195 | decay_mult: 1.0 196 | } 197 | param { 198 | lr_mult: 2.0 199 | decay_mult: 0.0 200 | } 201 | convolution_param { 202 | num_output: 64 203 | pad: 1 204 | kernel_size: 3 205 | stride: 1 206 | weight_filler { 207 | type: "msra" 208 | } 209 | bias_filler { 210 | type: "constant" 211 | value: 0.0 212 | } 213 | engine: CAFFE 214 | } 215 | } 216 | layer { 217 | name: "d1b_bn" 218 | type: "BatchNorm" 219 | bottom: "d1b_conv" 220 | top: "d1b_conv" 221 | param { 222 | lr_mult: 0.0 223 | } 224 | param { 225 | lr_mult: 0.0 226 | } 227 | param { 228 | lr_mult: 0.0 229 | } 230 | batch_norm_param { 231 | use_global_stats: false 232 | } 233 | } 234 | layer { 235 | name: "d1b_scale" 236 | type: "Scale" 237 | bottom: "d1b_conv" 238 | top: "d1b_conv" 239 | scale_param { 240 | axis: 1 241 | filler { 242 | type: "constant" 243 | value: 1.0 244 | } 245 | bias_term: true 246 | bias_filler { 247 | type: "constant" 248 | value: 0.0 249 | } 250 | } 251 | } 252 | layer { 253 | name: "d1b_relu" 254 | type: "ReLU" 255 | bottom: "d1b_conv" 256 | top: "d1b_conv" 257 | relu_param { 258 | engine: CAFFE 259 | } 260 | } 261 | layer { 262 | name: "d1c_conv" 263 | type: "Convolution" 264 | bottom: "d1b_conv" 265 | top: "d1c_conv" 266 | param { 267 | lr_mult: 1.0 268 | decay_mult: 1.0 269 | } 270 | param { 271 | lr_mult: 2.0 272 | decay_mult: 0.0 273 | } 274 | convolution_param { 275 | num_output: 64 276 | pad: 1 277 | kernel_size: 3 278 | stride: 1 279 | weight_filler { 280 | type: "msra" 281 | } 282 | bias_filler { 283 | type: "constant" 284 | value: 0.0 285 | } 286 | engine: CAFFE 287 | } 288 | } 289 | layer { 290 | name: "d1c_bn" 291 | type: "BatchNorm" 292 | bottom: "d1c_conv" 293 | top: "d1c_conv" 294 | param { 295 | lr_mult: 0.0 296 | } 297 | param { 298 | lr_mult: 0.0 299 | } 300 | param { 301 | lr_mult: 0.0 302 | } 303 | batch_norm_param { 304 | use_global_stats: false 305 | } 306 | } 307 | layer { 308 | name: "d1c_scale" 309 | type: "Scale" 310 | bottom: "d1c_conv" 311 | top: "d1c_conv" 312 | scale_param { 313 | axis: 1 314 | filler { 315 | type: "constant" 316 | value: 1.0 317 | } 318 | bias_term: true 319 | bias_filler { 320 | type: "constant" 321 | value: 0.0 322 | } 323 | } 324 | } 325 | layer { 326 | name: "d1c_relu" 327 | type: "ReLU" 328 | bottom: "d1c_conv" 329 | top: "d1c_conv" 330 | relu_param { 331 | engine: CAFFE 332 | } 333 | } 334 | layer { 335 | name: "d2a_pool" 336 | type: "PoolingND" 337 | bottom: "d1c_conv" 338 | top: "d2a_pool" 339 | pooling_nd_param { 340 | pool: MAX 341 | pad: 0 342 | kernel_size: 2 343 | stride: 2 344 | engine: CAFFE 345 | } 346 | } 347 | layer { 348 | name: "d2b_conv" 349 | type: "Convolution" 350 | bottom: "d2a_pool" 351 | top: "d2b_conv" 352 | param { 353 | lr_mult: 1.0 354 | decay_mult: 1.0 355 | } 356 | param { 357 | lr_mult: 2.0 358 | decay_mult: 0.0 359 | } 360 | convolution_param { 361 | num_output: 128 362 | pad: 1 363 | kernel_size: 3 364 | stride: 1 365 | weight_filler { 366 | type: "msra" 367 | } 368 | bias_filler { 369 | type: "constant" 370 | value: 0.0 371 | } 372 | engine: CAFFE 373 | } 374 | } 375 | layer { 376 | name: "d2b_bn" 377 | type: "BatchNorm" 378 | bottom: "d2b_conv" 379 | top: "d2b_conv" 380 | param { 381 | lr_mult: 0.0 382 | } 383 | param { 384 | lr_mult: 0.0 385 | } 386 | param { 387 | lr_mult: 0.0 388 | } 389 | batch_norm_param { 390 | use_global_stats: false 391 | } 392 | } 393 | layer { 394 | name: "d2b_scale" 395 | type: "Scale" 396 | bottom: "d2b_conv" 397 | top: "d2b_conv" 398 | scale_param { 399 | axis: 1 400 | filler { 401 | type: "constant" 402 | value: 1.0 403 | } 404 | bias_term: true 405 | bias_filler { 406 | type: "constant" 407 | value: 0.0 408 | } 409 | } 410 | } 411 | layer { 412 | name: "d2b_relu" 413 | type: "ReLU" 414 | bottom: "d2b_conv" 415 | top: "d2b_conv" 416 | relu_param { 417 | engine: CAFFE 418 | } 419 | } 420 | layer { 421 | name: "d2c_conv" 422 | type: "Convolution" 423 | bottom: "d2b_conv" 424 | top: "d2c_conv" 425 | param { 426 | lr_mult: 1.0 427 | decay_mult: 1.0 428 | } 429 | param { 430 | lr_mult: 2.0 431 | decay_mult: 0.0 432 | } 433 | convolution_param { 434 | num_output: 128 435 | pad: 1 436 | kernel_size: 3 437 | stride: 1 438 | weight_filler { 439 | type: "msra" 440 | } 441 | bias_filler { 442 | type: "constant" 443 | value: 0.0 444 | } 445 | engine: CAFFE 446 | } 447 | } 448 | layer { 449 | name: "d2c_bn" 450 | type: "BatchNorm" 451 | bottom: "d2c_conv" 452 | top: "d2c_conv" 453 | param { 454 | lr_mult: 0.0 455 | } 456 | param { 457 | lr_mult: 0.0 458 | } 459 | param { 460 | lr_mult: 0.0 461 | } 462 | batch_norm_param { 463 | use_global_stats: false 464 | } 465 | } 466 | layer { 467 | name: "d2c_scale" 468 | type: "Scale" 469 | bottom: "d2c_conv" 470 | top: "d2c_conv" 471 | scale_param { 472 | axis: 1 473 | filler { 474 | type: "constant" 475 | value: 1.0 476 | } 477 | bias_term: true 478 | bias_filler { 479 | type: "constant" 480 | value: 0.0 481 | } 482 | } 483 | } 484 | layer { 485 | name: "d2c_relu" 486 | type: "ReLU" 487 | bottom: "d2c_conv" 488 | top: "d2c_conv" 489 | relu_param { 490 | engine: CAFFE 491 | } 492 | } 493 | layer { 494 | name: "d3a_pool" 495 | type: "PoolingND" 496 | bottom: "d2c_conv" 497 | top: "d3a_pool" 498 | pooling_nd_param { 499 | pool: MAX 500 | pad: 0 501 | kernel_size: 2 502 | stride: 2 503 | engine: CAFFE 504 | } 505 | } 506 | layer { 507 | name: "d3b_conv" 508 | type: "Convolution" 509 | bottom: "d3a_pool" 510 | top: "d3b_conv" 511 | param { 512 | lr_mult: 1.0 513 | decay_mult: 1.0 514 | } 515 | param { 516 | lr_mult: 2.0 517 | decay_mult: 0.0 518 | } 519 | convolution_param { 520 | num_output: 256 521 | pad: 1 522 | kernel_size: 3 523 | stride: 1 524 | weight_filler { 525 | type: "msra" 526 | } 527 | bias_filler { 528 | type: "constant" 529 | value: 0.0 530 | } 531 | engine: CAFFE 532 | } 533 | } 534 | layer { 535 | name: "d3b_bn" 536 | type: "BatchNorm" 537 | bottom: "d3b_conv" 538 | top: "d3b_conv" 539 | param { 540 | lr_mult: 0.0 541 | } 542 | param { 543 | lr_mult: 0.0 544 | } 545 | param { 546 | lr_mult: 0.0 547 | } 548 | batch_norm_param { 549 | use_global_stats: false 550 | } 551 | } 552 | layer { 553 | name: "d3b_scale" 554 | type: "Scale" 555 | bottom: "d3b_conv" 556 | top: "d3b_conv" 557 | scale_param { 558 | axis: 1 559 | filler { 560 | type: "constant" 561 | value: 1.0 562 | } 563 | bias_term: true 564 | bias_filler { 565 | type: "constant" 566 | value: 0.0 567 | } 568 | } 569 | } 570 | layer { 571 | name: "d3b_relu" 572 | type: "ReLU" 573 | bottom: "d3b_conv" 574 | top: "d3b_conv" 575 | relu_param { 576 | engine: CAFFE 577 | } 578 | } 579 | layer { 580 | name: "d3c_conv" 581 | type: "Convolution" 582 | bottom: "d3b_conv" 583 | top: "d3c_conv" 584 | param { 585 | lr_mult: 1.0 586 | decay_mult: 1.0 587 | } 588 | param { 589 | lr_mult: 2.0 590 | decay_mult: 0.0 591 | } 592 | convolution_param { 593 | num_output: 256 594 | pad: 1 595 | kernel_size: 3 596 | stride: 1 597 | weight_filler { 598 | type: "msra" 599 | } 600 | bias_filler { 601 | type: "constant" 602 | value: 0.0 603 | } 604 | engine: CAFFE 605 | } 606 | } 607 | layer { 608 | name: "d3c_bn" 609 | type: "BatchNorm" 610 | bottom: "d3c_conv" 611 | top: "d3c_conv" 612 | param { 613 | lr_mult: 0.0 614 | } 615 | param { 616 | lr_mult: 0.0 617 | } 618 | param { 619 | lr_mult: 0.0 620 | } 621 | batch_norm_param { 622 | use_global_stats: false 623 | } 624 | } 625 | layer { 626 | name: "d3c_scale" 627 | type: "Scale" 628 | bottom: "d3c_conv" 629 | top: "d3c_conv" 630 | scale_param { 631 | axis: 1 632 | filler { 633 | type: "constant" 634 | value: 1.0 635 | } 636 | bias_term: true 637 | bias_filler { 638 | type: "constant" 639 | value: 0.0 640 | } 641 | } 642 | } 643 | layer { 644 | name: "d3c_relu" 645 | type: "ReLU" 646 | bottom: "d3c_conv" 647 | top: "d3c_conv" 648 | relu_param { 649 | engine: CAFFE 650 | } 651 | } 652 | layer { 653 | name: "u2a_dconv" 654 | type: "Deconvolution" 655 | bottom: "d3c_conv" 656 | top: "u2a_dconv" 657 | param { 658 | lr_mult: 1.0 659 | decay_mult: 1.0 660 | } 661 | convolution_param { 662 | num_output: 128 663 | bias_term: false 664 | pad: 0 665 | kernel_size: 2 666 | stride: 2 667 | weight_filler { 668 | type: "msra" 669 | } 670 | engine: CAFFE 671 | } 672 | } 673 | layer { 674 | name: "u2a_bn" 675 | type: "BatchNorm" 676 | bottom: "u2a_dconv" 677 | top: "u2a_dconv" 678 | param { 679 | lr_mult: 0.0 680 | } 681 | param { 682 | lr_mult: 0.0 683 | } 684 | param { 685 | lr_mult: 0.0 686 | } 687 | batch_norm_param { 688 | use_global_stats: false 689 | } 690 | } 691 | layer { 692 | name: "u2a_scale" 693 | type: "Scale" 694 | bottom: "u2a_dconv" 695 | top: "u2a_dconv" 696 | scale_param { 697 | axis: 1 698 | filler { 699 | type: "constant" 700 | value: 1.0 701 | } 702 | bias_term: true 703 | bias_filler { 704 | type: "constant" 705 | value: 0.0 706 | } 707 | } 708 | } 709 | layer { 710 | name: "u2a_relu" 711 | type: "ReLU" 712 | bottom: "u2a_dconv" 713 | top: "u2a_dconv" 714 | relu_param { 715 | engine: CAFFE 716 | } 717 | } 718 | layer { 719 | name: "u2b_crop" 720 | type: "Crop" 721 | bottom: "u2a_dconv" 722 | bottom: "d2c_conv" 723 | top: "u2b_crop" 724 | crop_param { 725 | axis: 2 726 | offset: 0 727 | } 728 | } 729 | layer { 730 | name: "u2b_concat" 731 | type: "Concat" 732 | bottom: "u2b_crop" 733 | bottom: "d2c_conv" 734 | top: "u2b_concat" 735 | concat_param { 736 | axis: 1 737 | } 738 | } 739 | layer { 740 | name: "u2c_conv" 741 | type: "Convolution" 742 | bottom: "u2b_concat" 743 | top: "u2c_conv" 744 | param { 745 | lr_mult: 1.0 746 | decay_mult: 1.0 747 | } 748 | param { 749 | lr_mult: 2.0 750 | decay_mult: 0.0 751 | } 752 | convolution_param { 753 | num_output: 128 754 | pad: 1 755 | kernel_size: 3 756 | stride: 1 757 | weight_filler { 758 | type: "msra" 759 | } 760 | bias_filler { 761 | type: "constant" 762 | value: 0.0 763 | } 764 | engine: CAFFE 765 | } 766 | } 767 | layer { 768 | name: "u2c_bn" 769 | type: "BatchNorm" 770 | bottom: "u2c_conv" 771 | top: "u2c_conv" 772 | param { 773 | lr_mult: 0.0 774 | } 775 | param { 776 | lr_mult: 0.0 777 | } 778 | param { 779 | lr_mult: 0.0 780 | } 781 | batch_norm_param { 782 | use_global_stats: false 783 | } 784 | } 785 | layer { 786 | name: "u2c_scale" 787 | type: "Scale" 788 | bottom: "u2c_conv" 789 | top: "u2c_conv" 790 | scale_param { 791 | axis: 1 792 | filler { 793 | type: "constant" 794 | value: 1.0 795 | } 796 | bias_term: true 797 | bias_filler { 798 | type: "constant" 799 | value: 0.0 800 | } 801 | } 802 | } 803 | layer { 804 | name: "u2c_relu" 805 | type: "ReLU" 806 | bottom: "u2c_conv" 807 | top: "u2c_conv" 808 | relu_param { 809 | engine: CAFFE 810 | } 811 | } 812 | layer { 813 | name: "u2d_conv" 814 | type: "Convolution" 815 | bottom: "u2c_conv" 816 | top: "u2d_conv" 817 | param { 818 | lr_mult: 1.0 819 | decay_mult: 1.0 820 | } 821 | param { 822 | lr_mult: 2.0 823 | decay_mult: 0.0 824 | } 825 | convolution_param { 826 | num_output: 128 827 | pad: 1 828 | kernel_size: 3 829 | stride: 1 830 | weight_filler { 831 | type: "msra" 832 | } 833 | bias_filler { 834 | type: "constant" 835 | value: 0.0 836 | } 837 | engine: CAFFE 838 | } 839 | } 840 | layer { 841 | name: "u2d_bn" 842 | type: "BatchNorm" 843 | bottom: "u2d_conv" 844 | top: "u2d_conv" 845 | param { 846 | lr_mult: 0.0 847 | } 848 | param { 849 | lr_mult: 0.0 850 | } 851 | param { 852 | lr_mult: 0.0 853 | } 854 | batch_norm_param { 855 | use_global_stats: false 856 | } 857 | } 858 | layer { 859 | name: "u2d_scale" 860 | type: "Scale" 861 | bottom: "u2d_conv" 862 | top: "u2d_conv" 863 | scale_param { 864 | axis: 1 865 | filler { 866 | type: "constant" 867 | value: 1.0 868 | } 869 | bias_term: true 870 | bias_filler { 871 | type: "constant" 872 | value: 0.0 873 | } 874 | } 875 | } 876 | layer { 877 | name: "u2d_relu" 878 | type: "ReLU" 879 | bottom: "u2d_conv" 880 | top: "u2d_conv" 881 | relu_param { 882 | engine: CAFFE 883 | } 884 | } 885 | layer { 886 | name: "u1a_dconv" 887 | type: "Deconvolution" 888 | bottom: "u2d_conv" 889 | top: "u1a_dconv" 890 | param { 891 | lr_mult: 1.0 892 | decay_mult: 1.0 893 | } 894 | convolution_param { 895 | num_output: 64 896 | bias_term: false 897 | pad: 0 898 | kernel_size: 2 899 | stride: 2 900 | weight_filler { 901 | type: "msra" 902 | } 903 | engine: CAFFE 904 | } 905 | } 906 | layer { 907 | name: "u1a_bn" 908 | type: "BatchNorm" 909 | bottom: "u1a_dconv" 910 | top: "u1a_dconv" 911 | param { 912 | lr_mult: 0.0 913 | } 914 | param { 915 | lr_mult: 0.0 916 | } 917 | param { 918 | lr_mult: 0.0 919 | } 920 | batch_norm_param { 921 | use_global_stats: false 922 | } 923 | } 924 | layer { 925 | name: "u1a_scale" 926 | type: "Scale" 927 | bottom: "u1a_dconv" 928 | top: "u1a_dconv" 929 | scale_param { 930 | axis: 1 931 | filler { 932 | type: "constant" 933 | value: 1.0 934 | } 935 | bias_term: true 936 | bias_filler { 937 | type: "constant" 938 | value: 0.0 939 | } 940 | } 941 | } 942 | layer { 943 | name: "u1a_relu" 944 | type: "ReLU" 945 | bottom: "u1a_dconv" 946 | top: "u1a_dconv" 947 | relu_param { 948 | engine: CAFFE 949 | } 950 | } 951 | layer { 952 | name: "u1b_crop" 953 | type: "Crop" 954 | bottom: "u1a_dconv" 955 | bottom: "d1c_conv" 956 | top: "u1b_crop" 957 | crop_param { 958 | axis: 2 959 | offset: 0 960 | } 961 | } 962 | layer { 963 | name: "u1b_concat" 964 | type: "Concat" 965 | bottom: "u1b_crop" 966 | bottom: "d1c_conv" 967 | top: "u1b_concat" 968 | concat_param { 969 | axis: 1 970 | } 971 | } 972 | layer { 973 | name: "u1c_conv" 974 | type: "Convolution" 975 | bottom: "u1b_concat" 976 | top: "u1c_conv" 977 | param { 978 | lr_mult: 1.0 979 | decay_mult: 1.0 980 | } 981 | param { 982 | lr_mult: 2.0 983 | decay_mult: 0.0 984 | } 985 | convolution_param { 986 | num_output: 64 987 | pad: 1 988 | kernel_size: 3 989 | stride: 1 990 | weight_filler { 991 | type: "msra" 992 | } 993 | bias_filler { 994 | type: "constant" 995 | value: 0.0 996 | } 997 | engine: CAFFE 998 | } 999 | } 1000 | layer { 1001 | name: "u1c_bn" 1002 | type: "BatchNorm" 1003 | bottom: "u1c_conv" 1004 | top: "u1c_conv" 1005 | param { 1006 | lr_mult: 0.0 1007 | } 1008 | param { 1009 | lr_mult: 0.0 1010 | } 1011 | param { 1012 | lr_mult: 0.0 1013 | } 1014 | batch_norm_param { 1015 | use_global_stats: false 1016 | } 1017 | } 1018 | layer { 1019 | name: "u1c_scale" 1020 | type: "Scale" 1021 | bottom: "u1c_conv" 1022 | top: "u1c_conv" 1023 | scale_param { 1024 | axis: 1 1025 | filler { 1026 | type: "constant" 1027 | value: 1.0 1028 | } 1029 | bias_term: true 1030 | bias_filler { 1031 | type: "constant" 1032 | value: 0.0 1033 | } 1034 | } 1035 | } 1036 | layer { 1037 | name: "u1c_relu" 1038 | type: "ReLU" 1039 | bottom: "u1c_conv" 1040 | top: "u1c_conv" 1041 | relu_param { 1042 | engine: CAFFE 1043 | } 1044 | } 1045 | layer { 1046 | name: "u1d_conv" 1047 | type: "Convolution" 1048 | bottom: "u1c_conv" 1049 | top: "u1d_conv" 1050 | param { 1051 | lr_mult: 1.0 1052 | decay_mult: 1.0 1053 | } 1054 | param { 1055 | lr_mult: 2.0 1056 | decay_mult: 0.0 1057 | } 1058 | convolution_param { 1059 | num_output: 64 1060 | pad: 1 1061 | kernel_size: 3 1062 | stride: 1 1063 | weight_filler { 1064 | type: "msra" 1065 | } 1066 | bias_filler { 1067 | type: "constant" 1068 | value: 0.0 1069 | } 1070 | engine: CAFFE 1071 | } 1072 | } 1073 | layer { 1074 | name: "u1d_bn" 1075 | type: "BatchNorm" 1076 | bottom: "u1d_conv" 1077 | top: "u1d_conv" 1078 | param { 1079 | lr_mult: 0.0 1080 | } 1081 | param { 1082 | lr_mult: 0.0 1083 | } 1084 | param { 1085 | lr_mult: 0.0 1086 | } 1087 | batch_norm_param { 1088 | use_global_stats: false 1089 | } 1090 | } 1091 | layer { 1092 | name: "u1d_scale" 1093 | type: "Scale" 1094 | bottom: "u1d_conv" 1095 | top: "u1d_conv" 1096 | scale_param { 1097 | axis: 1 1098 | filler { 1099 | type: "constant" 1100 | value: 1.0 1101 | } 1102 | bias_term: true 1103 | bias_filler { 1104 | type: "constant" 1105 | value: 0.0 1106 | } 1107 | } 1108 | } 1109 | layer { 1110 | name: "u1d_relu" 1111 | type: "ReLU" 1112 | bottom: "u1d_conv" 1113 | top: "u1d_conv" 1114 | relu_param { 1115 | engine: CAFFE 1116 | } 1117 | } 1118 | layer { 1119 | name: "u0a_dconv" 1120 | type: "Deconvolution" 1121 | bottom: "u1d_conv" 1122 | top: "u0a_dconv" 1123 | param { 1124 | lr_mult: 1.0 1125 | decay_mult: 1.0 1126 | } 1127 | convolution_param { 1128 | num_output: 32 1129 | bias_term: false 1130 | pad: 0 1131 | kernel_size: 2 1132 | stride: 2 1133 | weight_filler { 1134 | type: "msra" 1135 | } 1136 | engine: CAFFE 1137 | } 1138 | } 1139 | layer { 1140 | name: "u0a_bn" 1141 | type: "BatchNorm" 1142 | bottom: "u0a_dconv" 1143 | top: "u0a_dconv" 1144 | param { 1145 | lr_mult: 0.0 1146 | } 1147 | param { 1148 | lr_mult: 0.0 1149 | } 1150 | param { 1151 | lr_mult: 0.0 1152 | } 1153 | batch_norm_param { 1154 | use_global_stats: false 1155 | } 1156 | } 1157 | layer { 1158 | name: "u0a_scale" 1159 | type: "Scale" 1160 | bottom: "u0a_dconv" 1161 | top: "u0a_dconv" 1162 | scale_param { 1163 | axis: 1 1164 | filler { 1165 | type: "constant" 1166 | value: 1.0 1167 | } 1168 | bias_term: true 1169 | bias_filler { 1170 | type: "constant" 1171 | value: 0.0 1172 | } 1173 | } 1174 | } 1175 | layer { 1176 | name: "u0a_relu" 1177 | type: "ReLU" 1178 | bottom: "u0a_dconv" 1179 | top: "u0a_dconv" 1180 | relu_param { 1181 | engine: CAFFE 1182 | } 1183 | } 1184 | layer { 1185 | name: "u0b_crop" 1186 | type: "Crop" 1187 | bottom: "u0a_dconv" 1188 | bottom: "d0c_conv" 1189 | top: "u0b_crop" 1190 | crop_param { 1191 | axis: 2 1192 | offset: 0 1193 | } 1194 | } 1195 | layer { 1196 | name: "u0b_concat" 1197 | type: "Concat" 1198 | bottom: "u0b_crop" 1199 | bottom: "d0c_conv" 1200 | top: "u0b_concat" 1201 | concat_param { 1202 | axis: 1 1203 | } 1204 | } 1205 | layer { 1206 | name: "u0c_conv" 1207 | type: "Convolution" 1208 | bottom: "u0b_concat" 1209 | top: "u0c_conv" 1210 | param { 1211 | lr_mult: 1.0 1212 | decay_mult: 1.0 1213 | } 1214 | param { 1215 | lr_mult: 2.0 1216 | decay_mult: 0.0 1217 | } 1218 | convolution_param { 1219 | num_output: 32 1220 | pad: 1 1221 | kernel_size: 3 1222 | stride: 1 1223 | weight_filler { 1224 | type: "msra" 1225 | } 1226 | bias_filler { 1227 | type: "constant" 1228 | value: 0.0 1229 | } 1230 | engine: CAFFE 1231 | } 1232 | } 1233 | layer { 1234 | name: "u0c_bn" 1235 | type: "BatchNorm" 1236 | bottom: "u0c_conv" 1237 | top: "u0c_conv" 1238 | param { 1239 | lr_mult: 0.0 1240 | } 1241 | param { 1242 | lr_mult: 0.0 1243 | } 1244 | param { 1245 | lr_mult: 0.0 1246 | } 1247 | batch_norm_param { 1248 | use_global_stats: false 1249 | } 1250 | } 1251 | layer { 1252 | name: "u0c_scale" 1253 | type: "Scale" 1254 | bottom: "u0c_conv" 1255 | top: "u0c_conv" 1256 | scale_param { 1257 | axis: 1 1258 | filler { 1259 | type: "constant" 1260 | value: 1.0 1261 | } 1262 | bias_term: true 1263 | bias_filler { 1264 | type: "constant" 1265 | value: 0.0 1266 | } 1267 | } 1268 | } 1269 | layer { 1270 | name: "u0c_relu" 1271 | type: "ReLU" 1272 | bottom: "u0c_conv" 1273 | top: "u0c_conv" 1274 | relu_param { 1275 | engine: CAFFE 1276 | } 1277 | } 1278 | layer { 1279 | name: "u0d_conv" 1280 | type: "Convolution" 1281 | bottom: "u0c_conv" 1282 | top: "u0d_conv" 1283 | param { 1284 | lr_mult: 1.0 1285 | decay_mult: 1.0 1286 | } 1287 | param { 1288 | lr_mult: 2.0 1289 | decay_mult: 0.0 1290 | } 1291 | convolution_param { 1292 | num_output: 32 1293 | pad: 1 1294 | kernel_size: 3 1295 | stride: 1 1296 | weight_filler { 1297 | type: "msra" 1298 | } 1299 | bias_filler { 1300 | type: "constant" 1301 | value: 0.0 1302 | } 1303 | engine: CAFFE 1304 | } 1305 | } 1306 | layer { 1307 | name: "u0d_bn" 1308 | type: "BatchNorm" 1309 | bottom: "u0d_conv" 1310 | top: "u0d_conv" 1311 | param { 1312 | lr_mult: 0.0 1313 | } 1314 | param { 1315 | lr_mult: 0.0 1316 | } 1317 | param { 1318 | lr_mult: 0.0 1319 | } 1320 | batch_norm_param { 1321 | use_global_stats: false 1322 | } 1323 | } 1324 | layer { 1325 | name: "u0d_scale" 1326 | type: "Scale" 1327 | bottom: "u0d_conv" 1328 | top: "u0d_conv" 1329 | scale_param { 1330 | axis: 1 1331 | filler { 1332 | type: "constant" 1333 | value: 1.0 1334 | } 1335 | bias_term: true 1336 | bias_filler { 1337 | type: "constant" 1338 | value: 0.0 1339 | } 1340 | } 1341 | } 1342 | layer { 1343 | name: "u0d_relu" 1344 | type: "ReLU" 1345 | bottom: "u0d_conv" 1346 | top: "u0d_conv" 1347 | relu_param { 1348 | engine: CAFFE 1349 | } 1350 | } 1351 | layer { 1352 | name: "score" 1353 | type: "Convolution" 1354 | bottom: "u0d_conv" 1355 | top: "score" 1356 | param { 1357 | lr_mult: 1.0 1358 | decay_mult: 1.0 1359 | } 1360 | param { 1361 | lr_mult: 2.0 1362 | decay_mult: 0.0 1363 | } 1364 | convolution_param { 1365 | num_output: 2 1366 | pad: 0 1367 | kernel_size: 1 1368 | stride: 1 1369 | weight_filler { 1370 | type: "msra" 1371 | } 1372 | bias_filler { 1373 | type: "constant" 1374 | value: 0.0 1375 | } 1376 | engine: CAFFE 1377 | } 1378 | } 1379 | layer { 1380 | name: "loss" 1381 | type: "SoftmaxWithLoss" 1382 | bottom: "score" 1383 | bottom: "label" 1384 | top: "loss" 1385 | loss_weight: 1.0 1386 | phase: TRAIN 1387 | loss_param { 1388 | ignore_label: 255 1389 | } 1390 | } 1391 | --------------------------------------------------------------------------------