def unet(inputI, output_channel):
    '3D U-net'
    phase_flag = 1
    concat_dim = 4
    conv1_1 = conv3d(input=inputI, output_chn=64, kernel_size=3, stride=1, use_bias=False, name='conv1')
    conv1_bn = tf.contrib.layers.batch_norm(conv1_1, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv1_batch_norm')
    conv1_relu = tf.nn.relu(conv1_bn, name='conv1_relu')
    pool1_in = tf.layers.max_pooling3d(inputs=conv1_relu, pool_size=2, strides=2, name='pool1')
    pool1 = pool1_in
    conv2_1 = conv3d(input=pool1, output_chn=128, kernel_size=3, stride=1, use_bias=False, name='conv2')
    conv2_bn = tf.contrib.layers.batch_norm(conv2_1, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv2_batch_norm')
    conv2_relu = tf.nn.relu(conv2_bn, name='conv2_relu')
    pool2_in = tf.layers.max_pooling3d(inputs=conv2_relu, pool_size=2, strides=2, name='pool2')
    pool2 = pool2_in
    conv3_1 = conv3d(input=pool2, output_chn=256, kernel_size=3, stride=1, use_bias=False, name='conv3a')
    conv3_1_bn = tf.contrib.layers.batch_norm(conv3_1, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv3_1_batch_norm')
    conv3_1_relu = tf.nn.relu(conv3_1_bn, name='conv3_1_relu')
    conv3_2 = conv3d(input=conv3_1_relu, output_chn=256, kernel_size=3, stride=1, use_bias=False, name='conv3b')
    conv3_2 = (conv3_2 + conv3_1)
    conv3_2_bn = tf.contrib.layers.batch_norm(conv3_2, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv3_2_batch_norm')
    conv3_2_relu = tf.nn.relu(conv3_2_bn, name='conv3_2_relu')
    pool3_in = tf.layers.max_pooling3d(inputs=conv3_2_relu, pool_size=2, strides=2, name='pool3')
    pool3 = pool3_in
    conv4_1 = conv3d(input=pool3, output_chn=512, kernel_size=3, stride=1, use_bias=False, name='conv4a')
    conv4_1_bn = tf.contrib.layers.batch_norm(conv4_1, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv4_1_batch_norm')
    conv4_1_relu = tf.nn.relu(conv4_1_bn, name='conv4_1_relu')
    conv4_2 = conv3d(input=conv4_1_relu, output_chn=512, kernel_size=3, stride=1, use_bias=False, name='conv4b')
    conv4_2 = (conv4_2 + conv4_1)
    conv4_2_bn = tf.contrib.layers.batch_norm(conv4_2, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv4_2_batch_norm')
    conv4_2_relu = tf.nn.relu(conv4_2_bn, name='conv4_2_relu')
    pool4 = tf.layers.max_pooling3d(inputs=conv4_2_relu, pool_size=2, strides=2, name='pool4')
    conv5_1 = conv_bn_relu(input=pool4, output_chn=512, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='conv5_1')
    conv5_2 = conv_bn_relu(input=conv5_1, output_chn=512, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='conv5_2')
    deconv1_1 = deconv_bn_relu(input=conv5_2, output_chn=512, is_training=phase_flag, name='deconv1_1')
    concat_1 = tf.concat([deconv1_1, conv4_2], axis=concat_dim, name='concat_1')
    deconv1_2_in = conv_bn_relu(input=concat_1, output_chn=256, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='deconv1_2')
    deconv1_2 = deconv1_2_in
    deconv2_1 = deconv_bn_relu(input=deconv1_2, output_chn=256, is_training=phase_flag, name='deconv2_1')
    concat_2 = tf.concat([deconv2_1, conv3_2], axis=concat_dim, name='concat_2')
    deconv2_2_in = conv_bn_relu(input=concat_2, output_chn=128, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='deconv2_2')
    deconv2_2 = deconv2_2_in
    deconv3_1 = deconv_bn_relu(input=deconv2_2, output_chn=128, is_training=phase_flag, name='deconv3_1')
    concat_3 = tf.concat([deconv3_1, conv2_1], axis=concat_dim, name='concat_3')
    deconv3_2_in = conv_bn_relu(input=concat_3, output_chn=64, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='deconv3_2')
    deconv3_2 = deconv3_2_in
    deconv4_1 = deconv_bn_relu(input=deconv3_2, output_chn=64, is_training=phase_flag, name='deconv4_1')
    concat_4 = tf.concat([deconv4_1, conv1_1], axis=concat_dim, name='concat_4')
    deconv4_2 = conv_bn_relu(input=concat_4, output_chn=32, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='deconv4_2')
    pre_pro = conv3d(input=deconv4_2, output_chn=output_channel, kernel_size=1, stride=1, use_bias=True, name='pre_pro')
    pred_prob = pre_pro
    aux0_conv = conv3d(input=deconv1_2, output_chn=output_channel, kernel_size=1, stride=1, use_bias=True, name='aux0_conv')
    aux0_deconv_1 = Deconv3d(input=aux0_conv, output_chn=output_channel, name='aux0_deconv_1')
    aux0_deconv_2 = Deconv3d(input=aux0_deconv_1, output_chn=output_channel, name='aux0_deconv_2')
    aux0_prob = Deconv3d(input=aux0_deconv_2, output_chn=output_channel, name='aux0_prob')
    aux1_conv = conv3d(input=deconv2_2, output_chn=output_channel, kernel_size=1, stride=1, use_bias=True, name='aux1_conv')
    aux1_deconv_1 = Deconv3d(input=aux1_conv, output_chn=output_channel, name='aux1_deconv_1')
    aux1_prob = Deconv3d(input=aux1_deconv_1, output_chn=output_channel, name='aux1_prob')
    aux2_conv = conv3d(input=deconv3_2, output_chn=output_channel, kernel_size=1, stride=1, use_bias=True, name='aux2_conv')
    aux2_prob = Deconv3d(input=aux2_conv, output_chn=output_channel, name='aux2_prob')
    soft_prob = tf.nn.softmax(pred_prob, name='pred_soft')
    pred_label = tf.argmax(soft_prob, axis=4, name='argmax')
    return (pred_prob, pred_label, aux0_prob, aux1_prob, aux2_prob)
3D U-net
def unet(inputI, output_channel):
    
    phase_flag = 1
    concat_dim = 4
    conv1_1 = conv3d(input=inputI, output_chn=64, kernel_size=3, stride=1, use_bias=False, name='conv1')
    conv1_bn = tf.contrib.layers.batch_norm(conv1_1, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv1_batch_norm')
    conv1_relu = tf.nn.relu(conv1_bn, name='conv1_relu')
    pool1_in = tf.layers.max_pooling3d(inputs=conv1_relu, pool_size=2, strides=2, name='pool1')
    pool1 = pool1_in
    conv2_1 = conv3d(input=pool1, output_chn=128, kernel_size=3, stride=1, use_bias=False, name='conv2')
    conv2_bn = tf.contrib.layers.batch_norm(conv2_1, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv2_batch_norm')
    conv2_relu = tf.nn.relu(conv2_bn, name='conv2_relu')
    pool2_in = tf.layers.max_pooling3d(inputs=conv2_relu, pool_size=2, strides=2, name='pool2')
    pool2 = pool2_in
    conv3_1 = conv3d(input=pool2, output_chn=256, kernel_size=3, stride=1, use_bias=False, name='conv3a')
    conv3_1_bn = tf.contrib.layers.batch_norm(conv3_1, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv3_1_batch_norm')
    conv3_1_relu = tf.nn.relu(conv3_1_bn, name='conv3_1_relu')
    conv3_2 = conv3d(input=conv3_1_relu, output_chn=256, kernel_size=3, stride=1, use_bias=False, name='conv3b')
    conv3_2 = (conv3_2 + conv3_1)
    conv3_2_bn = tf.contrib.layers.batch_norm(conv3_2, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv3_2_batch_norm')
    conv3_2_relu = tf.nn.relu(conv3_2_bn, name='conv3_2_relu')
    pool3_in = tf.layers.max_pooling3d(inputs=conv3_2_relu, pool_size=2, strides=2, name='pool3')
    pool3 = pool3_in
    conv4_1 = conv3d(input=pool3, output_chn=512, kernel_size=3, stride=1, use_bias=False, name='conv4a')
    conv4_1_bn = tf.contrib.layers.batch_norm(conv4_1, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv4_1_batch_norm')
    conv4_1_relu = tf.nn.relu(conv4_1_bn, name='conv4_1_relu')
    conv4_2 = conv3d(input=conv4_1_relu, output_chn=512, kernel_size=3, stride=1, use_bias=False, name='conv4b')
    conv4_2 = (conv4_2 + conv4_1)
    conv4_2_bn = tf.contrib.layers.batch_norm(conv4_2, decay=0.9, updates_collections=None, epsilon=1e-05, scale=True, is_training=phase_flag, scope='conv4_2_batch_norm')
    conv4_2_relu = tf.nn.relu(conv4_2_bn, name='conv4_2_relu')
    pool4 = tf.layers.max_pooling3d(inputs=conv4_2_relu, pool_size=2, strides=2, name='pool4')
    conv5_1 = conv_bn_relu(input=pool4, output_chn=512, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='conv5_1')
    conv5_2 = conv_bn_relu(input=conv5_1, output_chn=512, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='conv5_2')
    deconv1_1 = deconv_bn_relu(input=conv5_2, output_chn=512, is_training=phase_flag, name='deconv1_1')
    concat_1 = tf.concat([deconv1_1, conv4_2], axis=concat_dim, name='concat_1')
    deconv1_2_in = conv_bn_relu(input=concat_1, output_chn=256, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='deconv1_2')
    deconv1_2 = deconv1_2_in
    deconv2_1 = deconv_bn_relu(input=deconv1_2, output_chn=256, is_training=phase_flag, name='deconv2_1')
    concat_2 = tf.concat([deconv2_1, conv3_2], axis=concat_dim, name='concat_2')
    deconv2_2_in = conv_bn_relu(input=concat_2, output_chn=128, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='deconv2_2')
    deconv2_2 = deconv2_2_in
    deconv3_1 = deconv_bn_relu(input=deconv2_2, output_chn=128, is_training=phase_flag, name='deconv3_1')
    concat_3 = tf.concat([deconv3_1, conv2_1], axis=concat_dim, name='concat_3')
    deconv3_2_in = conv_bn_relu(input=concat_3, output_chn=64, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='deconv3_2')
    deconv3_2 = deconv3_2_in
    deconv4_1 = deconv_bn_relu(input=deconv3_2, output_chn=64, is_training=phase_flag, name='deconv4_1')
    concat_4 = tf.concat([deconv4_1, conv1_1], axis=concat_dim, name='concat_4')
    deconv4_2 = conv_bn_relu(input=concat_4, output_chn=32, kernel_size=3, stride=1, use_bias=False, is_training=phase_flag, name='deconv4_2')
    pre_pro = conv3d(input=deconv4_2, output_chn=output_channel, kernel_size=1, stride=1, use_bias=True, name='pre_pro')
    pred_prob = pre_pro
    aux0_conv = conv3d(input=deconv1_2, output_chn=output_channel, kernel_size=1, stride=1, use_bias=True, name='aux0_conv')
    aux0_deconv_1 = Deconv3d(input=aux0_conv, output_chn=output_channel, name='aux0_deconv_1')
    aux0_deconv_2 = Deconv3d(input=aux0_deconv_1, output_chn=output_channel, name='aux0_deconv_2')
    aux0_prob = Deconv3d(input=aux0_deconv_2, output_chn=output_channel, name='aux0_prob')
    aux1_conv = conv3d(input=deconv2_2, output_chn=output_channel, kernel_size=1, stride=1, use_bias=True, name='aux1_conv')
    aux1_deconv_1 = Deconv3d(input=aux1_conv, output_chn=output_channel, name='aux1_deconv_1')
    aux1_prob = Deconv3d(input=aux1_deconv_1, output_chn=output_channel, name='aux1_prob')
    aux2_conv = conv3d(input=deconv3_2, output_chn=output_channel, kernel_size=1, stride=1, use_bias=True, name='aux2_conv')
    aux2_prob = Deconv3d(input=aux2_conv, output_chn=output_channel, name='aux2_prob')
    soft_prob = tf.nn.softmax(pred_prob, name='pred_soft')
    pred_label = tf.argmax(soft_prob, axis=4, name='argmax')
    return (pred_prob, pred_label, aux0_prob, aux1_prob, aux2_prob)