offline_eval_map_corloc.py

    <div id="post_detail">
<div class="post">
	<h2>
		<a id="cb_post_title_url" href="https://www.cnblogs.com/caffeaoto/p/8758962.html">用Tensorflow做蝴蝶检测</a>
	</h2>
	<div class="postbody">
	<div id="cnblogs_post_body" class="blogpost-body"><p>报名了一个蝴蝶检测比赛,一共给了700多张图,包含94种蝴蝶类别,要求检测出图片中的蝴蝶并正确分类。</p>

1.

https://www.cnblogs.com/caffeaoto/p/8758962.html
拿到数据集后,第一部就是将700多张图分成了 483张训练样本和238张测试样本(由于数据集中,有15种类别的蝴蝶只有一张,所以在测试样本中,仅包含了79种蝴蝶类别)

2.利用一个现有的包含蝴蝶类别的模型直接对测试集中的蝴蝶进行检测(相当于二分类),这里选用的是“ faster_rcnn_inception_resnet_v2_atrous_oid_2018_01_28 ”模型。该模型是在Open Image 数据集上训练的,总共有545个不同物体类别。

先是看的 object_detection/object_detection_tutorial.ipynb 这里直接导入的是frozen model,导致无法修改阈值,所以师兄换了一种模型导入方式,可以把检测的阈值调低,以提高检测到的蝴蝶数目

然后我需要做的是对检测的结果进行评估(计算Percison),但是走了点弯路。

tensorflow教程中的流程是,先把测试集转成TFrecord格式,然后再inference之后,直接在后面加入检测到的结果。但是在模型的输入处出现的问题,因为原本Frozen Model的输入是一个tensor,而师兄修改后的模型输入直接就是 image,所以我不知道怎么将输入进行转换。这里还需要后续的学习。于是我就换了一个方向,以师兄的code为基础,每次从文件夹中提出一张image,进行inference,然后我就根据image信息,解析其对应的xml文件中的信息,并写成tf_example的格式;同时将模型的输出dets添加到刚刚生成的example中。这样就解决了之前的问题,顺利把 annotation+detection结果保存成了 TFrecord格式。

下一步就是利用 object_detection/metrics/offline_eval_map_corloc.py 进行评估,但是出现了两个问题,导致我一度陷入僵局。第一个就是出现了  " ground_truth_group_of .size  :None type has no attrbute to size ",我以为是我的TFrecord出现了问题,但是最后发现是因为 

decoded_dict = data_parser.parse(example)

这里解析的时候,由于我原本TFrecord中并没有写入  standard_fields.TfExampleFields.object_group_of.object_group_of 信息,所以在解析的时候,这个内容就被填上了None ,所以不存在size,导致上面的问题产生。

self.optional_items_to_handlers = {
        fields.InputDataFields.groundtruth_difficult:
            Int64Parser(fields.TfExampleFields.object_difficult),
        fields.InputDataFields.groundtruth_group_of:
            Int64Parser(fields.TfExampleFields.object_group_of)

 查下 open image 中的特有的group_of参数是什么意思: Indicates that the box spans a group of objects (e.g., a bed of flowers or a crowd of people). We asked annotators to use this tag for cases with more than 5 instances which are heavily occluding each other and are physically touching.

 也就是说,带有group_of标记的说明,该框中包含了5个以上的物体,如拥挤的人群,一个铺满鲜花的床等等。

还有一个问题就是,我的GroundTruth中只有蝴蝶和背景两类,但是原本模型的label_map中却包含545类,所以其余的类别是没有GT的,这样在程序中有一个判断:

复制代码
# object_detection/utils/object_detection_evaluation.py
 if (self.num_gt_instances_per_class == 0).any():
      logging.warn(
          'The following classes have no ground truth examples: %s',
          np.squeeze(np.argwhere(self.num_gt_instances_per_class == 0)) +
          self.label_id_offset)
复制代码

我后来找到后,直接将其注释掉,最终跑通了。

该模型在蝴蝶单类的检测Precision=0.728



以下主要解释下评估的代码,防止以后忘记。假设模型输出validation_detections.tfrecord已保存在

models/research/butterfly路径下

第一步是生成配置文件:

复制代码
# From models/research/butterfly
SPLIT=validation  # or test

mkdir -p ${SPLIT}_eval_metrics

echo "
label_map_path: …/object_detection/data/oid_bbox_trainable_label_map.pbtxt
tf_record_input_reader: { input_path:
${SPLIT}_detections.tfrecord }
" > S P L I T e v a l m e t r i c s / {SPLIT}_eval_metrics/ {SPLIT}_input_config.pbtxt

echo "
metrics_set: open_images_detection_metrics
" > S P L I T e v a l m e t r i c s / {SPLIT}_eval_metrics/ {SPLIT}_eval_config.pbtxt

复制代码

然后运行评估程序:

复制代码
# From tensorflow/models/research/butterfly
SPLIT=validation  # or test

PYTHONPATH= P Y T H O N P A T H : PYTHONPATH: (readlink -f …)
python
-m object_detection/metrics/offline_eval_map_corloc
–eval_dir=KaTeX parse error: Expected 'EOF', got '\ ' at position 22: …}_eval_metrics \̲ ̲     #结果保存的路径 …{SPLIT}_eval_metrics/KaTeX parse error: Expected 'EOF', got '\ ' at position 27: …l_config.pbtxt \̲ ̲  </span>--in…{SPLIT}_eval_metrics/${SPLIT}_input_config.pbtxt  #输入的路径

复制代码

首先来看下主程序  models/research/object_detection/metrics/offline_eval_map_corloc.py

复制代码

  import csv
  import os
  import re
  import tensorflow as tf

 
  

  from object_detection import evaluator
  from object_detection.core import standard_fields
  from object_detection.metrics import tf_example_parser
  from object_detection.utils import config_util
  from object_detection.utils import label_map_util

...
def read_data_and_evaluate(input_config, eval_config):

def write_metrics(metrics, output_dir):
...
def
main(argv): del argv required_flags = ['input_config_path', 'eval_config_path', 'eval_dir'] #对应输入的三个参数 for flag_name in required_flags: if not getattr(FLAGS, flag_name): raise ValueError('Flag --{} is required'.format(flag_name))

configs = config_util.get_configs_from_multiple_files(
eval_input_config_path
=FLAGS.input_config_path,
eval_config_path
=FLAGS.eval_config_path)

eval_config = configs[eval_config]
input_config
= configs[eval_input_config]

metrics = read_data_and_evaluate(input_config, eval_config)    #主要实现部分在这里

# Save metrics
write_metrics(metrics, FLAGS.eval_dir)

复制代码

具体来看下

  read_data_and_evaluate(input_config, eval_config):

复制代码
def read_data_and_evaluate(input_config, eval_config):
  """Reads pre-computed object detections and groundtruth from tf_record.

Args:
input_config: input config proto of type  输入配置文件
object_detection.protos.InputReader.
eval_config: evaluation config proto of type 评估配置文件
object_detection.protos.EvalConfig.

Returns:
Evaluated detections metrics.  返回:评估结果

Raises:
ValueError: if input_reader type is not supported or metric type is unknown.
“”"
if input_config.WhichOneof(input_reader) == tf_record_input_reader:
input_paths
= input_config.tf_record_input_reader.input_path

label_map </span>=<span style="color: #000000;"> label_map_util.load_labelmap(input_config.label_map_path)#载入label_map
max_num_classes </span>= max([item.id <span style="color: #0000ff;">for</span> item <span style="color: #0000ff;">in</span><span style="color: #000000;"> label_map.item])      #获得最大的类别对应id (545)
categories </span>=<span style="color: #000000;"> label_map_util.convert_label_map_to_categories(
    label_map, max_num_classes)                       #list类型,eg. categories[110]={'id':111,'name':'Butterfly'}

object_detection_evaluators </span>=<span style="color: #000000;"> evaluator.get_evaluators(
    eval_config, categories)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> Support a single evaluator</span>
object_detection_evaluator =<span style="color: #000000;"> object_detection_evaluators[0]      #对应object_detection_evaluation.OpenImagesDetectionEvaluator

skipped_images </span>=<span style="color: #000000;"> 0
processed_images </span>=<span style="color: #000000;"> 0
</span><span style="color: #0000ff;">for</span> input_path <span style="color: #0000ff;">in</span><span style="color: #000000;"> _generate_filenames(input_paths):
  tf.logging.info(</span><span style="color: #800000;">'</span><span style="color: #800000;">Processing file: {0}</span><span style="color: #800000;">'</span><span style="color: #000000;">.format(input_path))

  record_iterator </span>= tf.python_io.tf_record_iterator(path=<span style="color: #000000;">input_path)  #读取 validation_detection.tfrecord
  data_parser </span>=<span style="color: #000000;"> tf_example_parser.TfExampleDetectionAndGTParser()

  </span><span style="color: #0000ff;">for</span> string_record <span style="color: #0000ff;">in</span><span style="color: #000000;"> record_iterator:                   #迭代器,一共238个测试样本,每次读取一个样本检测结果
    tf.logging.log_every_n(tf.logging.INFO, </span><span style="color: #800000;">'</span><span style="color: #800000;">Processed %d images...</span><span style="color: #800000;">'</span>, 1000<span style="color: #000000;">,
                           processed_images)
    processed_images </span>+= 1<span style="color: #000000;">

    example </span>=<span style="color: #000000;"> tf.train.Example()
    example.ParseFromString(string_record)                #解析TFrecord--&gt; example.features.feature 中以字典形式存放数据
    decoded_dict </span>=<span style="color: #000000;"> data_parser.parse(example)              #对TFrecord进一步解析,还原:groundtruth_boxes、groundtruth_classes、detection_boxes、detection_classes、detection_scores<br>                                          <br>

    </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> decoded_dict:<br>     <strong>#对应 object_detection/utils/object_detection_evaluation.py 中的 class OpenImagesDetectionEvaluator(),默认iou_threshold=0.5</strong>
      object_detection_evaluator.add_single_ground_truth_image_info( 
          decoded_dict[standard_fields.DetectionResultFields.key],
          decoded_dict)
      object_detection_evaluator.add_single_detected_image_info(
          decoded_dict[standard_fields.DetectionResultFields.key],
          decoded_dict)
    </span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
      skipped_images </span>+= 1<span style="color: #000000;">
      tf.logging.info(</span><span style="color: #800000;">'</span><span style="color: #800000;">Skipped images: {0}</span><span style="color: #800000;">'</span><span style="color: #000000;">.format(skipped_images))

</span><span style="color: #0000ff;">return</span><em><strong><span style="color: #000000;"> object_detection_evaluator.evaluate()

raise ValueError(Unsupported input_reader_config.)

复制代码

可以看出,主要的评测过程又放在了 

  object_detection/utils/object_detection_evaluation.py

第一个是 class OpenImagesDetectionEvaluator(ObjectDetectionEvaluator): 继承自  class ObjectDetectionEvaluator(DetectionEvaluator) ,而这个class 又继承自 class DetectionEvaluator(object)

所以我们从上往下看这几个函数,先是基类 DetectionEvaluator(object):Line:42

复制代码
class DetectionEvaluator(object):
  """Interface for object detection evalution classes.

Example usage of the Evaluator:

evaluator = DetectionEvaluator(categories)
                            即挨个添加 GT和detections ,最后一起evaluate()

Detections and groundtruth for image 1.

evaluator.add_single_groundtruth_image_info(…)
evaluator.add_single_detected_image_info(…)

Detections and groundtruth for image 2.

evaluator.add_single_groundtruth_image_info(…)
evaluator.add_single_detected_image_info(…)

metrics_dict = evaluator.evaluate()
“”"
metaclass = ABCMeta

def init(self, categories):
“”"Constructor.

Args:
  categories: A list of dicts, each of which has the following keys -
    'id': (required) an integer id uniquely identifying this category.
    'name': (required) string representing category name e.g., 'cat', 'dog'.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
self._categories </span>=<span style="color: #000000;"> categories

@abstractmethod
def add_single_ground_truth_image_info(self, image_id, groundtruth_dict):
“”"Adds groundtruth for a single image to be used for evaluation.

Args:
  image_id: A unique string/integer identifier for the image.
  groundtruth_dict: A dictionary of groundtruth numpy arrays required
    for evaluations.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">pass</span><span style="color: #000000;">

@abstractmethod
def add_single_detected_image_info(self, image_id, detections_dict):
“”"Adds detections for a single image to be used for evaluation.

Args:
  image_id: A unique string/integer identifier for the image.
  detections_dict: A dictionary of detection numpy arrays required
    for evaluation.
</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">pass</span><span style="color: #000000;">

@abstractmethod
def evaluate(self):
“”“Evaluates detections and returns a dictionary of metrics.”""
pass

@abstractmethod
def clear(self):
“”“Clears the state to prepare for a fresh evaluation.”""
pass

复制代码

然后class ObjectDetectionEvaluator(DetectionEvaluator)  Line:104class ObjectDetectionEvaluator(DetectionEvaluator):

复制代码
"""A class to evaluate detections."""

def init(self,
categories,
matching_iou_threshold
=0.5,
evaluate_corlocs
=False,
metric_prefix
=None,
use_weighted_mean_ap
=False,
evaluate_masks
=False):
“”“Constructor.
Args:
xxxxxx
Raises:
ValueError: If the category ids are not 1-indexed.
“””
  …#这个地方是最关键的,后面会一直用到
self._evaluation
= ObjectDetectionEvaluation(
num_groundtruth_classes
=self._num_classes,
matching_iou_threshold
=self._matching_iou_threshold,
use_weighted_mean_ap
=self._use_weighted_mean_ap,
label_id_offset
=self._label_id_offset)

def add_single_ground_truth_image_info(self, image_id, groundtruth_dict):
“”“Adds groundtruth for a single image to be used for evaluation.
“””
…略
  self._evaluation.add_single_ground_truth_image_info(xxx)
  
 def add_single_detected_image_info(self, image_id, detections_dict):
“”"Adds detections for a single image to be used for evaluation.

</span><span style="color: #800000;">"""</span><span style="color: #000000;">
...<br></span></pre>
  self._evaluation.add_detected_image_info(xxx)
 
 def evaluate(self): """Compute evaluation result. """ ...
  
(per_class_ap, mean_ap, _, _, per_class_corloc, mean_corloc) = (self._evaluation.evaluate())
    ...
def clear(self): """Clears the state to prepare for a fresh evaluation.""" self._evaluation = ObjectDetectionEvaluation( num_groundtruth_classes=self._num_classes, matching_iou_threshold=self._matching_iou_threshold, use_weighted_mean_ap=self._use_weighted_mean_ap, label_id_offset=self._label_id_offset) self._image_ids.clear()
复制代码

最后是OpenImagesDetectionEvaluator(ObjectDetectionEvaluator)    Line:376

复制代码
class OpenImagesDetectionEvaluator(ObjectDetectionEvaluator):
  """A class to evaluate detections using Open Images V2 metrics.
Open Images V2 introduce group_of type of bounding boxes and this metric
handles those boxes appropriately.

“”"

def init(self,
categories,
matching_iou_threshold
=0.5,
evaluate_corlocs
=False):
“”"Constructor.

Args:
  categories: A list of dicts, each of which has the following keys -
    'id': (required) an integer id uniquely identifying this category.
    'name': (required) string representing category name e.g., 'cat', 'dog'.
  matching_iou_threshold: IOU threshold to use for matching groundtruth
    boxes to detection boxes.
  evaluate_corlocs: if True, additionally evaluates and returns CorLoc.
</span><span style="color: #800000;">"""</span><span style="color: #000000;">
super(OpenImagesDetectionEvaluator, self).</span><span style="color: #800080;">__init__</span><span style="color: #000000;">(
    categories,
    matching_iou_threshold,
    evaluate_corlocs,
    metric_prefix</span>=<span style="color: #800000;">'</span><span style="color: #800000;">OpenImagesV2</span><span style="color: #800000;">'</span><span style="color: #000000;">)

def add_single_ground_truth_image_info(self, image_id, groundtruth_dict):
“”"Adds groundtruth for a single image to be used for evaluation.

</span><span style="color: #800000;">"""</span>
<span style="color: #0000ff;">if</span> image_id <span style="color: #0000ff;">in</span><span style="color: #000000;"> self._image_ids:
  </span><span style="color: #0000ff;">raise</span> ValueError(<span style="color: #800000;">'</span><span style="color: #800000;">Image with id {} already added.</span><span style="color: #800000;">'</span><span style="color: #000000;">.format(image_id))

groundtruth_classes </span>=<span style="color: #000000;"> (
    groundtruth_dict[standard_fields.InputDataFields.groundtruth_classes] </span>-<span style="color: #000000;">
    self._label_id_offset)
</span><span style="color: #008000;">#</span><span style="color: #008000;"> If the key is not present in the groundtruth_dict or the array is empty</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> (unless there are no annotations for the groundtruth on this image)</span>
<span style="color: #008000;">#</span><span style="color: #008000;"> use values from the dictionary or insert None otherwise.</span>
<span style="color: #0000ff;">if</span> (standard_fields.InputDataFields.groundtruth_group_of <span style="color: #0000ff;">in</span><span style="color: #000000;">
    groundtruth_dict.keys() </span><span style="color: #0000ff;">and</span><span style="color: #000000;">
    (groundtruth_dict[standard_fields.InputDataFields.groundtruth_group_of]
     .size </span><span style="color: #0000ff;">or</span> <span style="color: #0000ff;">not</span><span style="color: #000000;"> groundtruth_classes.size)):
  groundtruth_group_of </span>=<span style="color: #000000;"> groundtruth_dict[
      standard_fields.InputDataFields.groundtruth_group_of]
</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:
  groundtruth_group_of </span>=<span style="color: #000000;"> None
  </span><span style="color: #0000ff;">if</span> <span style="color: #0000ff;">not</span> len(self._image_ids) % 1000<span style="color: #000000;">:
    logging.warn(
        </span><span style="color: #800000;">'</span><span style="color: #800000;">image %s does not have groundtruth group_of flag specified</span><span style="color: #800000;">'</span><span style="color: #000000;">,
        image_id)
self._evaluation.add_single_ground_truth_image_info(
    image_id,
    groundtruth_dict[standard_fields.InputDataFields.groundtruth_boxes],
    groundtruth_classes,
    groundtruth_is_difficult_list</span>=<span style="color: #000000;">None,
    groundtruth_is_group_of_list</span>=<span style="color: #000000;">groundtruth_group_of)
self._image_ids.update([image_id])<br></span></pre>
复制代码

可以看出,这里只是修改了add_single_ground_truth_image_info 函数,其他都没变。而在其父类中,有把主要的工作交给了 class ObjectDetectionEvaluation(object) 来处理,这下整个代码在逐渐清晰起来。我最后会画个程序包含关系图,可能更容易理解些。

下面整个才是主要的保存 GT 和 Detection 结果的部分哦!!!

复制代码
class ObjectDetectionEvaluation(object):
  """Internal implementation of Pascal object detection metrics."""

def init(self,num_groundtruth_classes,matching_iou_threshold=0.5,nms_iou_threshold=1.0,nms_max_output_boxes=10000,use_weighted_mean_ap=False,label_id_offset=0):
if num_groundtruth_classes < 1:
raise ValueError(Need at least 1 groundtruth class for evaluation.)

<span style="font-size: 15px;"><strong>self.per_image_eval </strong></span></span><span style="font-size: 15px;"><strong>=</strong></span><span style="color: #000000;"><span style="font-size: 15px;"><strong> per_image_evaluation.PerImageEvaluation</strong></span>(
    num_groundtruth_classes</span>=<span style="color: #000000;">num_groundtruth_classes,
    matching_iou_threshold</span>=<span style="color: #000000;">matching_iou_threshold,
    nms_iou_threshold</span>=<span style="color: #000000;">nms_iou_threshold,
    nms_max_output_boxes</span>=<span style="color: #000000;">nms_max_output_boxes)
</span><span style="color: #0000ff;">def</span><span style="color: #000000;"> clear_detections(self):
self._initialize_detections()

def add_single_ground_truth_image_info(self,image_key, groundtruth_boxes, groundtruth_class_labels, groundtruth_is_difficult_list=None, groundtruth_is_group_of_list=None, groundtruth_masks=None):
def add_single_detected_image_info(self, image_key, detected_boxes,detected_scores, detected_class_labels,detected_masks=None):

scores, tp_fp_labels, is_class_correctly_detected_in_image
= (
self.per_image_eval.compute_object_detection_metrics(
detected_boxes
=detected_boxes,
detected_scores
=detected_scores,
detected_class_labels
=detected_class_labels,
groundtruth_boxes
=groundtruth_boxes,
groundtruth_class_labels
=groundtruth_class_labels,
groundtruth_is_difficult_list
=groundtruth_is_difficult_list,
groundtruth_is_group_of_list
=groundtruth_is_group_of_list,
detected_masks
=detected_masks,
groundtruth_masks
=groundtruth_masks))

</span><span style="color: #0000ff;">for</span> i <span style="color: #0000ff;">in</span><span style="color: #000000;"> range(self.num_class):
  </span><span style="color: #0000ff;">if</span> scores[i].shape[0] &gt;<span style="color: #000000;"> 0:
    self.scores_per_class[i].append(scores[i])
    self.tp_fp_labels_per_class[i].append(tp_fp_labels[i])
(self.num_images_correctly_detected_per_class
) </span>+=<span style="color: #000000;"> is_class_correctly_detected_in_image<br><br></span>

def evaluate(self):
“”"Compute evaluation result.

Returns:
  A named tuple with the following fields -
    average_precision: float numpy array of average precision for
        each class.
    mean_ap: mean average precision of all classes, float scalar
    precisions: List of precisions, each precision is a float numpy
        array
    recalls: List of recalls, each recall is a float numpy array
    corloc: numpy float array
    mean_corloc: Mean CorLoc score for each class, float scalar
</span><span style="color: #800000;">"""</span>
scores = np.concatenate(self.scores_per_class[class_index]) tp_fp_labels = np.concatenate(self.tp_fp_labels_per_class[class_index]) precision, recall = metrics.compute_precision_recall( scores, tp_fp_labels, self.num_gt_instances_per_class[class_index]) self.precisions_per_class.append(precision) self.recalls_per_class.append(recall) average_precision = metrics.compute_average_precision(precision, recall) self.average_precision_per_class[class_index] = average_precision
self.corloc_per_class </span>=<span style="color: #000000;"> metrics.compute_cor_loc(
    self.num_gt_imgs_per_class,
    self.num_images_correctly_detected_per_class)<br></span><span style="color: #000000;">
mean_ap </span>=<span style="color: #000000;"> np.nanmean(self.average_precision_per_class)
mean_corloc </span>=<span style="color: #000000;"> np.nanmean(self.corloc_per_class)
</span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ObjectDetectionEvalMetrics(
    self.average_precision_per_class, mean_ap, self.precisions_per_class,
    self.recalls_per_class, self.corloc_per_class, mean_corloc)</span></pre>
复制代码

我把不重要的部分都剃掉了,主要有两个重要的函数 1. object_detection/utils/per_image_evaluatuion.py  计算单张图的precision和recall

                        2. object_detection/utils/metrics.py          统计上述结果,并计算mAP等数值

1. object_detection/utils/per_image_evaluatuion.py  计算单张图的precision和recall

复制代码
scores, tp_fp_labels, is_class_correctly_detected_in_image = compute_object_detection_metrics(...)
-->
      scores, tp_fp_labels = self._compute_tp_fp(...) 
      -->for i in range(self.num_groundtruth_classes):
               scores, tp_fp_labels = self._compute_tp_fp_for_single_class(...)
               -->(iou, ioa, scores,num_detected_boxes) = self._get_overlaps_and_scores_box_mode(...)
                   -->detected_boxlist = np_box_list_ops.non_max_suppression(...)
         -->
复制代码
0
0
« 上一篇: 双系统,重装ubuntu后无法进入windows
» 下一篇: [ERROR] 安装完Detectron后出现 cython_nms.so: undefined symbol: PyFPE_jbuf
	</div>
	<p class="postfoot">
		posted on <span id="post-date">2018-04-10 16:11</span> <a href="https://www.cnblogs.com/caffeaoto/">caffeauto</a> 阅读(<span id="post_view_count">1518</span>) 评论(<span id="post_comment_count">2</span>)  <a href="https://i.cnblogs.com/EditPosts.aspx?postid=8758962" rel="nofollow">编辑</a> <a href="#" "AddToWz(8758962);return false;">收藏</a>
	</p>
</div>
<script type="text/javascript">var allowComments=true,cb_blogId=336677,cb_entryId=8758962,cb_blogApp=currentBlogApp,cb_blogUserGuid='5299712e-ab0b-e611-9fc1-ac853d9f53cc',cb_entryCreatedDate='2018/4/10 16:11:00';loadViewCount(cb_entryId);var cb_postType=1;var isMarkdown=false;</script>

</div><a name="!comments"></a><div id="blog-comments-placeholder"><div id="comments_pager_top"></div>

评论

		<div class="post">
			<h2>
				<a href="#3996063" class="layer">#1楼</a><a name="3996063" id="comment_anchor_3996063"></a>
				&nbsp;&nbsp;<span class="comment_actions"></span>
			</h2>
			<div id="comment_body_3996063" class="blog_comment_body">博主,我想问下,你的那个第一步生成config配置文件的eval_config.pbtxt是填写什么?还请指导下</div><div class="comment_vote"><a href="javascript:void(0);" class="comment_digg" "return voteComment(3996063,'Digg',this)">支持(0)</a><a href="javascript:void(0);" class="comment_bury" "return voteComment(3996063,'Bury',this)">反对(0)</a></div>
			<div class="postfoot">
				 <span class="comment_date">2018-06-11 19:12</span> | <a id="a_comment_author_3996063" href="http://home.cnblogs.com/u/1010645/" target="_blank">Zoe_启</a> <a href="http://msg.cnblogs.com/send/Zoe_%E5%90%AF" title="发送站内短消息" class="sendMsg2This">&nbsp;</a>
			</div>
		</div>
	
		<div class="post">
			<h2>
				<a href="#3996708" class="layer">#2楼</a><a name="3996708" id="comment_anchor_3996708"></a>[<span class="louzhu">楼主</span>]<span id="comment-maxId" style="display:none;">3996708</span><span id="comment-maxDate" style="display:none;">2018/6/12 15:57:56</span>
				&nbsp;&nbsp;<span class="comment_actions"></span>
			</h2>
			<div id="comment_body_3996708" class="blog_comment_body"><a href="#3996063" title="查看所回复的评论" "commentManager.renderComments(0,50,3996063);">@</a>

Zoe_启
metrics_set: 'open_images_detection_metrics

就是上面这个内容啊

http://pic.cnblogs.com/face/945479/20170302164420.png

2018-06-12 15:57 | caffeauto  

猜你喜欢

转载自blog.csdn.net/wc996789331/article/details/89444087
今日推荐