基于深度学习的多光谱图像语义分割 —— 从原理到实践(第五节) 基于深度学习的多光谱图像语义分割 —— 从原理到实践第五节前四节我们完成了数据准备、分块处理、预训练模型推理和应用分析。现在你将学习从头构建并训练自己的 U‑Net 模型这样你可以自由调整网络结构、类别数量、损失函数以适应你自己的多光谱数据集。本节将深入讲解 U‑Net 架构、自定义损失函数的设计、训练超参数的含义并给出完整的训练代码。5. U‑Net 构建、训练与损失函数设计5.1 回顾 U‑Net 网络架构U‑Net 因形似字母 U 而得名它最早由 Ronneberger 等人于 2015 年提出用于生物医学图像分割后来成为遥感分割的常用骨干网络。其核心思想是对称的编码器-解码器结构 跳跃连接。编码器收缩路径由多个卷积块卷积 ReLU 批归一化组成。每经过一个块空间分辨率减半通过最大池化同时通道数翻倍例如从 64 到 128。这一步提取了图像的语义特征“是什么”但丢失了空间细节“在哪里”。解码器扩展路径由多个上采样块转置卷积或插值和卷积块组成。每上采样一次分辨率翻倍通道数减半。关键点跳跃连接——将编码器对应层的特征图与解码器上采样后的特征图拼接再将融合后的特征继续卷积。这使得解码器能够保留低级细节信息弥补下采样造成的空间损失。最终输出层一个1×1卷积将通道数映射为类别数再经过 softmax 得到每个像素的类别概率分布。U‑Net 的优势在于端到端输入任意尺寸图像输出同尺寸分割图。参数高效跳跃连接避免了信息瓶颈即使训练数据有限也能收敛。灵活性可以自由调整深度、初始通道数、卷积核大小等。5.2 使用unet函数构建网络MATLAB 的 Computer Vision Toolbox 提供了unet函数只需指定输入尺寸和类别数即可自动生成 U‑Net 网络。我们还可以通过名称-值参数调整深度、卷积滤波器数量等但本例使用默认设置。输入图像块尺寸为[256, 256]输入通道数为 6光谱通道输出类别数为 2inputTileSize[256256];inputDepth6;% 使用前 6 个光谱通道numClasses2;% 二分类unetNetworkunet([inputTileSize,inputDepth],numClasses);unetNetwork是一个dlnetwork对象可以直接用于训练或推理。你可以通过analyzeNetwork(unetNetwork)查看网络层结构、参数数量和连接关系。5.3 自定义损失函数——带掩膜的交叉熵在语义分割中常用的损失函数是像素级交叉熵Cross‑Entropy其公式为Loss -Σ_i Σ_c y_i,c * log(p_i,c)其中y_i,c是真实标签的 one‑hot 编码p_i,c是网络预测的概率。但我们的数据中存在无效区域掩膜外这些像素不应参与损失计算。因此我们需要自定义损失函数利用掩膜屏蔽无效位置。我们定义如下函数需要单独保存为lossFcn.m文件或在脚本末尾以局部函数形式定义functionlosslossFcn(Y,T)% Y: 网络预测尺寸 H×W×CC为类别数% T: 真实标签 one‑hot尺寸 H×W×C无效区域为 NaNmask~isnan(T);% 有效像素位置逻辑矩阵T(isnan(T))0;% 临时替换 NaN 为 0避免计算错误losscrossentropy(Y,T,Maskmask);endcrossentropy支持Mask参数只会对mask为 true 的位置计算损失其余位置忽略。这样我们就实现了只关注有效区域的学习。5.4 训练选项Training Options详解我们采用**带动量的随机梯度下降SGDM**优化器。以下是每个超参数的含义参数值含义InitialLearnRate0.05初始学习率控制参数更新步长。过大易震荡过小收敛慢。MaxEpochs70训练轮数即遍历整个数据集的最大次数。MiniBatchSize16每批处理的图像块数。受 GPU 显存限制可调小或调大。L2Regularization0.001L2 正则化系数权重衰减防止过拟合。LearnRateDropPeriod10每 10 轮学习率乘以LearnRateDropFactor默认 0.1。LearnRateSchedule“piecewise”分段衰减学习率策略。GradientThreshold0.05梯度裁剪阈值限制梯度的 L2 范数防止梯度爆炸。Shuffle“every-epoch”每轮开始时随机打乱数据增强随机性。VerboseFrequency200每 200 次迭代输出一次训练信息。设置代码如下maxEpochs70;minibatchSize16;optionstrainingOptions(sgdm,...InitialLearnRate0.05,...MaxEpochsmaxEpochs,...MiniBatchSizeminibatchSize,...L2Regularization0.001,...LearnRateDropPeriod10,...LearnRateSchedulepiecewise,...GradientThreshold0.05,...Shuffleevery-epoch,...VerboseFrequency200);5.5 启动训练我们使用trainnet函数Deep Learning Toolbox进行训练。它支持自定义损失函数并自动利用 GPU如果可用加速。设置doTraining true开始训练。训练结束后将模型按时间戳保存便于后续加载。doTrainingfalse;% 设为 true 以执行训练ifdoTraining nettrainnet(dsTrain,unetNetwork,lossFcn,options);modelDateTimestring(datetime(now,Formatyyyy-MM-dd-HH-mm-ss));save(fullfile(dataDir,multispectralUnet-modelDateTime.mat),net);enddsTrain是我们在第三节构建的CombinedDatastore每次迭代返回一个图像块和对应的标签块。trainnet会自动进行前向传播、损失计算、反向传播和参数更新并实时输出损失值。训练过程可能持续数小时取决于 GPU 性能和数据量。你可以通过Verbose和Plots选项开启训练曲线图监控损失下降趋势。5.6 训练过程中的注意事项GPU 内存不足如果报错 Out of Memory可减小MiniBatchSize或inputTileSize。学习率调整若损失震荡剧烈可降低InitialLearnRate若收敛缓慢可适当提高。早停策略可以通过ValidationData和ValidationFrequency选项添加验证集当验证损失不再下降时提前终止训练防止过拟合。数据增强trainnet本身不支持在线增强但你可以自定义transform函数对数据存储进行扩充例如随机旋转、翻转、色彩抖动等提高泛化能力。5.7 保存和加载模型训练好的net变量保存在.mat文件中。之后使用时只需load(fullfile(dataDir,multispectralUnet-2026-07-17-10-30-00.mat),net);即可恢复网络用于后续推理如第四节所示。5.8 本节完整代码汇总以下是将本节所有代码组合在一起的脚本训练部分默认关闭% 构建 U-NetinputTileSize[256256];inputDepth6;numClasses2;unetNetworkunet([inputTileSize,inputDepth],numClasses);% 定义损失函数需单独保存为 lossFcn.m% function loss lossFcn(Y,T)% mask ~isnan(T);% T(isnan(T)) 0;% loss crossentropy(Y,T,Maskmask);% end% 训练选项maxEpochs70;minibatchSize16;optionstrainingOptions(sgdm,...InitialLearnRate0.05,...MaxEpochsmaxEpochs,...MiniBatchSizeminibatchSize,...L2Regularization0.001,...LearnRateDropPeriod10,...LearnRateSchedulepiecewise,...GradientThreshold0.05,...Shuffleevery-epoch,...VerboseFrequency200);% 启动训练需先确保 dsTrain 已存在doTrainingfalse;ifdoTraining nettrainnet(dsTrain,unetNetwork,lossFcn,options);modelDateTimestring(datetime(now,Formatyyyy-MM-dd-HH-mm-ss));save(fullfile(dataDir,multispectralUnet-modelDateTime.mat),net);end5.9 本节小结在本节中我们完成了以下重要工作深入理解了 U‑Net 的编码器-解码器结构和跳跃连接原理使用unet函数快速构建了适用于多光谱图像的分割网络设计了带掩膜的交叉熵损失函数实现有效区域聚焦详细解释了每个训练超参数的作用并设置了 SGDM 优化器给出了完整的训练代码支持自定义开关和模型保存。现在你已经具备了从头训练一个多光谱语义分割模型的所有知识。如果训练条件允许可以实际运行训练对比预训练模型的效果。最后预告训练完成后我们需要客观地评估模型的性能。第六节将介绍如何计算全局准确率、平均 IoU、F1‑score 等指标并与真实标签进行对比验证模型的泛化能力。敬请期待最后一节《模型评估与性能分析》。