code: # Copyright 2017 Division of Medical Image Computing, German Cancer Research Center (DKFZ)
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #     http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  import os
  import glob
  from os.path import join
  import numpy as np
  import torch
  import torch.nn as nn
  import torch.nn.functional as F
  from torch.optim import Adamax
  from torch.optim import Adam
  import torch.optim.lr_scheduler as lr_scheduler
  from torch.autograd import Variable
  
  from tractseg.libs.PytorchUtils import PytorchUtils
  from tractseg.libs.ExpUtils import ExpUtils
  from tractseg.models.BaseModel import BaseModel
  from tractseg.libs.PytorchUtils import conv2d
  from tractseg.libs.PytorchUtils import deconv2d
  
  
  class UNet_Pytorch_DeepSup(torch.nn.Module):
      def __init__(self, n_input_channels=3, n_classes=7, n_filt=64, batchnorm=False, dropout=False):
          super(UNet_Pytorch_DeepSup, self).__init__()
  
          self.dropout = dropout
  
          self.in_channel = n_input_channels
          self.n_classes = n_classes
  
          self.contr_1_1 = conv2d(n_input_channels, n_filt)
          self.contr_1_2 = conv2d(n_filt, n_filt)
          self.pool_1 = nn.MaxPool2d((2, 2))
  
          self.contr_2_1 = conv2d(n_filt, n_filt * 2)
          self.contr_2_2 = conv2d(n_filt * 2, n_filt * 2)
          self.pool_2 = nn.MaxPool2d((2, 2))
  
          self.contr_3_1 = conv2d(n_filt * 2, n_filt * 4)
          self.contr_3_2 = conv2d(n_filt * 4, n_filt * 4)
          self.pool_3 = nn.MaxPool2d((2, 2))
  
          self.contr_4_1 = conv2d(n_filt * 4, n_filt * 8)
          self.contr_4_2 = conv2d(n_filt * 8, n_filt * 8)
          self.pool_4 = nn.MaxPool2d((2, 2))
  
          self.dropout = nn.Dropout(p=0.4)
  
          self.encode_1 = conv2d(n_filt * 8, n_filt * 16)
          self.encode_2 = conv2d(n_filt * 16, n_filt * 16)
          self.deconv_1 = deconv2d(n_filt * 16, n_filt * 16, kernel_size=2, stride=2)
          # self.deconv_1 = nn.Upsample(scale_factor=2)     #does only upscale width and height  #Similar results to deconv2d
  
          self.expand_1_1 = conv2d(n_filt * 8 + n_filt * 16, n_filt * 8)
          self.expand_1_2 = conv2d(n_filt * 8, n_filt * 8)
          self.deconv_2 = deconv2d(n_filt * 8, n_filt * 8, kernel_size=2, stride=2)
          # self.deconv_2 = nn.Upsample(scale_factor=2)
  
          self.expand_2_1 = conv2d(n_filt * 4 + n_filt * 8, n_filt * 4, stride=1)
          self.expand_2_2 = conv2d(n_filt * 4, n_filt * 4, stride=1)
          self.deconv_3 = deconv2d(n_filt * 4, n_filt * 4, kernel_size=2, stride=2)
          # self.deconv_3 = nn.Upsample(scale_factor=2)
  
          self.output_2 = nn.Conv2d(n_filt * 4 + n_filt * 8, n_classes, kernel_size=1, stride=1, padding=0, bias=True)
          self.output_2_up = nn.Upsample(scale_factor=2, mode='bilinear')  # does only upscale width and height
  
          self.expand_3_1 = conv2d(n_filt * 2 + n_filt * 4, n_filt * 2, stride=1)
          self.expand_3_2 = conv2d(n_filt * 2, n_filt * 2, stride=1)
          self.deconv_4 = deconv2d(n_filt * 2, n_filt * 2, kernel_size=2, stride=2)
          # self.deconv_4 = nn.Upsample(scale_factor=2)
  
          self.output_3 = nn.Conv2d(n_filt * 2 + n_filt * 4, n_classes, kernel_size=1, stride=1, padding=0, bias=True)
          self.output_3_up = nn.Upsample(scale_factor=2, mode='bilinear')  # does only upscale width and height
  
          self.expand_4_1 = conv2d(n_filt + n_filt * 2, n_filt, stride=1)
          self.expand_4_2 = conv2d(n_filt, n_filt, stride=1)
  
          self.conv_5 = nn.Conv2d(n_filt, n_classes, kernel_size=1, stride=1, padding=0, bias=True)  # no activation function, because is in LossFunction (...WithLogits)
  
      def forward(self, inpt):
          contr_1_1 = self.contr_1_1(inpt)
          contr_1_2 = self.contr_1_2(contr_1_1)
          pool_1 = self.pool_1(contr_1_2)
  
          contr_2_1 = self.contr_2_1(pool_1)
          contr_2_2 = self.contr_2_2(contr_2_1)
          pool_2 = self.pool_2(contr_2_2)
  
          contr_3_1 = self.contr_3_1(pool_2)
          contr_3_2 = self.contr_3_2(contr_3_1)
          pool_3 = self.pool_3(contr_3_2)
  
          contr_4_1 = self.contr_4_1(pool_3)
          contr_4_2 = self.contr_4_2(contr_4_1)
          pool_4 = self.pool_4(contr_4_2)
  
          # pool_4 = self.dropout(pool_4)
  
          encode_1 = self.encode_1(pool_4)
          encode_2 = self.encode_2(encode_1)
          deconv_1 = self.deconv_1(encode_2)
  
          concat1 = torch.cat([deconv_1, contr_4_2], 1)
          expand_1_1 = self.expand_1_1(concat1)
          expand_1_2 = self.expand_1_2(expand_1_1)
          deconv_2 = self.deconv_2(expand_1_2)
  
          concat2 = torch.cat([deconv_2, contr_3_2], 1)
          expand_2_1 = self.expand_2_1(concat2)
          expand_2_2 = self.expand_2_2(expand_2_1)
          deconv_3 = self.deconv_3(expand_2_2)
  
          output_2 = self.output_2(concat2)
          output_2_up = self.output_2_up(output_2)
  
          concat3 = torch.cat([deconv_3, contr_2_2], 1)
          expand_3_1 = self.expand_3_1(concat3)
          expand_3_2 = self.expand_3_2(expand_3_1)
          deconv_4 = self.deconv_4(expand_3_2)
  
          output_3 = output_2_up + self.output_3(concat3)
          output_3_up = self.output_3_up(output_3)
  
          concat4 = torch.cat([deconv_4, contr_1_2], 1)
          expand_4_1 = self.expand_4_1(concat4)
          expand_4_2 = self.expand_4_2(expand_4_1)
  
          conv_5 = self.conv_5(expand_4_2)
  
          final = output_3_up + conv_5
  
          # return conv_51
          # return final
          return final, F.sigmoid(final)
apis: torch.nn.MaxPool2d torch.nn.functional.sigmoid torch.nn.Upsample torch.nn.Conv2d torch.cat torch.nn.Dropout