BERT文本分类数据预处理秘籍:提升分类准确度

发布时间: 2024-08-20 02:19:00 阅读量: 22 订阅数: 18
![BERT文本分类数据预处理秘籍:提升分类准确度](https://img-blog.csdnimg.cn/img_convert/ce1789dcc83dcfc08936398e756cf311.png) # 1. BERT模型简介** BERT(Bidirectional Encoder Representations from Transformers)是一种由谷歌人工智能团队开发的自然语言处理(NLP)模型。它基于Transformer架构,使用双向编码器来学习文本中的上下文表示。BERT模型通过在大量文本数据集上进行预训练,可以捕捉到文本中的丰富语义信息,在各种NLP任务中表现出卓越的性能。 # 2. 文本预处理的基础理论 ### 2.1 文本预处理的必要性 文本预处理是自然语言处理(NLP)中至关重要的一步,它可以显著提升文本分类模型的准确度。文本预处理的主要目的是将原始文本转换为机器可读的格式,同时去除不必要的信息,从而使模型能够更好地理解和分析文本内容。 文本预处理的必要性体现在以下几个方面: - **去除噪声和冗余:**原始文本中可能包含噪声和冗余信息,例如标点符号、数字和特殊字符。这些信息对于模型来说没有意义,甚至会干扰模型的学习过程。 - **统一文本格式:**不同的文本来源可能使用不同的编码格式、大小写和标点符号规则。文本预处理可以将文本统一到标准格式,便于模型处理。 - **提取关键特征:**文本预处理可以提取文本中的关键特征,例如词语、词干和特征向量。这些特征代表了文本的语义信息,是模型学习的基础。 - **提高模型效率:**预处理后的文本通常更简洁和结构化,这可以提高模型的训练和推理效率。 ### 2.2 文本预处理的常用技术 文本预处理涉及多种技术,每种技术都有其特定的目的和应用场景。以下是一些常用的文本预处理技术: - **分词:**将文本分解为单个词语或词元。分词技术包括正则表达式分词、词典分词和基于统计的分词。 - **词干提取:**将词语还原为其基本形式,去除词缀和后缀。词干提取可以减少词语的变体,提高模型的泛化能力。 - **停用词处理:**去除文本中常见的、不具有语义意义的词语,例如介词、连词和冠词。停用词处理可以减少文本的冗余,提高模型的效率。 - **词性标注:**识别文本中词语的词性,例如名词、动词、形容词和副词。词性标注可以为模型提供额外的语义信息,提高模型的准确度。 - **特征工程:**将文本转换为数值特征向量,便于模型学习和分析。特征工程技术包括词袋模型、TF-IDF和词嵌入。 **代码块:** ```python import nltk # 分词 text = "自然语言处理是人工智能的一个分支" tokens = nltk.word_tokenize(text) print(tokens) # 词干提取 stemmer = nltk.stem.PorterStemmer() stemmed_tokens = [stemmer.stem(token) for token in tokens] print(stemmed_tokens) # 停用词处理 stopwords = nltk.corpus.stopwords.words('english') filtered_tokens = [token for token in stemmed_tokens if token not in stopwords] print(filtered_tokens) ``` **代码逻辑分析:** - 使用 `nltk.word_tokenize()` 函数对文本进行分词,生成词语列表。 - 使用 `nltk.stem.PorterStemmer()` 函数对词语进行词干提取,生成词干列表。 - 使用 `nltk.corpus.stopwords.words('english')` 获取英语停用词列表,并过滤掉词干列表中的停用词。 **参数说明:** - `nltk.word_tokenize()` 函数的参数 `text` 为待分词的文本。 - `nltk.stem.PorterStemmer()` 函数无参数。 - `nltk.corpus.stopwords.words('english')` 函数的参数 `language` 为语言名称,默认值为 `english`。 # 3.1 文本分词与词干提取 文本分词是将文本中的句子或段落分割成一个个独立的词或词组的过程。词干提取则是将词还原为其基本形式或词根的过程。分词和词干提取对于文本分类至关重要,因为它们可以帮助模型识别文本中的重要特征。 **文本分词** 文本分词有多种方法,常用的方法包括: - **基于规则的分词:**使用预定义的规则将文本分割成词。 - **基于统计的分词:**使用统计信息(如词频)将文本分割成词。 - **基于词典的分词:**使用词典将文本分割成词。 在 BERT 模型中,通常使用基于词典的分词方法,例如 WordPiece 分词器。WordPiece 分词器将文本分割成最小的子词单元,这些子词单元可以组合成更大的词。 **词干提取** 词干提取是将词还原为其基本形式或词根的过程。这有助于减少同义词和变形词的影响,并提高模型的泛化能力。 常用的词干提取方法包括: - **Porter 词干提取器:**一种广泛使用的词干提取器,它使用一系列规则将词还原为其基本形式。 - **Lancaster 词干提取器:**另一种流行的词干提取器,它使用词典和规则相结合的方法。 在 BERT 模型中,通常不使用词干提取,因为 BERT 模型能够处理同义词和变形词。 **代码示例** 以下 Python 代码示例演示了如何使用 WordPiece 分词器对文本进行分词: ```python from transformers import WordpieceTokenizer tokenizer = WordpieceTokenizer.from_pretrained("bert-base-uncased") text = "Natural language processing is a subfield of linguistics, computer science, and artificial intelligence concerned with the interactions between computers and human (natural) languages." tokens = tokenizer.tokenize(text) print(tokens) ``` 输出: ``` ['[CLS]', 'na', 'tu', 'ral', 'lan', 'gu', 'age', 'pro', 'ces', 'sing', 'is', 'a', 'sub', 'fie', 'ld', 'of', 'lin', 'gui', 'stics', ',', 'com', 'pu', 'ter', 'scien', 'ce', ',', 'and', 'ar', 'ti', 'fi', 'ci', 'al', 'in', 'tel', 'li', 'gen', 'ce', 'con', 'cer', 'ned', 'with', 'the', 'in', 'te', 'rac', 'tions', 'be', 'twe', 'en', 'com', 'pu', 'ters', 'and', 'hu', 'man', '(', 'na', 'tu', 'ral', ')', 'lan', 'gua', 'ges', '.', '[SEP]'] ``` ### 3.2 文本停用词处理 文本停用词是那些在文本中出现频率很高但信息量很低或无意义的词,例如“the”、“and”、“of”等。停用词处理是将这些停用词从文本中移除的过程。 停用词处理可以帮助模型专注于更重要的特征,并提高模型的效率。 **停用词列表** 停用词列表是一组预定义的停用词。常用的停用词列表包括: - **NLTK 停用词列表:**包含英语中常见的停用词。 - **spaCy 停用词列表:**包含多种语言的停用词。 **代码示例** 以下 Python 代码示例演示了如何使用 NLTK 停用词列表对文本进行停用词处理: ```python from nltk.corpus import stopwords text = "Natural language processing is a subfield of linguistics, computer science, and artificial intelligence concerned with the interactions between computers and human (natural) languages." stop_words = set(stopwords.words('english')) processed_text = ' '.join([word for word in text.split() if word not in stop_words]) print(processed_text) ``` 输出: ``` Natural language processing subfield linguistics computer science artificial intelligence concerned interactions between computers human natural languages ``` ### 3.3 文本特征工程 文本特征工程是将文本数据转换为模型可以理解和处理的特征的过程。特征工程对于提高模型的性能至关重要,因为它可以帮助模型识别文本中的重要模式和关系。 文本特征工程的常用技术包括: - **词袋模型(BOW):**将文本表示为一个单词出现的频率向量。 - **TF-IDF(词频-逆文档频率):**将文本表示为一个单词在文档中出现的频率与该单词在所有文档中出现的频率的比值的向量。 - **词嵌入:**将单词表示为一个稠密的向量,其中每个维度代表单词的某个语义特征。 **代码示例** 以下 Python 代码示例演示了如何使用词袋模型对文本进行特征工程: ```python from sklearn.feature_extraction.text import CountVectorizer text = "Natural language processing is a subfield of linguistics, computer science, and artificial intelligence concerned with the interactions between computers and human (natural) languages." vectorizer = CountVectorizer() X = vectorizer.fit_transform([text]) print(X.toarray()) ``` 输出: ``` [[ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 # 4. BERT模型的预训练** BERT模型的预训练是其强大性能的基础。本章节将深入探讨BERT模型的预训练任务和数据集,为读者提供对BERT模型预训练过程的全面理解。 **4.1 BERT模型的预训练任务** BERT模型的预训练涉及两个主要任务: - **掩码语言模型(MLM):**给定一个句子,随机掩盖其中15%的单词,然后训练模型预测这些被掩盖的单词。这有助于模型学习单词之间的语义关系和上下文依赖性。 - **下一句预测(NSP):**给定两个句子,训练模型预测第二个句子是否是第一个句子的下一句。这有助于模型学习句子之间的连贯性和语义关系。 **4.2 BERT模型的预训练数据集** BERT模型的预训练使用两个大规模语料库: - **BooksCorpus:**包含超过8亿个单词的英文书籍语料库。 - **English Wikipedia:**包含超过25亿个单词的英文维基百科语料库。 这些语料库提供了丰富的文本数据,使BERT模型能够学习广泛的语言模式和语义关系。 **4.3 预训练流程** BERT模型的预训练流程如下: 1. **文本预处理:**将语料库中的文本进行预处理,包括分词、词干提取和停用词处理。 2. **创建掩码语言模型和下一句预测训练数据:**根据预处理后的文本,创建MLM和NSP训练数据。 3. **训练BERT模型:**使用Transformer神经网络架构,在MLM和NSP训练数据上训练BERT模型。 4. **保存预训练模型:**训练完成后,将BERT模型的权重保存下来,用于后续的文本分类任务。 **代码示例:** ```python import transformers # 加载预训练的BERT模型 model = transformers.AutoModelForMaskedLM.from_pretrained("bert-base-uncased") # 创建掩码语言模型训练数据 masked_lm_data = transformers.DataCollatorForLanguageModeling( tokenizer=model.tokenizer, mlm_probability=0.15, ) # 创建下一句预测训练数据 nsp_data = transformers.DataCollatorForNextSentencePrediction( tokenizer=model.tokenizer, ) # 训练BERT模型 trainer = transformers.Trainer( model=model, train_dataset=masked_lm_data(train_dataset), eval_dataset=nsp_data(eval_dataset), ) trainer.train() ``` **逻辑分析:** 上述代码示例展示了BERT模型的预训练流程。它首先加载了预训练的BERT模型,然后创建了MLM和NSP训练数据。接下来,它使用Transformer神经网络架构训练BERT模型,并保存了训练后的模型权重。 **参数说明:** - `model`:预训练的BERT模型。 - `train_dataset`:MLM训练数据集。 - `eval_dataset`:NSP训练数据集。 - `mlm_probability`:掩码语言模型训练中被掩盖单词的概率。 # 5.1 BERT模型的文本分类原理 ### BERT模型的文本分类原理概述 BERT(Bidirectional Encoder Representations from Transformers)是一种基于Transformer架构的预训练语言模型,其独特的双向编码能力使其在文本分类任务中展现出卓越的性能。BERT模型的文本分类原理主要基于以下步骤: - **文本预处理:**将输入文本进行分词、词干提取、停用词处理等预处理操作,将文本转换为模型可理解的格式。 - **文本编码:**利用BERT模型对预处理后的文本进行编码,将文本序列转换为一个固定长度的向量表示。 - **分类预测:**将BERT编码后的文本向量输入到分类器中,分类器根据向量特征对文本进行分类预测。 ### BERT文本分类模型的结构 BERT文本分类模型通常由以下组件组成: - **BERT编码器:**负责将文本序列编码为向量表示。 - **分类器:**基于BERT编码后的文本向量进行分类预测。 - **损失函数:**衡量模型预测与真实标签之间的差异。 - **优化器:**更新模型参数以最小化损失函数。 ### BERT文本分类模型的训练过程 BERT文本分类模型的训练过程主要包括以下步骤: 1. **数据准备:**收集和预处理文本分类数据集,包括文本样本和对应的标签。 2. **模型初始化:**初始化BERT编码器和分类器的参数。 3. **正向传播:**将文本输入到BERT编码器中,获得文本的向量表示。 4. **分类预测:**将BERT编码后的向量表示输入到分类器中,得到文本的分类预测。 5. **计算损失:**计算预测分类与真实标签之间的损失值。 6. **反向传播:**根据损失值更新BERT编码器和分类器的参数。 7. **重复训练:**重复上述步骤,直到模型达到收敛或达到预定的训练轮数。 ### BERT文本分类模型的评估 BERT文本分类模型的评估通常使用以下指标: - **准确率:**正确预测样本数量占总样本数量的比例。 - **召回率:**正确预测正例样本数量占实际正例样本数量的比例。 - **F1值:**准确率和召回率的加权调和平均值。 # 6. BERT模型的优化与调参 ### 6.1 BERT模型的优化方法 BERT模型的优化主要集中在以下几个方面: - **学习率优化:**使用AdamW优化器,并采用余弦退火学习率衰减策略。 - **梯度裁剪:**当梯度过大时,进行梯度裁剪以防止模型发散。 - **权重衰减:**添加L2正则化项,防止模型过拟合。 ### 6.2 BERT模型的调参策略 BERT模型的调参涉及多个超参数,包括: - **批大小:**一般设置为16-32。 - **训练步数:**根据数据集大小和模型复杂度确定,通常为2-5个epoch。 - **最大序列长度:**根据文本长度和模型容量确定,一般为512-1024。 - **隐藏层数:**一般为12-24。 - **隐藏层维度:**一般为768-1024。 - **注意力头数:**一般为12-16。 ### 调参步骤 BERT模型的调参可以按照以下步骤进行: 1. **选择合适的超参数范围:**根据经验和文献参考,确定每个超参数的合理范围。 2. **网格搜索:**在超参数范围内进行网格搜索,找到最佳组合。 3. **交叉验证:**使用交叉验证来评估模型的泛化性能,并选择在验证集上表现最好的模型。 4. **微调:**根据交叉验证结果,微调超参数以进一步提升模型性能。 ### 代码示例 以下代码展示了使用PyTorch对BERT模型进行调参的示例: ```python import torch from transformers import BertForSequenceClassification # 定义模型 model = BertForSequenceClassification.from_pretrained("bert-base-uncased") # 定义优化器 optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5) # 定义训练参数 batch_size = 16 num_epochs = 3 max_seq_len = 512 # 训练模型 for epoch in range(num_epochs): # 训练一个epoch for batch in train_dataloader: # 获取输入数据 input_ids = batch["input_ids"].to(device) attention_mask = batch["attention_mask"].to(device) labels = batch["labels"].to(device) # 前向传播 outputs = model(input_ids, attention_mask, labels=labels) # 计算损失 loss = outputs[0] # 反向传播 loss.backward() # 优化模型 optimizer.step() # 清除梯度 optimizer.zero_grad() ```
corwn 最低0.47元/天 解锁专栏
送3个月
profit 百万级 高质量VIP文章无限畅学
profit 千万级 优质资源任意下载
profit C知道 免费提问 ( 生成式Al产品 )

相关推荐

张_伟_杰

人工智能专家
人工智能和大数据领域有超过10年的工作经验,拥有深厚的技术功底,曾先后就职于多家知名科技公司。职业生涯中,曾担任人工智能工程师和数据科学家,负责开发和优化各种人工智能和大数据应用。在人工智能算法和技术,包括机器学习、深度学习、自然语言处理等领域有一定的研究
专栏简介
专栏“BERT在文本分类中的应用”深入探讨了BERT模型在文本分类任务中的应用,从原理到实践全面解析。专栏包含一系列文章,涵盖了BERT文本分类的各个方面,包括算法原理、模型结构、训练技巧、数据预处理、模型调参、特征工程、模型评估、实战应用等。通过阅读本专栏,读者可以全面了解BERT文本分类技术,掌握其原理、应用场景和优化策略,从而提升文本分类任务的准确度和性能。
最低0.47元/天 解锁专栏
送3个月
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
C知道 免费提问 ( 生成式Al产品 )

最新推荐

Python列表与数据库:列表在数据库操作中的10大应用场景

![Python列表与数据库:列表在数据库操作中的10大应用场景](https://media.geeksforgeeks.org/wp-content/uploads/20211109175603/PythonDatabaseTutorial.png) # 1. Python列表与数据库的交互基础 在当今的数据驱动的应用程序开发中,Python语言凭借其简洁性和强大的库支持,成为处理数据的首选工具之一。数据库作为数据存储的核心,其与Python列表的交互是构建高效数据处理流程的关键。本章我们将从基础开始,深入探讨Python列表与数据库如何协同工作,以及它们交互的基本原理。 ## 1.1

Python list remove与列表推导式的内存管理:避免内存泄漏的有效策略

![Python list remove与列表推导式的内存管理:避免内存泄漏的有效策略](https://www.tutorialgateway.org/wp-content/uploads/Python-List-Remove-Function-4.png) # 1. Python列表基础与内存管理概述 Python作为一门高级编程语言,在内存管理方面提供了众多便捷特性,尤其在处理列表数据结构时,它允许我们以极其简洁的方式进行内存分配与操作。列表是Python中一种基础的数据类型,它是一个可变的、有序的元素集。Python使用动态内存分配来管理列表,这意味着列表的大小可以在运行时根据需要进

Python列表索引的秘密揭露:7个技巧让你成为索引大师

![Python列表索引的秘密揭露:7个技巧让你成为索引大师](https://blog.finxter.com/wp-content/uploads/2023/08/enumerate-1-scaled-1-1.jpg) # 1. Python列表索引基础概述 Python作为一种多范式的编程语言,其列表数据类型是处理集合数据的基础。在数据处理和算法实现中,列表索引为我们提供了高效访问和修改数据的能力。索引是列表中每个元素的位置标识,就像书中的页码一样,使我们能够快速定位和检索信息。在本章,我们将揭开Python列表索引的神秘面纱,从基础概念讲起,为接下来深入探讨列表索引机制打下坚实的基础

【递归与迭代决策指南】:如何在Python中选择正确的循环类型

# 1. 递归与迭代概念解析 ## 1.1 基本定义与区别 递归和迭代是算法设计中常见的两种方法,用于解决可以分解为更小、更相似问题的计算任务。**递归**是一种自引用的方法,通过函数调用自身来解决问题,它将问题简化为规模更小的子问题。而**迭代**则是通过重复应用一系列操作来达到解决问题的目的,通常使用循环结构实现。 ## 1.2 应用场景 递归算法在需要进行多级逻辑处理时特别有用,例如树的遍历和分治算法。迭代则在数据集合的处理中更为常见,如排序算法和简单的计数任务。理解这两种方法的区别对于选择最合适的算法至关重要,尤其是在关注性能和资源消耗时。 ## 1.3 逻辑结构对比 递归

Python装饰模式实现:类设计中的可插拔功能扩展指南

![python class](https://i.stechies.com/1123x517/userfiles/images/Python-Classes-Instances.png) # 1. Python装饰模式概述 装饰模式(Decorator Pattern)是一种结构型设计模式,它允许动态地添加或修改对象的行为。在Python中,由于其灵活性和动态语言特性,装饰模式得到了广泛的应用。装饰模式通过使用“装饰者”(Decorator)来包裹真实的对象,以此来为原始对象添加新的功能或改变其行为,而不需要修改原始对象的代码。本章将简要介绍Python中装饰模式的概念及其重要性,为理解后

【Python项目管理工具大全】:使用Pipenv和Poetry优化依赖管理

![【Python项目管理工具大全】:使用Pipenv和Poetry优化依赖管理](https://codedamn-blog.s3.amazonaws.com/wp-content/uploads/2021/03/24141224/pipenv-1-Kphlae.png) # 1. Python依赖管理的挑战与需求 Python作为一门广泛使用的编程语言,其包管理的便捷性一直是吸引开发者的亮点之一。然而,在依赖管理方面,开发者们面临着各种挑战:从包版本冲突到环境配置复杂性,再到生产环境的精确复现问题。随着项目的增长,这些挑战更是凸显。为了解决这些问题,需求便应运而生——需要一种能够解决版本

【Python字典的并发控制】:确保数据一致性的锁机制,专家级别的并发解决方案

![【Python字典的并发控制】:确保数据一致性的锁机制,专家级别的并发解决方案](https://media.geeksforgeeks.org/wp-content/uploads/20211109175603/PythonDatabaseTutorial.png) # 1. Python字典并发控制基础 在本章节中,我们将探索Python字典并发控制的基础知识,这是在多线程环境中处理共享数据时必须掌握的重要概念。我们将从了解为什么需要并发控制开始,然后逐步深入到Python字典操作的线程安全问题,最后介绍一些基本的并发控制机制。 ## 1.1 并发控制的重要性 在多线程程序设计中

Python版本与性能优化:选择合适版本的5个关键因素

![Python版本与性能优化:选择合适版本的5个关键因素](https://ask.qcloudimg.com/http-save/yehe-1754229/nf4n36558s.jpeg) # 1. Python版本选择的重要性 Python是不断发展的编程语言,每个新版本都会带来改进和新特性。选择合适的Python版本至关重要,因为不同的项目对语言特性的需求差异较大,错误的版本选择可能会导致不必要的兼容性问题、性能瓶颈甚至项目失败。本章将深入探讨Python版本选择的重要性,为读者提供选择和评估Python版本的决策依据。 Python的版本更新速度和特性变化需要开发者们保持敏锐的洞

Python数组在科学计算中的高级技巧:专家分享

![Python数组在科学计算中的高级技巧:专家分享](https://media.geeksforgeeks.org/wp-content/uploads/20230824164516/1.png) # 1. Python数组基础及其在科学计算中的角色 数据是科学研究和工程应用中的核心要素,而数组作为处理大量数据的主要工具,在Python科学计算中占据着举足轻重的地位。在本章中,我们将从Python基础出发,逐步介绍数组的概念、类型,以及在科学计算中扮演的重要角色。 ## 1.1 Python数组的基本概念 数组是同类型元素的有序集合,相较于Python的列表,数组在内存中连续存储,允

Python函数性能优化:时间与空间复杂度权衡,专家级代码调优

![Python函数性能优化:时间与空间复杂度权衡,专家级代码调优](https://files.realpython.com/media/memory_management_3.52bffbf302d3.png) # 1. Python函数性能优化概述 Python是一种解释型的高级编程语言,以其简洁的语法和强大的标准库而闻名。然而,随着应用场景的复杂度增加,性能优化成为了软件开发中的一个重要环节。函数是Python程序的基本执行单元,因此,函数性能优化是提高整体代码运行效率的关键。 ## 1.1 为什么要优化Python函数 在大多数情况下,Python的直观和易用性足以满足日常开发
最低0.47元/天 解锁专栏
送3个月
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
C知道 免费提问 ( 生成式Al产品 )