1. 从零开始:认识Halcon的深度学习三剑客

如果你在工业视觉领域摸爬滚打过一阵子,肯定对Halcon不陌生。它就像是视觉工程师的瑞士军刀,传统算法玩得风生水起。但最近几年,深度学习这股风也吹到了Halcon里,它内置的深度学习模块,让很多以前要靠复杂算法设计才能解决的难题,现在变得“有手就行”。我刚接触的时候也犯嘀咕,觉得这玩意儿会不会很复杂?但实际用下来发现,Halcon把很多繁琐的步骤都封装好了,流程非常清晰,特别适合我们这些想快速把AI能力集成到现有视觉项目里的工程师。

Halcon的深度学习模块主要提供了三种“武器”,我习惯叫它们“三剑客”:

  • 分类(Classification):这是最基础也是最常用的。简单说,就是教电脑看图说话,告诉它这张图里是什么。比如,产线上的一批零件,我需要快速判断它是良品A、不良品B还是混进来的异物C。分类网络就能帮你搞定。
  • 目标检测(Object Detection):这个就进阶一点了。不仅要告诉你图里有没有某个东西,还要用框(Bounding Box)把它在哪儿、有多大给标出来。想象一下,在一个托盘上散乱地放着多种型号的螺丝,你需要同时找到它们并识别各自的型号,这就是目标检测的用武之地。
  • 语义分割(Semantic Segmentation):这是目前工业检测里最精细、也最“卷”的技术。它不像目标检测那样只给个框,而是对图像中的每一个像素点进行分类,给每一个像素都打上标签。比如,在PCB板检测中,你需要精确地分割出焊盘、走线、阻焊层、背景等不同区域,甚至找出微米级的桥接、缺损,语义分割就能做到像素级的识别。

我刚开始学的时候,总觉得这三个任务背后是三种完全不同的技术。但Halcon聪明的地方在于,它为你设计了一套高度统一的工作流程。无论你做分类、检测还是分割,基本都遵循“准备数据 -> 训练网络 -> 评估模型 -> 应用推理”这四个核心步骤。只是在不同任务下,数据的格式、网络的输出、评估的指标有所不同。这种设计大大降低了学习成本,你只要掌握了一套,就能很快触类旁通。接下来,我就以最经典的图像分类任务为起点,带你走一遍完整的实战流程,把每个环节的细节和容易踩的坑都掰开揉碎了讲清楚。

2. 实战第一步:数据准备与网络初始化

俗话说“巧妇难为无米之炊”,在深度学习里,这个“米”就是数据。数据质量直接决定了你模型的天花板。很多新手朋友一上来就急着调参训练,结果效果不好,折腾半天才发现是数据没处理好。这一章,我们就好好聊聊怎么备好这锅“米”,以及怎么选一口合适的“锅”(预训练网络)。

2.1 数据的“清洗、整理与增强”

假设我们现在要做一个水果分类的项目,目标是区分苹果、桃子和梨。你的原始图片可能来自产线相机,背景杂乱,光照不均,大小不一。直接扔给网络训练,效果肯定大打折扣。

第一步:数据收集与标注。 对于分类任务,Halcon要求的数据组织形式非常简单:按类别分文件夹存放。比如,你建立一个总文件夹叫 fruit_dataset,里面再建三个子文件夹,分别叫 apple、peach、pear,然后把对应的图片放进去就行了。Halcon会自动把文件夹名当作类别标签。这里有个关键点,每个类别的图片数量尽量均衡,别让网络“偏科”。比如苹果有1000张,桃子只有100张,网络就会倾向于把所有东西都猜成苹果。

第二步:至关重要的图像预处理。 这是提升模型鲁棒性的关键。Halcon提供了 preprocess_dl_classifier 等算子,但理解其背后的逻辑更重要。通常我们需要:

  1. 尺寸归一化:网络输入尺寸是固定的(比如224x224)。你需要把大小各异的原始图像缩放到这个尺寸。注意,缩放时最好保持长宽比,然后用灰度填充边缘,避免物体变形。
  2. 像素值归一化:将图像的像素值范围(通常是0-255)映射到网络期望的范围(比如0-1或-1到1)。这能加速训练收敛。在Halcon中,这通过设置 'image_range_min' 和 'image_range_max' 参数来实现。
  3. 通道数调整:工业相机可能是黑白(单通道),但预训练网络(如ResNet)通常是在RGB三通道数据上训练的。你需要将单通道图像复制成三通道,或者使用Halcon的 compose3 算子合成。
  4. ROI提取(可选但重要):如果物体只占图像的一小部分,背景干扰很大,我强烈建议你先用传统方法或人工标注一个ROI(感兴趣区域),只裁剪出物体部分进行训练。这能极大提升模型对物体本身的关注度。

下面是一个简单的数据读取和预处理代码示例,你可以把它封装成一个函数:

* 读取原始数据,自动获取标签
RawDataFolder := 'fruit_dataset/'
read_dl_classifier_data_set (RawDataFolder, 'last_folder', RawImageFiles, Labels, LabelIndices, Classes)

* 设置预处理后的输出目录
PreprocessedFolder := 'fruit_preprocessed/'
* 如果目录已存在,可以选择覆盖或跳过
OverwritePreprocessingFolder := false

* 循环处理每一张图像
for Index := 0 to |RawImageFiles|-1 by 1
    read_image (Image, RawImageFiles[Index])
    * 1. 这里可以加入你的ROI提取代码,例如阈值分割、Blob分析等
    * 2. 调整图像尺寸到网络输入大小,例如224x224
    get_image_size (Image, Width, Height)
    zoom_image_factor (Image, ImageZoomed, 224.0/Width, 224.0/Height, 'constant')
    * 3. 确保图像为三通道(如果网络需要)
    count_channels (ImageZoomed, Channels)
    if (Channels != 3)
        * 将单通道图像转为三通道
        compose3 (ImageZoomed, ImageZoomed, ImageZoomed, ImageRGB)
        ImagePreprocessed := ImageRGB
    else
        ImagePreprocessed := ImageZoomed
    endif
    * 4. 构造输出路径并保存图像
    * ... 保存 ImagePreprocessed 到 PreprocessedFolder 对应类别子目录下
endfor

第三步:划分数据集。 千万不要用全部数据来训练!一定要分成训练集(Training Set)、验证集(Validation Set) 和测试集(Test Set)。常见的比例是70%:15%:15%。训练集用于模型学习;验证集用于在训练过程中监控模型表现,调整超参数(如学习率);测试集则是在模型完全训练好后,用于最终评估其泛化能力,在整个训练过程中绝对不能碰。Halcon的 split_dl_classifier_data_set 算子可以帮你自动完成这个划分。

2.2 选择合适的预训练网络

Halcon提供了几个开箱即用的预训练分类网络,它们是在大型图像数据集(如ImageNet)上预训练好的,包含了提取通用图像特征的能力。我们直接在它们的基础上进行“微调”(Fine-tuning),比自己从零训练一个网络要快得多,效果也好得多,尤其是在我们自己的数据量不大的情况下。

以Halcon 20.11版本为例,常见的预训练分类网络有:

  • pretrained_dl_classifier_compact.hdl:一个轻量级网络,速度快,占用资源少。适合对实时性要求高、计算资源有限的场景,或者物体特征比较明显、背景简单的分类任务。它对输入图像的最小尺寸要求较低。
  • pretrained_dl_classifier_enhanced.hdl:能力更强的网络,可以处理更复杂的图像和更细粒度的分类任务。当然,它的计算量也更大一些。
  • pretrained_dl_classifier_resnet50.hdl:基于经典的ResNet-50架构。这是一个在精度和速度之间取得很好平衡的网络,也是我最常推荐新手使用的网络。它的特征提取能力很强,泛化性好,适用于大多数工业分类场景。

选择哪个网络?我的经验是:先从ResNet50开始。它就像一辆性能均衡的SUV,能应对大多数路况。如果上线后发现速度跟不上,再考虑换更轻量的Compact网络;如果发现复杂缺陷分类精度不够,再考虑换更深的网络或尝试Enhanced版本。

读取和初始化网络非常简单:

* 读取预训练的ResNet50分类网络
read_dl_classifier ('pretrained_dl_classifier_resnet50.hdl', DLClassifierHandle)

* 必须根据你的数据设置网络的基本参数
ImageWidth := 224
ImageHeight := 224
ImageNumChannels := 3
ImageRangeMin := 0.0
ImageRangeMax := 255.0

set_dl_classifier_param (DLClassifierHandle, 'image_width', ImageWidth)
set_dl_classifier_param (DLClassifierHandle, 'image_height', ImageHeight)
set_dl_classifier_param (DLClassifierHandle, 'image_num_channels', ImageNumChannels)
set_dl_classifier_param (DLClassifierHandle, 'image_range_min', ImageRangeMin)
set_dl_classifier_param (DLClassifierHandle, 'image_range_max', ImageRangeMax)
* 设置类别,从之前读取数据时获得的Classes变量传入
set_dl_classifier_param (DLClassifierHandle, 'classes', Classes)

3. 核心环节:模型训练与过程监控

数据准备好了,网络也加载了,接下来就是最激动人心也最需要耐心的环节——训练。这个过程就像教一个聪明但没经验的学生,你需要告诉它学习节奏(学习率)、一次学多少(批大小)、以及怎么检验它学得对不对(验证集)。

3.1 理解并设置关键超参数

超参数是训练开始前就需要设定好的参数,它们不来自数据,而是来自你的经验或调优。几个最重要的:

  • batch_size(批大小):一次训练迭代中送入网络的图像数量。越大越好,但受限于你的GPU显存。常见设置是32、64、128。如果显存不够导致内存溢出(Out of Memory),就调小它。我一般从64开始试。
  • learning_rate(学习率):这是最重要的超参数之一,决定了参数更新的步长。太大容易“跑飞”,在最优解附近震荡甚至发散;太小则学习速度慢,容易陷入局部最优。对于微调预训练模型,学习率通常设得比较小,比如 0.001 或 0.0001。
  • momentum(动量):通常设为0.9。它可以帮助优化过程在正确的方向上加速,并抑制震荡,让训练更平稳。
  • num_epochs(训练轮数):整个训练数据集被完整遍历一次称为一个Epoch。需要多少轮?这没有定数,取决于数据和任务复杂度。我通常设置一个较大的值(比如100或200),然后配合早停(Early Stopping) 策略:当验证集上的错误率在连续多个Epoch不再下降时,就停止训练,防止过拟合。
  • runtime(运行设备):一定要设为 'gpu'!用CPU训练深度学习模型的速度会让你怀疑人生。

在Halcon中设置这些参数:

* 设置批大小
BatchSize := 64
set_dl_classifier_param (DLClassifierHandle, 'batch_size', BatchSize)
* 对于显存较小的GPU,可以设置更小的设备批大小
set_dl_classifier_param (DLClassifierHandle, 'batch_size_device', 32)

* 设置初始学习率
InitialLearningRate := 0.001
set_dl_classifier_param (DLClassifierHandle, 'learning_rate', InitialLearningRate)

* 设置动量
set_dl_classifier_param (DLClassifierHandle, 'momentum', 0.9)

* 指定在GPU上运行
set_dl_classifier_param (DLClassifierHandle, 'runtime', 'gpu')
* 立即初始化GPU(如果还没初始化的话)
set_dl_classifier_param (DLClassifierHandle, 'runtime_init', 'immediately')

3.2 启动训练与可视化监控

参数设好,就可以开始训练了。Halcon提供了 train_dl_classifier 算子,但为了更好的控制和学习率调度,我更喜欢按照示例程序的方式,自己写训练循环。不过,Halcon也封装了高级接口。

训练过程中,最怕的就是“黑箱”操作,你不知道模型学得怎么样了。Halcon的 plot_dl_classifier_training_progress 算子是你的“监控仪表盘”。它能实时绘制两条关键曲线:

  1. 训练误差曲线:模型在训练集上的表现。
  2. 验证误差曲线:模型在验证集上的表现。

如何解读这两条曲线?

  • 理想情况:两条曲线都稳步下降,并且最终保持在一个很低的水平,且彼此非常接近。这说明模型学得很好,没有过拟合也没有欠拟合。
  • 过拟合(Overfitting):训练误差持续下降,但验证误差下降到一定程度后开始上升。这说明模型把训练数据中的噪声和特殊细节都学进去了,导致在新数据上表现变差。解决办法:增加数据量、使用数据增强、给网络增加正则化(如Dropout)、或者提前停止训练。
  • 欠拟合(Underfitting):训练误差和验证误差都很高,且下降得很慢或几乎不降。这说明模型太简单,或者训练轮数不够,无法从数据中学到有效模式。解决办法:增加网络复杂度、增加训练轮数、检查数据预处理是否有问题、尝试提高学习率。

下面是一个简化的训练与监控代码框架:

* 假设我们已经划分好了数据集:TrainingImages, TrainingLabels, ValidationImages, ValidationLabels
NumEpochs := 100
* 每4个Epoch绘制一次训练进度图
PlotEveryNthEpoch := 4
* 学习率调度:每30个Epoch,将学习率乘以0.1(即降为原来的10%)
LearningRateStepEveryNthEpoch := 30
LearningRateStepRatio := 0.1

* 训练模型,并保存到文件
FileName := 'my_trained_fruit_classifier.hdl'
* 这里调用一个封装好的训练函数,内部包含了循环和进度绘制
* 具体实现可参考Halcon示例程序 `classify_fruit_compact.hdev`
train_dl_classifier (DLClassifierHandle, TrainingImages, TrainingLabels, ValidationImages, ValidationLabels, NumEpochs, LearningRateStepEveryNthEpoch, LearningRateStepRatio, PlotEveryNthEpoch, FileName)

训练时,你会看到一个窗口,里面的曲线随着Epoch增加而变化。耐心观察,这是你和模型“交流”的主要方式。

4. 模型评估与工业实战应用

模型训练完了,曲线看起来也挺漂亮,但这不代表它就能直接上生产线了。我们必须用从未见过的测试集给它来一次“毕业考试”,并且要能看懂“成绩单”。

4.1 使用混淆矩阵进行量化评估

对于分类任务,最直观的评估工具就是混淆矩阵(Confusion Matrix)。它是一张N x N的表格(N是类别数),行代表真实的类别,列代表模型预测的类别。对角线上的数字表示预测正确的样本数,其余位置则是预测错误的情况。

Halcon生成混淆矩阵非常简单:

* 读取训练好的模型
read_dl_classifier (FileName, DLClassifierHandle)

* 对测试集进行预测
get_predicted_classes (TestImages, DLClassifierHandle, PredictedClassesTest)

* 生成并显示混淆矩阵
gen_confusion_matrix (TestLabels, PredictedClassesTest, [], [], WindowHandle, ConfusionMatrix)

怎么看懂这张表? 假设我们有三类:苹果、桃子、梨。混淆矩阵可能长这样:

真实 \ 预测苹果桃子梨
苹果9532
桃子1981
梨5293
  • 主对角线(加粗):模型预测正确的数量。苹果对了95个,桃子对了98个,梨对了93个。
  • 非对角线元素:预测错误的数量。例如,第一行第二列的“3”,表示有3个真实的苹果被错误地预测成了桃子。
  • 分析:从这个矩阵看,模型整体表现不错。但苹果被误判为梨(2个)和桃子被误判为苹果(1个)的情况相对较少,而梨被误判为苹果(5个)的情况稍多。这可能意味着梨和苹果在某些特征上比较相似,需要回头检查这两类数据的特征是否区分度不够,或者考虑增加一些数据增强来强化它们的差异。

除了直观的表格,我们还需要几个关键数值指标:

  • 准确率(Accuracy):所有预测正确的样本占总样本的比例。(95+98+93) / 300 = 95.3%。这是最常用的指标,但在各类别样本数量不平衡时可能会失真。
  • 精确率(Precision):以“苹果”为例,所有被预测为苹果的样本中,真正是苹果的比例。95 / (95+1+5) ≈ 94.1%。它关注的是预测结果的“准不准”。
  • 召回率(Recall):以“苹果”为例,所有真实的苹果样本中,被正确预测出来的比例。95 / (95+3+2) = 95%。它关注的是真实样本的“找得全不全”。

Halcon可以通过 get_confusion_matrix 算子计算这些指标。一个健壮的模型,应该在测试集上拥有高且均衡的精确率和召回率。

4.2 工业实战:PCB元件缺陷分类案例

光说不练假把式。我分享一个之前做过的真实项目:PCB板上的元件缺陷分类。任务是将摄像头拍到的元件区域,自动分类为“正常(OK)”、“气泡(Bubble)”、“划伤(Scratch)”、“破损(Crack)”和“翘脚(Lifted Lead)”。

我们面临的挑战:

  1. 缺陷样本稀少,尤其是“破损”和“翘脚”这类严重缺陷,在产线上出现的频率本身就很低。
  2. 缺陷形态多变,同一种缺陷(如划伤)的长短、深浅、方向各不相同。
  3. 背景干扰,PCB板的丝印、走线、焊盘等都会干扰特征提取。

我们的解决方案:

  1. 数据层面:
    • 重点采集与增强:针对稀有缺陷,我们专门在维修站收集了一批坏板,并进行了大量的数据增强——随机旋转、翻转、调整亮度对比度、添加高斯噪声、模拟轻微模糊等。特别是对于划伤,我们用了仿射变换来模拟不同方向。
    • 精准ROI:先用传统的模板匹配或Blob分析,精确定位每一个元件的位置,裁剪出只包含元件的子图像,极大消除了背景干扰。
  2. 模型层面:
    • 选择了 pretrained_dl_classifier_enhanced.hdl,因为缺陷特征相对细微,需要更强的网络。
    • 在训练时,我们采用了加权损失函数(通过在 set_dl_classifier_param 中设置 'class_weights' 参数),给样本稀少的缺陷类别(如翘脚)赋予更高的权重,让模型在训练时更关注它们。
  3. 训练技巧:
    • 使用了较小的初始学习率(0.0005),并采用了学习率衰减策略。
    • 设置了较大的 num_epochs (200),并启用了早停机制(监控验证集损失,连续10轮不下降则停止)。
  4. 结果与部署:
    • 最终在测试集上达到了99.2%的准确率。混淆矩阵显示,“翘脚”和“破损”的召回率也达到了97%以上,满足了客户要求。
    • 部署时,我们将训练好的 .hdl 模型文件集成到现有的Halcon视觉程序中。推理部分代码非常简洁:
* 在线检测循环中
* 1. 采集图像
grab_image (Image, AcqHandle)
* 2. 定位并裁剪出元件ROI (RegionOfInterest)
* ... (传统算法定位)
reduce_domain (Image, RegionOfInterest, ImageReduced)
* 3. 预处理(缩放、通道转换等)
preprocess_dl_classifier (ImageReduced, ImagePreprocessed, DLClassifierHandle)
* 4. 推理
apply_dl_classifier (ImagePreprocessed, DLClassifierHandle, DLClassifierResultHandle)
* 5. 获取结果
get_dl_classifier_result (DLClassifierResultHandle, 'all', 'predicted_classes', PredictedClass)
get_dl_classifier_result (DLClassifierResultHandle, PredictedClass, 'confidence', Confidence)
* 6. 判断:如果置信度高于阈值(如0.98)且为缺陷类,则触发报警
if (Confidence > 0.98 and PredictedClass != 'ok')
    disp_message (WindowHandle, 'Defect Found: ' + PredictedClass, 'image', 10, 10, 'red', 'true')
endif

这个项目让我深刻体会到,在工业场景中,数据和预处理往往比模型本身更重要。一个设计良好的数据流水线和一个合适的预训练网络,就能解决80%的问题。剩下的20%,则需要你根据具体任务,耐心地去调整超参数和训练策略。

5. 迈向更高阶:目标检测与语义分割初探

掌握了分类,你已经拿到了Halcon深度学习的入门钥匙。但工业视觉的需求远不止于此。当你的任务从“是什么”变成“在哪里”和“边界在哪”时,就需要请出另外两位“剑客”了。

5.1 目标检测:定位与识别一步到位

目标检测在Halcon中对应的网络类型是 'object_detection'。它与分类最大的区别在于数据标注。你需要为训练图像中的每一个待检测物体标注一个矩形框(Bounding Box) 和其对应的类别标签。Halcon使用一种特定的DL样本字典格式来存储这些信息,里面包含了图像路径、边界框坐标、类别ID等。

工作流程类比:

  1. 数据准备:使用 read_dict 读取标注好的样本字典。标注工具可以用Halcon自带的 annotate_dl_dataset,或者其他标注工具(如LabelImg)导出后再转换格式。
  2. 网络选择:Halcon提供了预训练的目标检测网络,如基于YOLO等架构的模型。读取使用 read_dl_model。
  3. 参数设置:除了设置图像尺寸、类别,还需要设置与锚框(Anchor)相关的参数,这些参数通常预训练网络已经设定好,微调时一般不用改。
  4. 训练与评估:流程和分类类似,但评估指标变了。常用的有平均精度(Average Precision, AP) 和交并比(Intersection over Union, IoU)。Halcon的 evaluate_dl_model 可以计算这些指标。
  5. 推理:使用 apply_dl_model 后,得到的结果是每个检测框的坐标、类别和置信度。

一个简单示例:检测图像中的多种水果。

* 读取目标检测模型
read_dl_model ('pretrained_dl_detector_compact.hdl', DLModelHandle)
* 设置参数
set_dl_model_param (DLModelHandle, 'classes', ['apple', 'peach', 'pear'])
* ... 其他参数设置

* 推理
apply_dl_model (ImagePreprocessed, DLModelHandle, DLResultHandle)
* 获取结果:会得到多个检测框
get_dl_model_result (DLResultHandle, 'all', 'bbox', BBoxes)
get_dl_model_result (DLResultHandle, 'all', 'class_id', ClassIDs)
get_dl_model_result (DLResultHandle, 'all', 'confidence', Confidences)

* 可视化
for i := 0 to |BBoxes|-1 by 1
    if (Confidences[i] > Threshold)
        * 根据BBoxes[i]的坐标画出矩形框
        * 在框旁显示类别和置信度
    endif
endfor

5.2 语义分割:像素级的极致解析

语义分割是Halcon深度学习模块中功能最强大,也是相对最复杂的一环,网络类型为 'semantic_segmentation'。它的标注成本最高,因为需要为图像中的每一个像素标注类别,生成一张与原始图同尺寸的“标签图”,其中每个像素的值代表其类别索引。

工作流程核心差异:

  1. 数据标注:这是最大的门槛。你需要使用专业的像素级标注工具(如Halcon的 annotate_dl_dataset 或第三方工具如CVAT、Labelme)。标注结果是一张单通道的标签图像。
  2. 网络与输出:Halcon提供了预训练的语义分割网络(如基于DeepLabV3等)。网络的输出不是类别ID,而是一个概率图。对于每个像素位置,网络会输出一个长度为N(类别数)的向量,表示该像素属于各个类别的概率。
  3. 后处理:对网络输出的概率图,使用 tuple_argmax 或 best_match 等操作,找到每个像素概率最大的类别,生成最终的整型标签图。通常还需要进行一些形态学后处理(如开运算去除小噪点)来优化分割结果。
  4. 评估指标:常用平均交并比(Mean IoU)。计算每个类别的预测区域与真实区域的重合度,再求所有类别的平均值。

实战意义: 在我做过的液晶屏Mura缺陷检测项目中,语义分割大放异彩。Mura(斑痕)缺陷与背景的对比度极低,边界模糊,用传统阈值或边缘检测根本无从下手。我们用语义分割网络,将图像分割成“背景”、“亮点Mura”、“暗点Mura”等区域。网络能够学习到这种细微的纹理和灰度变化,精准地勾勒出缺陷的轮廓,甚至能区分不同严重程度的Mura,这是传统算法和分类/检测网络都无法做到的。

简单代码示意:

* 读取语义分割模型
read_dl_model ('pretrained_dl_segmentation_compact.hdl', DLModelHandle)
set_dl_model_param (DLModelHandle, 'classes', ['background', 'defect'])

* 推理 - 输出是每个像素属于各类别的概率
apply_dl_model (ImagePreprocessed, DLModelHandle, DLResultHandle)
* 获取所有类别的分数图
get_dl_model_result (DLResultHandle, 'all', 'segmentation_score_maps', ScoreMaps)
* ScoreMaps是一个包含多个二维数组的元组,每个数组对应一个类别的概率图

* 后处理:找到每个像素得分最高的类别
* 这里假设只有两类,可以简单比较
* 对于多类,需要遍历每个像素位置,比较所有ScoreMaps中的值
* 生成最终的分割区域
threshold (ScoreMaps[1], DefectRegion, 0.5, 1.0) * 假设索引1是缺陷类的概率图
connection (DefectRegion, ConnectedDefects)
* 后续可以对ConnectedDefects进行特征筛选(面积、形状等)

从分类到检测再到分割,Halcon为你搭建了一条清晰的能力进阶路径。我的建议是,先扎扎实实把分类任务做透,理解数据、训练、评估的完整闭环。当你对这套流程烂熟于心后,转向目标检测和语义分割,你会发现核心思想是相通的,只是数据的“形状”和网络的“输出”变了。这时,你的学习重心就变成了如何准备更复杂的标注数据,以及如何理解和处理网络输出的新格式。

更多推荐