rishizek / tensorflow-deeplab-v3

DeepLabv3 built in TensorFlow
MIT License
286 stars 102 forks source link

Cannot find multigride architecture #10

Open Balabala-Hong opened 6 years ago

Balabala-Hong commented 6 years ago

Hi,@rishizek: Thanks for your implementation of deeplabV3, but I cannot find the multigride architecture as you mentioned in the Evaluation of README file: "repo | MG(1,2,4)+ASPP(6,12,18)+Image Pooling | 16 | 76.42%".Can you tell me where did you put the code of this multigride architecture? blocks = [ resnet_v2_block('block1', base_depth=64, num_units=3, stride=2), resnet_v2_block('block2', base_depth=128, num_units=4, stride=2), resnet_v2_block('block3', base_depth=256, num_units=23, stride=2), resnet_v2_block('block4', base_depth=512, num_units=3, stride=1), ]

rishizek commented 6 years ago

Hi @FlyingIce1 , thank you for your interest in the repo.

It is complex but the multigrid architecture is implemented in slim library. The key parameter is output_stride, which you can find document explanation here and here. The default output stride of ResNet is 32, as you may know from ResNet and Deeplab papers. When you set output_stride = 16, the slim module automatically sets MG(1,2,4). More concretely, if you set ouput_stirde = 16, after current_stride=16 here, the rate parameter (which is also know as atrous convolution rate parameter) here will be multiplied instead of stride afterword. And this creates MG(1,2,4). The resnet_v2_block() functions you mentioned will eventually return resnet_utils.Block() class here if you read code carefully, so it is OK to overwrite rate parameter later on.

I hope this answers your question.

Balabala-Hong commented 6 years ago

,Thank you for your explanation,I'll check it.

luke-evans-liu commented 6 years ago

But, even so, the atrous rates in the last residual block are (2, 2, 2) according to the slim codes, not (1, 2, 4) as paper mentioned.

a7b23 commented 5 years ago

The atrous rates are (2,2,2) not (2,4,8) as the stride for the last block is 1 and so the rate gets multiplied by 1 only here. @rishizek what are your thoughts?

rishizek commented 5 years ago

Hi all, Thanks for your comments. Indeed, you, guys, are right. Now I'm also thinking that the multigrid is missing. Perhaps that could be reason that the accuracy of this repo is lower than that of paper. Maybe I should fix README.

northeastsquare commented 5 years ago

@luke-evans-liu @a7b23 @rishizek no mater output_stride=16 or 8, the atrous rate is always (1,1,1), reason as follows, so where am I wrong? because https://github.com/tensorflow/tensorflow/blob/r1.8/tensorflow/contrib/slim/python/slim/nets/resnet_v2.py#L208 output_stride=output_stride/4, everytime https://github.com/tensorflow/tensorflow/blob/r1.8/tensorflow/contrib/slim/python/slim/nets/resnet_utils.py#L216 current_stride *= unit.get('stride', 1), current_stride=1 alwalys since unit.get('stride', 1) =1, and output_stride=4 or 2 (as output_stride/4, as upper) since https://github.com/tensorflow/tensorflow/blob/r1.8/tensorflow/contrib/slim/python/slim/nets/resnet_v2.py#L276 bock4 stride=1. this line https://github.com/tensorflow/tensorflow/blob/23c218785eac5bfe737eec4f8081fd0ef8e0684d/tensorflow/contrib/slim/python/slim/nets/resnet_utils.py#L211 will never be executed.

so can I change the code mannually, https://github.com/tensorflow/tensorflow/blob/23c218785eac5bfe737eec4f8081fd0ef8e0684d/tensorflow/contrib/slim/python/slim/nets/resnet_utils.py#L210 to make rate=[1,2,4] ? that is to say, change the code as following: ` for ib, block in enumerate(blocks): with variable_scope.variable_scope(block.scope, 'block', [net]) as sc: for i, unit in enumerate(block.args): if output_stride is not None and current_stride > output_stride: raise ValueError('The target output_stride cannot be reached.')

    with variable_scope.variable_scope('unit_%d' % (i + 1), values=[net]):
      # If we have reached the target output_stride, then we need to employ
      # atrous convolution with stride=1 and multiply the atrous rate by the
      # current unit's stride for use in subsequent layers.
      print('ib:', ib) 
      if ib == 3:
        rate = pow(2, i)
        print("rate:", rate)
        net = block.unit_fn(net, rate=rate, **dict(unit, stride=1))
      elif output_stride is not None and current_stride == output_stride:
        net = block.unit_fn(net, rate=rate, **dict(unit, stride=1))
        rate *= unit.get('stride', 1)

      else:
        net = block.unit_fn(net, rate=1, **unit)
        current_stride *= unit.get('stride', 1)
  net = utils.collect_named_outputs(outputs_collections, sc.name, net)

`