weiliu89 / caffe

Caffe: a fast open framework for deep learning.
http://caffe.berkeleyvision.org/
Other
4.77k stars 1.67k forks source link

where to change the code to try different nms threshold for detection #883

Open anandkoirala opened 6 years ago

anandkoirala commented 6 years ago

Please use the caffe-users list for usage, installation, or modeling questions, or other requests for help. Do not post such requests to Issues. Doing so interferes with the development of Caffe.

Please read the guidelines for contributing before submitting this issue.

Issue summary

@weiliu89 HI all can someone tell me which file i modify to get detections for my choice of nms... ssd_detect.py have no nms argument to be passed...

Steps to reproduce

If you are having difficulty building Caffe or training a model, please ask the caffe-users mailing list. If you are reporting a build error that seems to be due to a bug in Caffe, please attach your build configuration (either Makefile.config or CMakeCache.txt) and the output of the make (or cmake) command.

Your system configuration

Operating system: Compiler: CUDA version (if applicable): CUDNN version (if applicable): BLAS: Python or MATLAB version (for pycaffe and matcaffe respectively):

fraukej commented 6 years ago

@anandkoirala There are two ways you can change the nms threshold:

  1. During training
  2. During testing

For 1., change the nms_param in your ssd_<dataset>.py file. See here for ilsvrc, here for pascal and here for coco dataset.

For 2., you can change the parameter conf_thresh in ssd_detect.py in this line (e.g. change it to

result = detection.detect(args.image_file, conf_thresh=0.8)

) to change the confidence threshold to 0.8 (= 80%). It is 0.5 (= 50%) by default.

If you want to, you can add it as an argument in the argument parser.

anandkoirala commented 6 years ago

@fraukej thanks for the reply but the conf_threshold is different to nms_threshold.. i want it during testing... because the score_ssd_pascal.py is producing the detections of the background not my objects so i used ssd_detect.py to save the detections of my objects as a detection file.. the problem now is i want to change the detection time nms thershold.. (the score_ssd_pascal.py can do it passed as argument but i cannot use this script for above reasons..... therefore i want to do it from ssd_detect.py but i don't know how).. can u please help me.. Regards, Anand

GloriaLovera commented 6 years ago

ssd_detect.py does not define the net programatically (i.e. building it layer by layer as in https://github.com/weiliu89/caffe/blob/ssd/examples/ssd/ssd_pascal.py) but it uses a prototxt file passed as main argument(line 139-140):

_models/VGGNet/VOC0712/SSD300x300/deploy.prototxt

Latest layer of this prototxt is the DetectionOutput layer where the nms threshold parameter can be changed:

layer {
  name: "detection_out"
  type: "DetectionOutput"
  bottom: "mbox_loc"
  bottom: "mbox_conf_flatten"
  bottom: "mbox_priorbox"
  top: "detection_out"
  include {
    phase: TEST
  }
  detection_output_param {
    num_classes: 21
    share_location: true
    background_label_id: 0
    nms_param {
      nms_threshold: 0.45
      top_k: 100
    }
    code_type: CENTER_SIZE
    keep_top_k: 100
    confidence_threshold: 0.25
  }
}
anandkoirala commented 6 years ago

@GloriaLovera Thank you very much.. now it is working with the changes to nms in the deploy.prototxt btw.. do u have any idea why the score_ssd file was detecting only background but the ssd_detect is detecting my objects... although all the file locations and labelmap file are the same.. the model was trained on a single class object.. with thanks, Anand

GloriaLovera commented 6 years ago

@anandkoirala If ssd_detect.py works as expected it means that prototxt and label map files are correct. Did you properly change the num_classes and background_id values in score_ssd script? (lines 277 and 279)

num_classes = 21
share_location = True
background_label_id=0

:-) Gloria

anandkoirala commented 6 years ago

@GloriaLovera yes everything is right.... but did't work.. with score_ssd

fraukej commented 5 years ago

@GloriaLovera @anandkoirala Is there any way to change the nms at runtime using pycaffe?

The only way I found is reading the netParams, changing the nms, writing the net params file again and then loading the model using this file, which is very ugly:

# Reading the net parameters
net_param = caffe_pb2.NetParameter()
prototxt_file_name = graph_directory + model_def

with open(prototxt_file_name, 'r') as f:
buffer = f.read()
txtf.Merge(buffer, net_param)

# changing the nms threshold
net_param.layer[-1].detection_output_param.nms_param.nms_threshold = self.nms_thresh

# saving the net parameters again ...
with open(prototxt_file_name, 'w') as f:
    print(str(net_param), file=f)

# ... so that we can open a file here ...
self.net = self.caffe.Net(graph_directory + model_def, 1,
                          weights=graph_directory + weights_file)

In C++, there is a Net constructor which uses loaded NetParameters to construct a new net. This is what I want to use. However, it is not exposed to the Python interface (see here). Do you have any idea what I have to do for it to work properly?