将结果写回ymir平台#

2023/03/01 更新

写进度#

write the execution progress percentage of the task to monitor file.

Parameters:

Name Type Description Default
percent float

the execution progress percentage of the task, range in [0, 1]

required
Source code in ymir_exc/monitor.py
18
19
20
21
22
23
24
25
26
27
28
29
30
def write_monitor_logger(percent: float,
                         state: ExecutorState = ExecutorState.ES_RUNNING,
                         return_code: ExecutorReturnCode = ExecutorReturnCode.RC_EXEC_NO_ERROR) -> None:
    """write the execution progress percentage of the task to monitor file.

    Parameters
    ----------
    percent : float
         the execution progress percentage of the task, range in [0, 1]
    """
    env_config = env.get_current_env()
    with open(env_config.output.monitor_file, 'w') as f:
        f.write(f"{env_config.task_id}\t{time.time()}\t{percent:.2f}\t{state}\t{int(return_code)}\n")

将任务进度百分比 percent 写到监控文件 cfg.ymir.output.monitor_file (/out/monitor.txt) 中

from ymir_exc import monitor

monitor.write_monitor_logger(percent)

保存训练日志(tensorboard)#

需要将tensorboard 日志文件保存到指定目录 cfg.ymir.output.tensorboard_dir (/out/tensorboard) 中

保存训练结果#

write training result to training result file

if exist result in training result file, new result will append to file

Source code in ymir_exc/result_writer.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
@versionadded(
    version="2.1.0",
    reason="support segmentation metrics and custom metrics",
)
def write_training_result(stage_name: str,
                          files: List[str],
                          evaluation_result: Dict[str, Union[float, int]] = {},
                          timestamp: Optional[int] = None,
                          attachments: Optional[Dict[str, List[str]]] = None,
                          evaluate_config: Optional[dict] = None) -> None:
    """write training result to training result file

    if exist result in training result file, new result will append to file
    """
    write_model_stage(stage_name=stage_name,
                      files=files,
                      evaluation_result=evaluation_result,
                      timestamp=timestamp,
                      attachments=attachments,
                      evaluate_config=evaluate_config)

将验证集评测指标及相关文件保存到结果文件 cfg.ymir.output.training_result_file (/out/models/result.yaml) 中

from ymir_exc import result_writer

## 目标检测结果
result_writer.write_training_result(stage_name='best', files=['best.pt', 'best.onnx', 'config.yaml'], evaluation_result=dict(mAP=0.8))

## 语义分割结果
result_writer.write_training_result(stage_name='best', files=['best.pt', 'best.onnx', 'config.yaml'], evaluation_result=dict(mIoU=0.8))

## 实例分割结果
result_writer.write_training_result(stage_name='best', files=['best.pt', 'best.onnx', 'config.yaml'], evaluation_result=dict(maskAP=0.8))

保存多组训练结果#

from ymir_exc import result_writer

result_writer.write_training_result(stage_name='epoch_10', files=['epoch_10.pt', 'config.yaml'], evaluation_result=dict(mAP=0.82))

result_writer.write_training_result(stage_name='epoch_20', files=['epoch_20.pt', 'config.yaml'], evaluation_result=dict(mAP=0.84))

写挖掘结果#

write mining result to mining_result_file

Parameters:

Name Type Description Default
mining_result List[Tuple[str, float]]
  • image_path: str
  • score: float
required
Source code in ymir_exc/result_writer.py
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
def write_mining_result(mining_result: List[Tuple[str, float]]) -> None:
    """write mining result to mining_result_file

    Parameters
    ----------
    mining_result : List[Tuple[str, float]]
        - image_path: str
        - score: float
    """
    # sort desc by score
    sorted_mining_result = sorted(mining_result, reverse=True, key=(lambda v: v[1]))

    env_config = env.get_current_env()
    with open(env_config.output.mining_result_file, "w") as f:
        for img_path, score in sorted_mining_result:
            f.write(f"{img_path}\t{score}\n")

将图像路径与对应分数写到结果文件 cfg.ymir.output.mining_result_file (/out/result.tsv) 中

from ymir_exc import result_writer

result_writer.write_mining_result(mining_result=[(img_path1, 0.8), (img_path2, 0.6)])

写推理结果#

supported_algorithms = ['classification', 'detection', 'segmentation'] for detection infer result, use ymir format for segmentation infer result, write coco-format to infer_result_file directly

Source code in ymir_exc/result_writer.py
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
@versionchanged(
    version="2.0.0",
    reason="support detection and segmentation infer result",
)
def write_infer_result(infer_result: Union[Dict, Dict[str, List[Annotation]]],
                       algorithm: Optional[str] = 'detection') -> None:
    """
    supported_algorithms = ['classification', 'detection', 'segmentation']
    for detection infer result, use ymir format
    for segmentation infer result, write coco-format to infer_result_file directly
    """
    env_config = env.get_current_env()
    supported_algorithms = ['classification', 'detection', 'segmentation']
    assert algorithm in supported_algorithms, f'unknown {algorithm}, not in {supported_algorithms}'

    if algorithm == 'detection':
        protocol_version = env_config.protocol_version
        # from ymir1.3.0, keyword change from annotations to boxes
        if Version(protocol_version) >= Version("1.0.0"):
            keyword = "boxes"
        else:
            keyword = "annotations"

        detection_result = {}
        for asset_path, annotations in infer_result.items():
            asset_basename = os.path.basename(asset_path)
            detection_result[asset_basename] = {keyword: [annotation.dict() for annotation in annotations]}

        result = {"detection": detection_result}
        with open(env_config.output.infer_result_file, "w") as f:
            f.write(json.dumps(result))
    elif algorithm == 'segmentation':
        with open(env_config.output.infer_result_file, 'w') as f:
            f.write(json.dumps(infer_result))
    else:
        raise Exception(f'not implement {algorithm} infer result')

将图像路径与对应推理结果写到 cfg.ymir.output.infer_result_file (/out/infer-result.json)

from ymir_exc import result_writer
from ymir_exc.result_writer import Annotation, Box

## 目标检测结果
ann1 = Annotation(class_name = 'dog', score = 0.8, box = Box(x=10, y=20, w=10, h=10))
ann2 = Annotation(class_name = 'cat', score = 0.6, box = Box(x=10, y=20, w=10, h=10))
result_writer.write_infer_result(infer_result=dict(img_path1=[ann1, ann2], img_path2=[]))

## 语义分割与实例分割结果
coco_result = dict()
...
result_writer.write_infer_result(infer_result=coco_result, algorithm='segmentation')

进阶功能#

写进度,考虑多个过程#

每个过程有对应的进度,对每个过程进行加权,即为整体进度。

mining and infer can run in the same task. we support mining process percent in [0, 0.5], infer in [0.5, 1.0]

then we can:

# for mining, mining_percent in [0, 1]
monitor.write_monitor_logger(mining_percent * 0.5)

# for infer, infer_percent in [0, 1]
monitor.write_monitor_logger(0.5 + infer_percent * 0.5)

or we can

from ymir_exc import monitor

monitor.write_monitor_logger_for_mutiple_tasks(cfg, task='infer', percent=infer_percent, order='tmi')

if we consider more complicated case, mining task can divide into preprocess, task and postprocess stage, then we can use:

from ymir_exc.util import write_ymir_monitor_process, YmirStage

write_ymir_monitor_process(cfg, task='infer', naive_stage_percent=0.2, stage=YmirStage.PREPROCESS, stage_weights = [0.1, 0.8, 0.1], task_order='tmi')