ARTICLE DETAIL

资讯详情

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

基于TensorFlow 2.3与MobileNetV2的花卉识别系统设计与实现

基于TensorFlow 2.3与MobileNetV2的花卉识别系统设计与实现 简介本资源是一份面向高校计算机、人工智能及相关专业本科生的期末大作业级花卉图像识别系统基于Python与TensorFlow 2.3框架开发聚焦K12及入门级深度学习实践场景解决多类别花卉图像分类与可视化识别问题。压缩包共27个文件涵盖5个核心Python脚本含数据划分、模型训练、测试推理与GUI界面、2个训练完成的.h5模型文件、9张示例图像及5个标注XML文件辅以requirements.txt环境配置、readme.md项目说明与data_split.py等工具脚本整体结构清晰、模块职责明确便于理解CNN建模全流程。资源包大小为239.31MB已获导师指导并通过高分验收下载解压后可直接运行无需修改代码或配置。目前已有248人学习下载提供完整可运行工程、97%左右实测识别准确率、简洁美观的图形界面及规范的数据预处理逻辑是课程设计、AI入门实践与深度学习项目复现的理想参考范例。 期末大作业选了个花卉识别系统用的是Python TensorFlow 2.3这套组合。从选题、搭环境到最终跑通GUI演示前前后后花了三周左右中间踩了不少坑也总结出一些对新手比较友好的做法。这篇文章就完整记录一下这个系统的设计与实现过程从数据集处理、模型构建、训练调优到界面封装全部覆盖。如果你也在做类似的图像分类期末项目或者想用TensorFlow 2.3快速搭一个能演示的识别系统这份内容可以直接参考着一步步照做。为什么会写这个主题因为花卉识别在图像分类里属于比较典型的多分类任务类间相似度高、背景干扰多既不会简单到没东西可写也不至于难到做不完。而且数据集可以直接用TensorFlow官方提供的tf_flowers省去了自己爬图、清洗的麻烦。整个项目的技术栈也很有代表性深度学习、迁移学习、图像预处理、GUI交互这些做完之后写到简历上都是实打实的亮点。1. 项目概述与整体设计思路1.1 期末大作业的项目目标拆解这个系统的核心目标很明确输入一张花卉图片系统能告诉你是哪一种花。项目用的是TensorFlow官方flowers数据集包含5个类别雏菊daisy、蒲公英dandelion、玫瑰rose、向日葵sunflower、郁金香tulip。每类大约800张左右图片大小不一有背景干扰是一个很真实的多分类任务。期末大作业和一般的研究课题不一样评审老师最看重三件事第一技术栈是否合理、是否能讲清楚第二系统是否完整可用而不是只交一个训练脚本第三答辩时能不能现场展示效果。所以我在设计这个项目时给自己定了几个硬性要求识别准确率不能太低至少85%以上否则演示效果会很难看必须有一个图形界面不能只停留在命令行输出结果代码结构要清晰方便答辩时现场讲解和回答提问训练时间可控普通笔记本电脑能跑完不能因为算力不够导致项目烂尾基于这几个要求技术方案基本上就锁定了TensorFlow 2.3做训练和推理MobileNetV2做迁移学习tkinter做桌面GUI。这套组合最大的优势是在保证精度的前提下训练速度和资源占用都非常友好。1.2 技术选型与方案论证先说DeepLearning框架的选择。TensorFlow 2.3和PyTorch都能做这个项目但我最终选了TensorFlow 2.3主要原因是它在Keras API的加持下对初学者非常友好。一个模型的搭建、编译、训练、保存几乎不需要关心底层的数据流图前后端分离这些复杂概念几行代码就能跑通。期末项目最重要的目的是展示完整的任务流程而不是展示你手动实现了多少底层细节所以用TensorFlow 2.3能把精力集中在数据处理和模型效果上。再说网络结构。这个项目是典型的图像分类任务从头训练一个CNN当然可行但效果通常不理想。原因很简单数据集只有约3700张图片对深度学习模型来说属于小规模数据从零训练精度很难达到80%以上而且训练时间非常长。所以我用了迁移学习方案选择MobileNetV2作为骨干网络。选择它的原因有三个第一MobileNetV2在ImageNet上预训练过已经学会了通用的边缘、纹理、形状等特征第二模型非常轻量参数量远小于ResNet、VGG这些训练和推理速度快第三模型的分类器部分可以自由替换非常适合做自定义类别的分类任务。GUI界面使用的tkinter也是经过权衡的。可能有人会推荐PyQt5或Web前端但对期末作业来说tkinter是Python自带的库不需要额外安装依赖打包部署也方便展示效果完全够用。1.3 系统整体流程整个系统的流程分成两个阶段训练阶段和推理阶段。训练阶段做的事情是加载数据集、数据增强、构建模型、训练模型、保存模型文件。这个阶段的主要产出是一个.h5格式的模型文件里面保存了训练好的网络权重。推理阶段做的事情是加载模型文件、读取图片、预处理、模型预测、展示结果。这个阶段是在GUI中完成的用户点击按钮选择图片系统自动完成从图片到识别结果的整个过程。两个阶段的核心逻辑是独立分开的中间通过模型文件衔接。这个设计有好处训练脚本和识别脚本解耦答辩时可以分别讲解不会因为界面代码和训练代码混在一起导致逻辑混乱。2. 数据集准备与图像预处理2.1 数据集选型与下载方式花卉识别的数据集有好几个选择除了自己爬取图片最常用的公开数据集是Oxford 102 Flowers和TensorFlow官方的tf_flowers。我选tf_flowers的原因很直接它可以直接通过TensorFlow Datasets拉取不需要手动下载、解压和组织目录结构对期末项目来说可以节省大量时间。而且它包含了5个类别类别数量适中既有多分类任务的说服力又不会让训练时间变得不可控。加载tf_flowers数据集的代码很简单import tensorflow_datasets as tfds # 下载并加载tf_flowers数据集 dataset, info tfds.load( tf_flowers, splittrain, as_supervisedTrue, with_infoTrue ) print(info.splits[train].num_examples) # 训练样本总数 print(info.features[label].num_classes) # 类别数数据集会自动下载到~/tensorflow_datasets目录下第一次运行需要联网下载大约200多MB。如果你在学校的网络环境里建议提前下载好放在本地后面的事就比较顺。你可能会问为什么不自己爬图我个人的建议是期末大作业尽量不要把时间浪费在数据采集和数据清洗上。爬下来的图片往往有很多无效样本分辨率参差不齐还需要手工筛选和重命名工作量非常大。直接用现成数据集把精力留给模型调优和系统设计性价比更高。2.2 图像增强与数据加载这个数据集原始图片的分辨率并不统一有的大有的小。而MobileNetV2的输入是224x224所以必须把所有图片统一resize到这个尺寸。直接resize会丢失很多细节而且这么小的数据集直接喂给模型容易过拟合所以在处理时需要用图像增强来做数据扩增。这就是ImageDataGenerator发挥作用的地方。它能在训练时实时对图片做随机变换比如旋转、平移、翻转、缩放等相当于把数据集凭空放大了好几倍让模型看到更多样化的输入泛化能力自然更强。生成训练集和验证集数据流的核心代码如下import tensorflow as tf from tensorflow.keras.preprocessing.image import ImageDataGenerator # 训练集增强配置 train_datagen ImageDataGenerator( rescale1.0/255.0, rotation_range30, width_shift_range0.2, height_shift_range0.2, shear_range0.2, zoom_range0.2, horizontal_flipTrue, fill_modenearest, validation_split0.2 ) # 验证集只做归一化不做增强 val_datagen ImageDataGenerator( rescale1.0/255.0, validation_split0.2 ) # 构造数据流 train_generator train_datagen.flow_from_directory( data_dir, target_size(224, 224), batch_size32, class_modecategorical, subsettraining, shuffleTrue ) validation_generator val_datagen.flow_from_directory( data_dir, target_size(224, 224), batch_size32, class_modecategorical, subsetvalidation )这里有两个关键的细节值得注意。细节一是rescale1.0/255.0。像素值从0到255的范围缩放到0到1之间这是神经网络训练的标准预处理步骤不归一化的话数值范围过大会导致梯度更新不稳定模型很难收敛。这个操作在训练和推理阶段必须保持一致否则模型预测结果会出问题后面讲部署时会再提到。细节二是迁移学习任务中的数据增强参数不能设置得太激进。我最初把rotation_range设置为180度结果准确率反而下降了。原因是花卉图片有方向性旋转180度后的图像已经不符合真实场景强行让模型学习这种无意义的变换只会带偏特征提取。30度左右的旋转加上随机翻转已经是比较合理的配置。2.3 数据集划分与标签映射train_generator和validation_generator都通过flow_from_directory生成这种方式要求数据按目录组织。你需要把图片按照类别放在不同的文件夹下结构大概是这样的flower_dataset/ daisy/ image1.jpg image2.jpg dandelion/ ... rose/ ... sunflower/ ... tulip/ ...flow_from_directory会自动把文件夹名称作为类别标签同时在内部建立标签和索引的映射关系。验证集默认使用20%的数据我尝试过10%和30%的划分最终保持20%是因为在总体样本量不大的情况下太少验证数据会导致评估指标方差大太多则浪费训练样本。还有一个需要注意的点数据集的类别是打乱的。tfds.load返回的数据集顺序是随机的如果直接用前80%做训练、后20%做验证可能某个类别的图片全部集中在一段里造成验证集分布不均。所以我在加载数据后先做了整体shuffle再按顺序取训练和验证部分保证每个类别的图片在训练集和验证集中都有一定比例出现。3. 模型构建与训练调优3.1 迁移学习原理与骨干网络选择要理解迁移学习可以先打个比方一个精通素描的画家你让他去学油画国画他不需要从零开始学怎么握笔、怎么构图只需要学习油画特有的笔触和色彩就行了。MobileNetV2就是那个精通基础绘画技巧的画家它在ImageNet数据集上见过一千万张图片已经学会了用卷积核提取边缘、纹理、形状等通用特征。在我们这个场景下需要的是利用MobileNetV2的眼力来提取花卉图片的视觉特征然后在这个基础上加一层新的分类器让它学会区分5种花卉。这样既节省了训练时间又能在小数据集上取得不错的精度。MobileNetV2相比其他预训练模型最明显的优势是轻量。它使用了深度可分离卷积Depthwise Separable Convolution参数量大约是ResNet50的十分之一。这意味着训练和推理时占用显存更少CPU也能勉强跑动对学生党用笔记本做项目非常友好。3.2 模型搭建过程模型搭建的核心思路是固定MobileNetV2的主体部分只替换最后的分类层。这里有两种策略一是把所有层都冻结即权重要不更新只训练新增的全连接层二是不冻结对整个模型做微调。我采用了两阶段训练策略先冻结主干网络训练分类层再解冻部分层进行微调。第一阶段模型定义代码如下import tensorflow as tf from tensorflow.keras import layers, models from tensorflow.keras.applications import MobileNetV2 # 加载预训练模型不包括顶部分类器 base_model MobileNetV2( weightsimagenet, include_topFalse, input_shape(224, 224, 3) ) # 冻结主干网络 base_model.trainable False # 构建新模型 model models.Sequential([ base_model, layers.GlobalAveragePooling2D(), layers.Dropout(0.3), layers.Dense(5, activationsoftmax) ]) model.summary()GlobalAveragePooling2D的作用是将MobileNetV2输出的特征图压缩成一个一维向量。相比直接Flatten它的参数量更少且天然具有防过拟合的效果在迁移学习中几乎是标配。Flatten会把7x7的特征图展平成49个值加上前面的卷积层输出通道数很多参数量会爆炸。GlobalAveragePooling则直接对每个通道求平均非常巧妙。Dropout(0.3)的作用是随机丢弃30%的神经元连接防止模型对训练数据记忆过深。这个参数我调试过过小比如0.1效果不明显过大比如0.5则会让模型欠拟合。0.3在5分类小数据集上是一个比较理想的折中值。模型的编译配置是这样的model.compile( optimizertf.keras.optimizers.Adam(learning_rate0.001), losscategorical_crossentropy, metrics[accuracy] )为什么用categorical_crossentropy作为损失函数因为它适用于多分类问题配合softmax输出层能让模型输出一个概率分布比如[0.8, 0.05, 0.1, 0.02, 0.03]表示五个类别的置信度。训练时计算预测概率和真实标签的交叉熵数值越小说明预测越接近真实情况。3.3 训练过程与超参数实验训练过程分两个阶段。第一阶段冻结主干网络只训练分类头。这一步的收敛速度非常快因为主干网络的参数不动只有新加的Dense层在更新。我用batch_size32、学习率0.001训练20个epoch。以我的笔记本为例一阶段耗时大约10分钟。第二阶段是微调。解冻MobileNetV2的高层特征提取部分用一个较小的学习率对整个网络做联合调整。为什么要解冻因为ImageNet预训练模型是在通用物体上训练出来的虽然底层特征边缘、纹理等通用性很强但高层特征和花卉图像分布还是会有些偏差。微调就是让高层特征更适应花卉数据。这一阶段学习率一定要调小比如0.0001否则很容易破坏已经学好的特征。base_model.trainable True # 冻结前100层只微调后面部分层 for layer in base_model.layers[:100]: layer.trainable False model.compile( optimizertf.keras.optimizers.Adam(learning_rate0.0001), losscategorical_crossentropy, metrics[accuracy] ) early_stop tf.keras.callbacks.EarlyStopping( monitorval_loss, patience5, restore_best_weightsTrue ) model_checkpoint tf.keras.callbacks.ModelCheckpoint( flower_model.h5, monitorval_accuracy, save_best_onlyTrue, modemax ) history model.fit( train_generator, steps_per_epochtrain_generator.samples // 32, validation_datavalidation_generator, validation_stepsvalidation_generator.samples // 32, epochs30, callbacks[early_stop, model_checkpoint] )为什么冻结前100层因为MobileNetV2共153层前100层主要是浅层特征具有极高的通用性不同数据集之间变化不大。而最后约50层是深层特征更贴近ImageNet的类别语义需要针对花卉数据进行调整。我试过两种方案冻结前100层和完全不冻结。完全不冻结在小数据集上过拟合很明显训练准确率接近100%但验证准确率只有85%左右。冻结前100层的方案最终验证集准确率稳定在92%左右。EarlyStopping回调解决的是一个实际问题不知道最优epoch数是几。设置patience5的意思是如果连续5个epoch验证集损失没有下降就停止训练并恢复到最佳权重。这套机制能有效防止过拟合避免你盯着训练曲线反复试探。整个训练过程的超参数配置汇总如下参数第一阶段第二阶段学习率0.0010.0001Batch Size3232Epochs2030是否冻结主干全部冻结前100层冻结验证集比例20%20%训练完成后最终验证集准确率大约在92%到94%之间测试集准确率在89%左右。不同的随机种子会带来小幅波动但整体效果足够期末演示使用。4. 识别系统界面与功能实现4.1 GUI架构设计模型训练好之后接下来就是把这个模型封装成普通人能用的系统。我选择的是tkinter原因前面说过它是Python自带的GUI库不需要额外安装任何依赖。GUI界面分成三个区域顶部是标题和导入按钮中间是图片展示区底部是识别结果区。整体交互流程是点击“选择图片”按钮弹出文件选择对话框选中图片后预览在画布上再点击“识别”按钮下方显示识别结果和各类别置信度。界面布局的主要代码如下import tkinter as tk from tkinter import filedialog from tkinter import messagebox from PIL import Image, ImageTk class FlowerApp: def __init__(self, window): self.window window self.window.title(花卉识别系统) self.window.geometry(500x600) self.model load_model(flower_model.h5) self.class_names [雏菊, 蒲公英, 玫瑰, 向日葵, 郁金香] # 选择图片按钮 self.btn_choose tk.Button( self.window, text选择图片, font(微软雅黑, 14), commandself.choose_image ) self.btn_choose.pack(pady10) # 图片展示画布 self.label_image tk.Label(self.window) self.label_image.pack(pady10) # 识别按钮 self.btn_predict tk.Button( self.window, text开始识别, font(微软雅黑, 14), commandself.predict_image ) self.btn_predict.pack(pady10) # 结果显示标签 self.label_result tk.Label( self.window, text请选择一张花卉图片进行识别, font(微软雅黑, 12) ) self.label_result.pack(pady10)界面代码的逻辑很直白没有需要特别设计的架构。有一点要注意的是tkinter在Windows上默认字体对中文的显示支持不够好建议统一设置成微软雅黑之类的常见中文字体避免演示时出现乱码或者排版异常。4.2 模型加载与推理逻辑模型加载和推理是这个系统最核心的部分。因为模型是训练脚本里的产物推理时必须保证输入的预处理方式和训练时完全一致。这里说的预处理包括三件事图片尺寸调整为224x224、像素值除以255归一化、转换为模型要求的张量格式。推理部分的代码是这样的import numpy as np from tensorflow.keras.preprocessing import image from tensorflow.keras.models import load_model def predict_flower(self, img_path): # 加载并调整图片尺寸 img image.load_img(img_path, target_size(224, 224)) # 转成数组并归一化 img_array image.img_to_array(img) img_array np.expand_dims(img_array, axis0) img_array img_array / 255.0 # 模型预测 predictions self.model.predict(img_array, verbose0) pred_index np.argmax(predictions[0]) confidence np.max(predictions[0]) return self.class_names[pred_index], confidence, predictions[0]image.load_img会自动把图片resize到指定尺寸这一步把resize细节封装好了。np.expand_dims给图片增加一个维度把3维图片变成4维张量因为模型期望的输入是(batch_size, height, width, channels)一张图片对应的batch_size就是1。需要特别强调的是归一化这步。我在调试时遇到过一个问题在训练时用了rescale1.0/255.0做归一化推理时却忘了对输入图片做同样处理结果预测结果非常离谱几乎是随机乱猜。查了半天才发现是这个问题。所以训练和推理的数据预处理必须保持一致这是图像分类系统里最容易踩的坑之一。4.3 批量识别与结果展示除了单张识别我还加了一个批量识别的功能。用户可以选择一个文件夹系统自动对该文件夹下的所有图片进行识别并生成一个结果列表。这个功能不是期末作业的硬性要求但加上之后答辩时效果很好能体现系统的完整性。批量识别的逻辑并不复杂可以复用单张推理的代码import os def batch_predict(self, folder_path): results [] for filename in os.listdir(folder_path): if filename.lower().endswith((.jpg, .png, .jpeg)): img_path os.path.join(folder_path, filename) pred_class, confidence, _ self.predict_flower(img_path) results.append((filename, pred_class, float(confidence))) return results批量识别结果展示时我用了一个文本框加滚动条每条记录占一行格式是图片名 --- 识别结果 --- 置信度。这能很直观地看到模型对不同图片的判断情况也方便在答辩现场快速展示模型的整体识别能力。5. 测试复盘与效果评估5.1 测试集结果与混淆矩阵模型训练完成后我对验证集做了一个比较完整的评估。整体准确率约92.5%在5分类任务中算不错的成绩。但看整体准确率还不够还需要看每个类别的分布情况。五类的详细表现如下类别测试样本数正确识别数准确率主要混淆对象雏菊17516091.4%郁金香蒲公英17816994.9%雏菊玫瑰16715592.8%郁金香向日葵16415996.9%雏菊郁金香17014585.3%玫瑰、雏菊从表格可以看出郁金香的准确率最低这和郁金香本身形态多变有关。郁金香有杯状花型、百合花型、流苏花型等不同品种之间的外观差异甚至比郁金香和玫瑰的差异还大模型在区分郁金香和玫瑰这种高相似度组合时容易出错。我用sklearn的confusion_matrix可以直观看到这些混淆关系。如果你在答辩中能展示混淆矩阵并解释为什么会出现这些错误会显得你对模型的理解更深而不是只跑通了一个流程就了事。5.2 实际场景验证与局限训练集里的图片基本都是近景、单花主体、背景相对简单的。为了测试系统的真实可用性我在网络上找了一些不同场景下的花卉图片做测试包括远景花丛、室内盆栽、逆光拍摄等。结果有点意外背景干净的单花照片基本都能正确识别但背景杂乱或者多花混在一起的照片错误率明显上升。这其实暴露了模型的一个局限——它学习的其实不仅仅是花的特征还包括了一部分背景信息。虽然训练时做了图像增强但增强的强度不能无限制提升否则模型会过拟合到增强后的假样本上。另外还发现一个规律如果测试图片的拍摄角度和训练集差异很大比如仰拍郁金香模型容易给出低置信度的预测。这是所有图像分类模型的通病解决思路要么是收集更多角度和场景的样本扩充数据集要么是在训练时加大图像增强的范围。但期末大作业的时间有限能做到现有程度已经足够这部分可以作为答辩时的展望讲出来。6. 常见问题与排查技巧实录6.1 环境配置阶段的问题TensorFlow 2.3的环境配置是大作业第一个坎。很多人卡在这里的时候会以为是自己的代码有问题其实大部分是版本兼容性问题。我总结了几类最常见的坑。第一是Python版本与TensorFlow版本不匹配。TensorFlow 2.3官方支持Python 3.5到3.8如果你装了Python 3.9以上版本pip install tensorflow2.3会自动去找一个兼容版本可能会因为找不到而报错。解决方案就是重装Python 3.8。第二是pip安装慢的问题。如果直接pip install tensorflow在国内网络环境下通常会卡住或者非常慢。可以在安装命令后面加上清华源镜像pip install tensorflow2.3 -i https://pypi.tuna.tsinghua.edu.cn/simple第三是CUDA和cuDNN版本的对应关系。如果电脑有NVIDIA显卡TensorFlow 2.3需要CUDA 10.1和cuDNN 7.6。版本不对导入tensorflow的时候就会报错找不到动态链接库。我的建议是如果电脑没有独立显卡干脆直接用CPU版本。这个项目用的MobileNetV2很轻量CPU训练20个epoch也就十几分钟没必要跟CUDA死磕。6.2 训练阶段的典型问题训练过程中最常遇到的问题就是loss不下降。我一开始用Adam默认学习率0.001训练但发现loss下降很慢验证集准确率一直停留在20%左右相当于随机猜。排查之后发现问题出在迁移学习阶段从张量输入到预训练模型之间没有做归一化。预训练模型在ImageNet训练时使用的是特定的归一化方法MobileNetV2用的是(-1, 1)的归一化。我在ImageDataGenerator里用的rescale1.0/255.0是[0,1]的归一化两者不一致导致模型输入分布不对效果自然差。后来我换成了MobileNetV2.preprocess_input来处理输入或者手动把像素值归一化到(-1,1)loss才正常下降。这个问题很隐蔽网上大部分教程用的rescale都是1.0/255.0但它在MobileNetV2上其实不是最优选择。另一个典型问题是过拟合。训练集准确率很快到98%以上但验证集上只有75%左右说明模型把训练集的细节记住了而不是学到了泛化规律。对我这个项目来说缓解过拟合主要靠三种手段Dropout、早停、微调阶段冻结部分层。其中最有用的其实是EarlyStopping它能让你在验证集性能最好的那个点停下来。6.3 部署推理阶段的坑模型部署到GUI之后还会遇到一类问题就是预测结果和训练时的结果不一致。这个坑我在前面已经提过核心就是推理时的预处理和训练时不一致。除了归一化之外还有一个容易被忽略的细节图片的通道顺序。训练时flow_from_directory从文件读取的图片默认是RGB三通道而某些库读取时会返回BGR顺序。如果你用OpenCV的cv2.imread读取图片它的排列顺序是BGR蓝绿红直接喂给模型预测会出现颜色错乱导致识别错误。解决方案是用tensorflow.keras.preprocessing.image.load_img或cv2.cvtColor转一下确保喂给模型的图片是RGB格式。还有一个细节是标签对齐问题。训练时flow_from_directory自动生成标签映射这个映射顺序取决于文件夹名称的字母排序。我第一次启动GUI时发现向日葵的图片识别出来的结果总是郁金香排查了很久才发现是标签映射顺序搞反了。所以训练时要用train_generator.class_indices把映射打印出来推理时直接用同一份映射不要凭感觉手写。print(train_generator.class_indices) # 输出示例{daisy: 0, dandelion: 1, rose: 2, sunflower: 3, tulip: 4}每次训练完模型都先打印一次class_indices和GUI里的class_names做对照确认无误再打包截图这样能避免很多哭笑不得的小问题。最后再分享一个小技巧如果演示现场的网络环境不稳定不要把模型文件放在load_model时从云端加载。一定要放在本地路径最好和GUI代码在同一个目录下。另外模型文件大约12MB左右可以直接通过微信或者U盘拷到演示机器上不依赖任何外部资源现场演示的容错率会高很多。我做完这个项目的最大体会是期末大作业拼的往往不是模型精度有多高而是整个流程能不能顺畅走通、每个环节的问题能不能讲清楚。把训练、评估、部署这条线完整跑一遍收获远大于闷头调参。本文还有配套的精品资源点击获取
返回列表