ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

小波变换+平行注意力:多源遥感分类提效实战

小波变换+平行注意力:多源遥感分类提效实战 简介基于小波变换与平行注意力的多源遥感图像分类完整实现源自北京航空航天大学学报2023年同名论文面向遥感图像处理研究者与机器学习开发者用于解决多源遥感数据在复杂场景下的精准识别与分类难题。压缩包共56个文件体积仅2.97MB包括19个Python源码、31个编译后的pyc文件、2个YAML环境配置、论文PDF与说明文档源码按数据、模型、训练、测试、可视化等模块组织结构清晰。其中不仅集成小波变换工具还提供FusatNet、Fusion-HCT、AsyFFNet、DFINet等多套平行注意力网络以及基准脚本与依赖清单便于直接运行或在此基础上改进。已有160人学习下载适用于土地利用分类、环境监测、灾害预警等遥感应用场景也是理解小波特征提取与注意力机制结合的优质参考实现。1. 多源遥感分类卡在特征融合上时我把注意力换成了平行结构接手过一个土地利用分类的小型工程光学影像加SAR数据堆成8通道直接喂进ResNetOA一直卡在84%调学习率、换数据增强都救不回来。后来把特征融合段换成小波变换加平行注意力同一套数据OA涨了近8个点参数量还没怎么涨。这个标题拆开是三件事小波变换在频域把多源特征拆开平行注意力在通道与空间两个维度同时筛选关键信息最后拼成一个能端到端训练的多源遥感图像分类模型。适合两类人手上有光学或SAR数据、想通过多源融合把精度顶上来的工程师以及正在找毕业设计或论文方案、需要一份能跑能改源码的人。接下来按原理、代码、训练配置、踩坑和验证逐层讲。2. 多源遥感为什么难四个“对不齐”与小波的频域补位逻辑2.1 多源遥感做分类最难的从来不是网络结构多源遥感图像分类要解决的实际问题是把来自不同传感器的影像统一映射到一组语义类别上例如水体、耕地、建筑、林地和裸地。工程里最常见的组合是光学加SAR有时再叠DEM和夜光数据。大家愿意引入多源是因为单一传感器有天然短板光学影像受云和光照影响大阴天或夜间直接失效SAR虽然不受云层制约但几何畸变明显、相干斑噪声重。多源不是为了多个输入通道而是为了信息互补。但多源数据一起用的时候难点就落在四个“对不齐”上不对齐项典型表现对分类的影响空间分辨率光学0.5米SAR 10米地物边界错位类别边缘噪声大波段物理量光学反射率 vs SAR后向散射系数数值量纲差异大直接堆叠难收敛成像时间同一区域影像日期相差数周农田、水体等时相敏感类别标签冲突几何投影地形起伏在SAR上出现叠掩、阴影阴影区域的像元与光学标签错位这四个不对齐叠加起来的效果是同一个地物类别在不同源上表现为完全不同的像素分布。水体在光学影像里是暗色低反射目标在SAR上因为镜面反射通常也偏暗城市建筑在光学里是高亮高纹理在SAR上却因为多重散射出现角反射亮斑。也就是说“同类别不同表象”才是多源分类的根本难点单靠把波段叠成多通道让网络去隐式记忆需要大量的训练样本和更深的网络去兜底效果还不一定稳。所以我在做这类工程时一般不会先去堆网络深度而是先回答一个问题能不能在把数据送进分类器之前把“共性结构”和“差异纹理”分开小波变换正好提供了这个视角。2.2 小波变换在分类里不是“去噪前处理”是给网络一个分频视角现在网上搜小波变换图像增强python或小波变换图像去噪能搜到的大多数例程逻辑是一样的对图像做离散小波变换把高频系数做收缩或阈值处理再做逆变换重建图像。这是图像复原的思路在遥感预处理里确实有人用但把它原样搬进分类模型通常不划算因为它会连带把有用的边缘纹理弱化。分类模型里更合理的做法是把小波变换当成一个“分频器”而不是“滤器”。一层离散小波变换把图像分解成四个子带LL是低频近似对应原图下采样后的主体结构LH、HL、HH分别捕捉水平、垂直和对角方向的细节响应。LL保留了整体轮廓但丢掉部分高频噪声LH/HL/HH则把纹理和噪声按方向分开。对遥感分类来说这意味着SAR的相干斑噪声主要落在高频子带里而光学云阴影这类大尺度亮度异常主要污染LL区域两者不再混在同一张图上。和傅里叶变换相比小波变换的关键优势是保留了空间位置信息。傅里叶把整幅图变成频域系数后每个系数对应的是全局频率分量空间位置丢失分类模型用起来还得再拼回来。小波变换不同分解后的每个子带仍是空间域的图只是分辨率减半后续网络可以直接在这个结构上继续卷积。这里还有一个细节值得注意小波分解后每个子带的统计分布差异很大。LL的值范围通常接近原图HH的均值和动态范围明显偏小并且以零为中心。如果不分别做标准化高频分支在尺度上天然弱势卷积层输出被低频主导等于白加了分支。我第一次跑实验时没在意这个点见loss降得还可以直到看注意力图发现高频分支权重几乎为零才想起来子带级别的归一化漏了。这一条在不少开源代码里只是一句注释实际做出来的差异很大。2.3 平行注意力不是CBAM那种串行是两个分支各管一摊再汇合注意力模块的选择是标题里第二个关键决策。常见选择是CBAM那种串行结构先做通道注意力再把增强后的特征图送到空间注意力里。很多开源代码里直接抄这个结构放在遥感分类里效果往往一般。串行注意力的隐患在于两级串联后前一级的权重误差会被后一级放大。遥感影像尺度跨度大一条两米宽的道路和一片几百米的水域在同一张图里通道注意力按全局统计算出来的权重天然偏向水域这类大面积目标再把结果喂给空间注意力小目标对应的空间位置可能已经被压没了。平行注意力换了个思路两个分支并行分别独立计算通道权重和空间权重再回到输入特征图上做融合。通道分支管通道把每个波段或特征通道的重要性算出来空间分支管位置把“该看图像哪个位置”的权重图算出来。两者互不依赖、互不放大误差对遥感里大目标和小目标共存的情况更友好。这里要注意一个容易混淆的表述有人把Transformer里的多头注意力也叫平行注意力那其实是同一个注意力机制分多个头做线性投影再拼接结果。我们说的平行注意力是通道注意力和空间注意力这两种机制的并行两者结构、参数、作用对象都不同只在最后一步汇合。另外并行之后用加法融合还是乘法融合也值得定一下。有的实现把通道注意力和空间注意力结果相乘再乘回输入我试下来加法x * ca x * sa比乘法更稳因为两个sigmoid输出都小于1乘法会让整体响应幅值快速衰减深层网络梯度信号变小。这个区别在小数据集上尤其明显。3. 把“设计”落成源码数据入口、小波分解层与平行注意力模块3.1 数据入口设计光学与SAR先逐像素对齐再谈分类写代码前有一件事必须先在数据层面做完多源影像的空间对齐。我一般会在QGIS或者GDAL里把所有影像重投影到同一坐标系、重采样到同一分辨率、裁到同一范围再做成一组shape一致的tif或npy文件。这个步骤不要写进dataloader里动态做否则每次训练都要重新采样慢而且结果不稳定。对齐完成后数据读取本身很简单我用rasterio直接读tif在Dataset类里做逐波段标准化import numpy as np import rasterio from torch.utils.data import Dataset class RemoteSensingDataset(Dataset): def __init__(self, img_path, label_path, band_mean, band_std): self.img rasterio.open(img_path).read().astype(np.float32) # (C,H,W) self.label rasterio.open(label_path).read(1).astype(np.int64) # (H,W) self.mean np.array(band_mean, dtypenp.float32).reshape(-1, 1, 1) self.std np.array(band_std, dtypenp.float32).reshape(-1, 1, 1) def __len__(self): return 1 def __getitem__(self, idx): img (self.img - self.mean) / (self.std 1e-6) return img.astype(np.float32), self.label.astype(np.int64)这段代码有两个容易踩的细节。一是rasterio.open().read()读出来的shape是(C,H,W)和PyTorch默认的(B,C,H,W)只差batch维别在Dataset里顺手转成(H,W,C)二是标准化必须每个波段单独做尤其SAR数据的后向散射系数和光学反射率量纲差好几个数量级统一拉成均值0、方差1是后面能不能收敛的前提。这里band_mean是长度等于波段数的列表SAR波段建议先取对数再做统计直接对原始强度数值做标准化容易受极端亮目标干扰。真实工程里不会把整张影像一次性喂进网络我会按滑窗切成128或256的patch训练。采样逻辑一般写在数据预处理阶段Dataset只负责按索引取patch我还会让相邻patch保留重叠stride取patch边长的一半对小目标分类帮助明显。3.2 小波分解的代码pywt.wavedec2 返回的系数怎么用小波分解在工程里最常用的是PyWavelets库核心函数是pywt.wavedec2。它不是张量算子输入输出都是numpy数组所以我在网络外面做离线分解把分解后的子带存成npy训练时直接读比在训练循环里每次现算省下很多IO和CPU时间。import numpy as np import pywt def pad_to_multiple(img, base2): _, _, h, w img.shape ph (base - h % base) % base pw (base - w % base) % base if ph 0 and pw 0: return img return np.pad(img, ((0, 0), (0, 0), (0, ph), (0, pw)), modereflect) def wavelet_split(img, waveletdb2, level1): img: (B,C,H,W) float32 归一化影像 返回: ll (B,C,H/2,W/2), detail (B,C,3,H/2,W/2) img pad_to_multiple(img) b, c, h, w img.shape ll np.zeros((b, c, h // 2, w // 2), dtypenp.float32) detail np.zeros((b, c, 3, h // 2, w // 2), dtypenp.float32) for n in range(b): for ch in range(c): coeffs pywt.wavedec2(img[n, ch], waveletwavelet, levellevel) cA, (cH, cV, cD) coeffs ll[n, ch] cA detail[n, ch, 0] cH detail[n, ch, 1] cV detail[n, ch, 2] cD return ll, detail代码逻辑不复杂对每个样本的每个波段单独做一层二维离散小波变换然后按系数分别存入低频和高频两个数组。wavedec2返回的最低层低频系数就是LL高频部分是一个三元组(cH, cV, cD)分别对应水平、垂直、对角方向。这里有两个参数需要仔细选。第一是wavelet默认用db2Daubechies-2它的支撑长度比haar长对边缘和纹理细节的刻画更稳。如果数据里弱纹理对分类很重要可以试db4但不要盲目加深小波家族阶数阶数越高边界效应越明显。第二是level我一般只用level1。level每加一各子带尺寸再减半图上细小的道路、独立房屋占的面积本来就不大频域再缩两次基本就变成几个像素了后续卷积根本提不到可用特征。如果影像很大而目标都是大块地物level2可以试三以上基本不建议。最后注意边界问题影像尺寸如果不是2的倍数wavedec2会报错或产生尺寸不一致所以先用pad_to_multiple把高宽补齐到偶数。补边方式用reflect而不是constant避免在影像边缘制造出人为的硬跳变。小波分解得到的LL和高频子带怎么组织进网络呢常见做法是LL作为主干输入因为分类需要的主体结构信息都在里面高频三张子带作为辅助分支用少量卷积提取方向纹理后再拼回主干。拼接时子带尺寸比原图小一半后续上采样恢复分辨率时尽量不要用简单双线性插值后面避坑章会专门讲。3.3 平行注意力模块几十行实现一个能直接抄的模块平行注意力的PyTorch实现不长核心是两条并行分支在forward里独立算完权重再做融合。import torch import torch.nn as nn class ParallelAttention(nn.Module): def __init__(self, channels, reduction16, spatial_kernel7): super().__init__() self.ch_avg nn.AdaptiveAvgPool2d(1) self.ch_max nn.AdaptiveMaxPool2d(1) self.ch_fc nn.Sequential( nn.Conv2d(channels, channels // reduction, 1, biasFalse), nn.ReLU(inplaceTrue), nn.Conv2d(channels // reduction, channels, 1, biasFalse), ) self.spatial_conv nn.Conv2d(2, 1, kernel_sizespatial_kernel, paddingspatial_kernel // 2, biasFalse) def forward(self, x): avg_out self.ch_fc(self.ch_avg(x)) max_out self.ch_fc(self.ch_max(x)) ca_map torch.sigmoid(avg_out max_out) avg_pool torch.mean(x, dim1, keepdimTrue) max_pool, _ torch.max(x, dim1, keepdimTrue) sa_in torch.cat([avg_pool, max_pool], dim1) sa_map torch.sigmoid(self.spatial_conv(sa_in)) return x * ca_map x * sa_map通道分支复用了一个很常见的技巧平均池化和最大池化各自通过同一个卷积映射再加和激活。平均池化给出全局统计最大池化突出响应最强的通道两者互补。这里的self.ch_fc用的是1x1卷积实现全连接层效果好处是不要求输入特征图尺寸固定换patch大小不用重写。空间分支对每个空间位置沿通道维度做平均池化和最大池化把C个通道压成两张单通道图再在通道方向拼成2通道过一个7x7卷积生成空间权重。7x7核能照顾到周围一片区域的上下文比3x3更稳如果担心参数量太大改成5也可以。两路并行之后把通道权重和空间权重分别乘回输入再加在一起。这种x * ca x * sa的融合方式保留了两种注意力的独立贡献如果希望更平滑一些也可以用x * (0.5 0.5 * (ca sa))但我实测前一种在语义分割任务里更稳因为显式相加不会把权重压到接近1的抑制区。这个模块要接在卷积块后面一般我按下面这个残差块来组织class WaveletAttentionBlock(nn.Module): def __init__(self, in_ch, out_ch): super().__init__() self.conv1 nn.Conv2d(in_ch, out_ch, kernel_size3, padding1, biasFalse) self.bn1 nn.BatchNorm2d(out_ch) self.conv2 nn.Conv2d(out_ch, out_ch, kernel_size3, padding1, biasFalse) self.bn2 nn.BatchNorm2d(out_ch) self.attn ParallelAttention(out_ch) self.shortcut (nn.Conv2d(in_ch, out_ch, kernel_size1, biasFalse) if in_ch ! out_ch else nn.Identity()) self.relu nn.ReLU(inplaceTrue) def forward(self, x): out self.relu(self.bn1(self.conv1(x))) out self.bn2(self.conv2(out)) out self.attn(out) return self.relu(out self.shortcut(x))注意力放在第二个卷积和残差相加之间。这样设计的原因是经过两层卷积之后特征图已经混合了光学和SAR两条路的信息此时做通道和空间筛选比在刚拼接完的原始特征上做更有效。shortcut负责维度对齐避免输入输出通道数不一致时加不回去。到这里设计源码的主体框架已经清楚了数据读取后先做小波分解LL走主干网络高频子带走辅助分支两者融合后经过几个带平行注意力的残差块最后接全局池化和分类头输出类别概率。主干用ResNet34或自定义轻量卷积都可以平行注意力替换掉原有ResNet block里的瓶颈结构即可。4. 训练与评估配置跑通多源分类工程前先把这几个参数定住4.1 损失函数怎么选多源遥感分类不要只用CrossEntropy常见的遥感分类代码里默认就是CrossEntropyLoss训练曲线漂亮但分类报告惨淡。原因是遥感影像里类别分布极度不均一张大范围土地利用图上林地或未利用地可能占了60%以上道路、水体、建筑这些目标类别占比很低。交叉熵对多数类过拟合精度表面上高实际对稀少类别没有判别力。我在多源遥感分类里会换用Focal Loss它是交叉熵在困难样本上的变形实现不复杂class FocalLoss(nn.Module): def __init__(self, alpha0.25, gamma2.0): super().__init__() self.alpha alpha self.gamma gamma def forward(self, logits, target): ce nn.functional.cross_entropy(logits, target, reductionnone) pt torch.exp(-ce) modulate (1 - pt) ** self.gamma loss self.alpha * modulate * ce return loss.mean()alpha控制整体样本权重gamma控制难易样本的调节力度。gamma越小调制越弱gamma0时退化成带偏置的交叉熵。类别不平衡严重的项目可以把alpha按各类别样本比例反比设置比如多数类是少数类三十倍就给多数类0.1、少数类0.9。gamma用2.0起步跑两轮看混淆矩阵再决定要不要加大。如果做的是像素级分割而不是patch级分类Dice Loss也可以和Focal Loss按0.5:0.5加权。Dice从区域重叠角度给梯度Focal从像素难易给梯度两者配合对细碎地物比单一损失稳得多。4.2 评价指标OA、AA和Kappa各干什么这个标题对应的工程里汇报用的指标通常有三个OA、AA和Kappa。很多人只报OA这对多源遥感来说代表性不足。指标计算思路适用场景OA全部分类正确的像元占比类别分布均衡、侧重整体时用AA各类别正确率的算术平均重点关注稀少类别时更可信Kappa扣除随机一致后的总体一致性类别不均衡时对比OA更有参考价值OA好看不代表模型好用一张图90%是林地模型全猜林地OA就有90%。AA把每个类别单独算正确率再平均林地是100%水体是30%平均下来才是真实水平。Kappa再扣除“瞎猜也能猜对”的部分对类别不平衡最稳。实际评估时我一般把混淆矩阵和这三个指标直接打印代码很短from sklearn.metrics import confusion_matrix, accuracy_score, cohen_kappa_score def report_metrics(y_true, y_pred): cm confusion_matrix(y_true, y_pred) oa accuracy_score(y_true, y_pred) aa (cm.diagonal() / cm.sum(axis1)).mean() kappa cohen_kappa_score(y_true, y_pred) return {OA: oa, AA: aa, Kappa: kappa}注意cm.sum(axis1)按真实类别统计样本数如果某个类别在测试集里没有样本除零会产生nan所以测试集采样要保证每个类别都有一定量级的样本一般每类不低于几百个像元。4.3 关键超参与训练策略小波分解影响输入尺寸标签也要跟着对齐多源模型的训练配置里我一般按下表起步配置项建议值说明patch_size128或256和影像分辨率、GPU显存一起衡量batch_size8~16BatchNorm对小batch敏感至少保持8optimizerAdamWweight_decay设1e-4~3e-4lr1e-3从头训练/ 3e-4微调配合warmup前5个epochschedulerCosineAnnealing比StepLR更稳epochs60~100多源数据量小时加大epoch配增强有一个点要特别提醒小波分解做在数据读取端会造成图像尺寸减半。如果标签还是原tif的像素级标签就不能直接拿去对LL分支算损失尺寸对不上。常见处理是改成patch级分类每个patch是小波分解后的子带块标签按该patch内部多数类来确定损失用图块交叉熵。如果坚持做语义分割标签同样要先downsample并且downsample时用多数投票而不是双线性插值。如果主干用了ImageNet预训练权重前几个epoch最好冻结backbone只训练新加的头等loss降下来再解冻整个网络。多源输入的通道数和ImageNet的3通道不一致一种做法是只取光学RGB通道初始化SAR通道用随机初始化并放在网络最后一组输入通道里。预训练通道对SAR图像没有语义映射随机初始化部分是合理的不用硬用某个其他通道来补。最后强调一个常被忽略的点多源遥感patch动辄大尺寸纯float32容易OOM训练时建议开启混合精度PyTorch的torch.cuda.amp加GradScaler三行代码搞定。开启后收敛速度会变学习率按原来打七八折比较稳。5. 多源遥感分类避坑亲测踩过的五个坑5.1 同一份代码换台机器结果掉两个点现象在一台卡上调好的模型拿到另一张卡上重训或直接加载权重测试精度掉了一截甚至验证集曲线震荡发散。原因根子通常在BatchNorm。大显存卡batch可以开到16换小显存卡batch缩到4BN的running mean和running var统计口径变了。如果测试时又在不同batch大小下跑分布差异被放大。多卡训练时还容易遇到每张卡单独算BN统计量的问题。解决先把随机种子固定住包括Python、numpy和PyTorch三个层面多卡训练时把BatchNorm换成SyncBatchNorm测试时一定要切到model.eval()让BN走running统计而不是当前batch统计。记录实验结果时把batch size写进配置文件名这是基本规范。5.2 加小波分解后精度不升反降现象满怀期待把小波分解做出来换上去后OA掉了3~5个点还不如直接堆通道。原因结构组织出了偏差。比较常见的是把LL、LH、HL、HH四张子带直接按通道拼在一起喂给同一个卷积网络等于把所有通道混在一起重新学高频子带里的SAR噪声和非判别纹理被当成了强特征模型越训越偏。另一个常见问题是子带尺寸减半后直接用插值上采样还原丢失了高频结构本身。解决LL走主干高频子带走辅助分支只在深层特征融合对高频分支单独加dropout让网络不要把高频子带当唯一判据分解只做level1尺寸减半对多数patch已经足够。改完后重新跑一轮消融对比加不加小波的差距别凭感觉调。5.3 光学和SAR的标签错位几十米现象分类结果的整体指标看着正常但放大看地物边缘全是锯齿建筑轮廓对不齐道路断断续续边界错误集中。原因多源影像没有做严格空间对齐。光学的投影坐标和SAR坐标系如果只是“看起来差不多”在山区或城区变形会非常明显。标签通常是人工在光学影像上画的相当于标签坐标系和光学对齐而SAR影像要映射到同一坐标系里任何一方投影参数有偏差边界就是错位的结果。解决数据进模型前用GDAL或QGIS把所有影像重投影到同一UTM坐标、重采样到同一分辨率、按矢量边界裁切。做完后在QGIS里把两种源叠加成半透明图层肉眼检查道路和桥梁边缘是否重合这一步比任何代码都可靠。位置不对的先手动校准别急着往下走。5.4 训练Loss降到很低mIoU却上不去现象训练曲线loss确实在稳步下降但验证集mIoU或Kappa卡住甚至不如随机初始化的小模型。原因多源遥感场景类别极度不平衡时Focal Loss调制不够模型可以把多数类学得很好但多数类占loss大头少数类的误差被淹没了。另一个可能是测试集本身采样不均衡评估指标被大类别主导。解决改用FocalLoss并把alpha按类别频率反比设置训练时用WeightedRandomSampler对多数类降采样、少数类升采样评估时坚持看AA和Kappa并打印混淆矩阵找到被吞掉的是水体还是道路再回数据采样层针对性处理。5.5 SAR输入没做对数变换第一轮训练就爆数值现象loss第一轮直接nan或者模型很快收敛到全0.5的类别输出怎么调学习率都没用。原因SAR图像原始值是后向散射强度或幅度动态范围从0到几千甚至几万光学反射率是0~1的归一化值。SAR没做对数变换batch里几个强散射体就能把梯度拉爆梯度在饱和区反复摆动。解决在标准化之前先对SAR强度做log1p或转dB处理dB公式是10 * log10(x 1e-6)然后再做均值方差标准化可视化确认转换后直方图接近单峰高斯而不是长尾分布。这一行预处理决定后面所有训练是否有效血泪经验。6. 验证模型是否真的“看了该看的地方”三个检查方法模型训完先别急着写论文或交付做三个验证再下结论。6.1 把空间注意力权重打回原图训练完第一件事不是看OA而是把平行注意力模块里的空间权重图sa_map导出来归一化后叠加到光学影像上。用一个hook把forward里的sa_map截下来保存成热力图即可。合理的结果是注意力集中在道路、水系、建筑轮廓这些有语义的边界上如果热力图散成一团噪点或者集中到影像角落阴影里那模型学到的是伪特征而不是地物语义。6.2 用Grad-CAM看分类决策区域空间注意力只反映模块内部筛选结果分类头怎么决策还要看Grad-CAM。代码核心十行左右def grad_cam(model, x, target_class): feature model.backbone(x) logit model.head(feature)[0, target_class] grad torch.autograd.grad(logit, feature)[0] weights grad.mean(dim(2, 3), keepdimTrue) return torch.relu((weights * feature).sum(dim1, keepdimTrue))我会分别对光学输入、SAR输入、双源融合三种输入跑同一目标类别对比响应区域。如果融合后响应区比单源更集中说明多源融合确实在帮模型定位如果两张源明显冲突那大概率是数据对齐阶段还有问题。6.3 跑一张完整的消融表所有验证手段都比不上一张消融表有说服力。把四组配置各跑三遍固定随机种子配置OAAAKappa单源光学基线.........单源SAR基线.........多源通道堆叠.........多源小波平行注意力.........这张表同时回答了两件事多源比单源涨了多少小波加平行注意力在多源这条增量里拿了多少。如果后一项没有明显提升说明卡点还在数据质量上宁可回头修对齐也别继续堆模块。我的习惯是每次迭代都把空间注意力图和Grad-CAM存进实验记录和消融表放在一起。指标可以骗人可视化骗不了人——注意力在哪儿、什么时候学歪了一眼就能看出来。希望这些方法能在你的多源遥感分类工程里派上用场少走我走过的弯路。本文还有配套的精品资源点击获取
返回列表