结节分割框架
================================================

网络组成部分
------------------------------------------------
* baseLayers
    * 如:convBlock(包含conv-norm层-activation层)/SE模块/等
    * 参数列表单独定义
        * 需要确定以层的方式定义/以函数的方式定义

* backbones
    * 如:VGG/ResNet/DenseNet等。同时backbone里的网络也可以作为encoder的输入,如Hrnet可以将VGG/ResNet作为输入,再叠加decoder
    * 输入:
        * input_shape:用于定义网络输入大小
        * block数量
        * stride_list
            * 定义网络第i个模块输出与输出入receptive_field比例
        * atrous_list
            * 每个模块的atrous_rate组成的列表
                * 如果是普通串行模块,atrous_rate[idx]是整数,如果是类似于deeplabv3中的并行模块,则atrous_rate[idx]是列表
        * 基本Filters数量:网络第一个conv layer的num_filters数量。如果没有意外情况,每个block的filters是前一个block filters的二倍
        * downsample的方式
            * conv + stride>1
            * maxpooling
            * ...
        * 基本模块相关参数
            * norm_func(convBlock)
            * activation_func
            * kernel_initializer
            * ...
    * 输出
        * 模型
        * 各个模块最后一个tensor形成的列表


* decoders
    * 不同组合方式
        * Unet的decoder:与encoder block数量一致,读取decoder上一个block的输出和encoder对应层级的输出
        * 类似于FCN输出
        * 基本decoder加入其他融合方式
            * ACF:结合coarse segmentation 结果 & feature map生成fine segmentation result
            * OCR: 等

    * 输入
        * encoder的输出:模型+tensor列表
        * 其他参数
            * 输出大小(默认是恢复encoder输入的空间尺寸)
            * 分割的类的数量
            * 基本模块相关参数(同encoder)
            * 是否添加其他模块:每一个模块是否添加以bool变量传入
                * deep_supervision = True 则添加deep_supervision
            * upsample方式
                * conv+upsample/其他upsample函数
                * deconv
                * ....
    * 输出
        * 分割模型






连接
-------------------------------------------------
* build_mode
    * 根据不同模型名,选择对应函数、传进来参数的部分build_model
* Segmentation类--BuildSegModel函数
    * 输入
        * general的config文件,包含
            * 数据路径等训练相关参数
            * encoder/deocder名字
            * 所有模型共享的参数
                *  如kernel_initializer/kernel_size/....
            * 每个模型参数的config文件(需要和general_config/模型共享参数config拼在一起)
        
    * build_model过程
        * 根据config文件产生对应参数
        * encoder_result = build_model(encoder模型名字,输入大小,[encoder模型参数字典])
        * decoder_result = build_model(decoder模型名字,输入大小,[encoder_result,decoder模型参数字典])



如何拆分已有模型
----------------------------------------
* 将网络结构分为encoder、decoder两个部分
    * 将encoder拆分至stage(一般来讲,感受野放大一倍算是一个block)
    * 将decoder拆分至stage
    * 将上述encoder、decoder 模块中共用的模块拆分出来定义到baseLayers中
* encoder
    * 假设有k个重复模块
    * result = [input_tensor] + [last_tensor_of_stage_1,...,last_tensor_of_stage_k]
    * 如果没有output可以一般性的添加GAP/GMP/Dense等得到分类的输出就结果
    * model = Model(input_tensor,设置的output)
    * return:[model,result]
* decoder
    * 读取encoder的模型、以及encoder_tensors
    * input_tensor = encoder_result[0].input
    * tensors = encoder_result[1]
    * 重复decoder的block
        * decoder可以拆分为k个stage
        * 伪代码
            * decoder_list = []
            * x = result[-1]
            * for stage_idx in range(k):
                *  x = ConvUnit(x) #经过convUnit调整channel维度
                *  x = Upsample()(x) #经过upsample调整空间维度
                *  x = Concatenate()([x,result[-(stage_idx+1)]]) #将encoder-decoder的feature结合,利用到encdoer的tensor_list
                * for block_idx in range(2):
                    * x = ConvUnit(x)
                * decoder_list.append(x)
    * 利用decoder_list多个阶段的feature做融合等
    * 输出最终结果



如何添加新的网络结构
----------------------------------------
* 根据类型,将要定义的结构存到对应文件夹下
* baseLayers
    * 直接添加对应的py文件。模块可以携程Layer的形式也可以写成函数的形式
* backbones/decoders
    * 按照输入输出格式要求,定义网络。
    * 在/models/model_utils/文件中import对应的模型定义函数(以保证通过str类型的模型名可以找到对应的模型函数)[<b>待改写</b>]
    * 在/files/Model_parameters.json文件中添加新的模型参数,在/files/model_map.json文件中添加当前模型的dict。格式为
        模型名:{参数1:值1....}


搭建分割模型示例
---------------------------------------------------
* 见搭建segmentation_model示例.ipynb


网络训练示例
--------------------------------------------
* 见../train.ipynb