NLP入门

一、自然语言处理

1 什么是自然语言处理

【什么是人工智能,分别对应哪几个领域】

复制代码
AI是模仿甚至超越人的某项机能,NLP、CV、ASR
NLP是机器理解并生成人类语言

2 自然语言处理的发展简史





properties 复制代码
1950 -- 图灵提出"机器能思考吗",划时代性的话题
1956 -- 达特茅斯会议,提出人工智能(Artificial Intelligence),AI的元年,之前都是人类智能(Human Intelligence)
1957-1970 -- NLP开始出现两大阵营:规则 + 统计
1994-1999 -- 统计学开始占据主导地位
2000-2012 -- 机器学习开始盛行
2012-2022 -- 传统的深度学习占据主导地位
2023 -- 大模型时代
  • 基于规则举例:设计语言学规则,解析句子结构,例如一个句子由主谓宾构成。
  • 基于统计举例:统计机器翻译模型,收集大量平行语料库,例如中英互译,统计不同短语的分配概率,计算给定源语言翻译为目标语言的可能性。

3 自然语言处理的应用场景

properties 复制代码
语音助手:小爱同学
机器翻译:谷歌翻译
搜素引擎:百度翻译
智能对话:文心一言
推荐系统:短视频app推荐
......

二、文本预处理

1 认识文本预处理

  • 【文本预处理及作用】

    properties 复制代码
    所处阶段:数据输入到模型之前
    作用:数据清洗、指导超参数的确定,,,
  • 文本预处理的主要环节

    properties 复制代码
    1.文本处理的基本方法:分词、NER、POS
    2.文本张量的表示方法:one-hot、word2vec、wordEmbedding
    3.文本语料的数据分析:标签数量分析(类别不均衡问题)、句子长度分析、词频统计和关键词词云
    4.文本特征处理:添加n-gram特征、文本长度规范
    5.数据增强方法:回译数据增强

2 文本处理的基本方法

【文本处理的基本方法有几种】

复制代码
分词、pos、ner(2步,第一步命名实体的边界识别,序列标注任务,就是token级别的分类;第二步,对span进行分类,可以看做是句子级别的分类。)

2.1 分词

  • 分词的意义
properties 复制代码
分词就是将连续的字序列,按照一定的规范,重新组合成词序列的过程
一般实现模型训练的时候,模型接受的文本基本最小单位是词语,因此我们需要对文本进行分词
词语是语意理解的基本单元
英文具有天然的空格分隔符,而中文分词的目的:寻找一个合适的分词边界,进行准确分词
  • 常用分词工具

    • jieba分词工具

      • 精确模式:就是按照人类擅长的表达词汇的习惯来分词
      python 复制代码
      import jieba
      content = "我喜欢学习"
      jieba.cut(content, cut_all=False) # 返回生成器,cut_all=False默认
      jieba.lcut(content, cut_all=False) # 返回列表
      • 全模式分词:将尽可能成词的词汇分割出来
      python 复制代码
      import jieba
      content = "我喜欢学习"
      jieba.cut(content, cut_all=True) # 返回生成器
      jieba.lcut(content, cut_all=True) # 返回列表
      • 搜索引擎模式:在精确模式分词的基础上,将长粒度的词再次切分
      python 复制代码
      import jieba
      content = "我喜欢学习"
      jieba.cut_for_search(content) # 返回生成器
      jieba.lcut_for_search(content) # 返回列表结果
      • 支持中文繁体分词
      python 复制代码
      import jieba
      content = "煩惱即是菩提,我暫且不提"
      jieba.lcut(content)
      ['煩惱', '即', '是', '菩提', ',', '我', '暫且', '不', '提']
      • 支持用户自定义词典

        • 词典的意义
        properties 复制代码
        可以根据自定义词典,修改jieba分词方式,优先考虑词典里面的词来切分
        格式:词语 词频(可省略) 词性(可省略)
        • 代码实现
        python 复制代码
        import jieba
        content = "我喜欢学习"
        jieba.load_userdict("字典文件路径")
        jieba.lcut(content)

2.2 命名实体识别(实体抽取、ner)

  • 定义
properties 复制代码
命名实体:通常指人名、地名、机构名等专有名词
NER:从一段文本中识别出上述描述的命名实体
常见的7类命名实体:人名、地名、机构名、时间、日期、货币、百分比
  • 作用
properties 复制代码
同词汇一样,命名实体也是人类理解文本的基础单元,也是AI解决NLP领域高阶任务的重要环节

2.3 词性标注(pos)

  • 定义
properties 复制代码
对每个词语进行词性的标注:动词、名词、形容词等
  • 实现方式
python 复制代码
import jieba.posseg as pseg  # one.flag 词性 one.word token
content = "我喜欢学习"
pseg.lcut(content)

3 文本张量的表示方法

【文本张量的表示方法有几种】

复制代码
onehot、word2vec、word embedding

【word2vec有几种方法,分别解释一下】

复制代码
cbow、skipgram

3.1 文本张量表示

properties 复制代码
意义:将文本转换为向量(数字)的形式,使得模型能够识别进而实现训练,一般是进行词向量的表示
实现的方式:
one-hot
word2Vec
wordEmbedding

3.2 One-Hot 词向量表示

  • 定义
properties 复制代码
针对每一个词汇,都会用一个向量表示,向量的长度是n(n就是词表大小),n代表去重之后的词汇总量,而且向量中只有0和1两种数字
俗称:独热编码、01编码
  • 代码实现

    python 复制代码
    import jieba
    from tensorflow.keras.preprocessing.text import Tokenizer
    import joblib
    
    
    def onehot_gen(sent: str):
        # 1 准备语料vocabs
        vocabs = list(set(jieba.lcut(sent)))
    
        # 2 实例化词汇映射器Tokenizer,使用映射器拟合现有文本数据,内部生成 index_word、word_index
        my_tokenizer = Tokenizer()
        my_tokenizer.fit_on_texts(vocabs)
    
        # 3 查询单词idx 赋值zero_list 生成onehot
        for vocab in vocabs:
            zero_list = [0] * len(vocabs)
            # word_index 要对应 -1,my_tokenizer 从 1 开始
            idx = my_tokenizer.word_index[vocab] - 1
            zero_list[idx] = 1
            print(vocab, '\t', zero_list)
    
        # 4 使用joblib工具保存映射器 joblib.dump()
        my_path = 'onehot_vec.pkl'
        joblib.dump(my_tokenizer, my_path)
        print('my_tokenizer saved')
    
        print(my_tokenizer.word_index)  # char: idx
        print(my_tokenizer.index_word)  # idx: char
    
    
    def onehot_use(char):
        my_path = 'onehot_vec.pkl'
        my_tokenizer = joblib.load(my_path)
        zero_list = [0] * len(my_tokenizer.word_index)
        idx = my_tokenizer.word_index[char] - 1
        zero_list[idx] = 1
        print(f'{char}的onehot编码为{zero_list}')
    
    
    if __name__ == '__main__':
        sent = '两只黄鹂鸣翠柳,一行白鹭上青天。'
        onehot_gen(sent)
        onehot_use('黄鹂')
  • 【one-hot的优缺点】

    优点:简单,容易理解
    缺点:1、相似度为0;2、大语料情况下,占用大量资源

3.3 Word2Vec模型

properties 复制代码
word2vec是一种无监督(自监督)的训练方法,本质是训练一个模型,
将模型的参数矩阵当作所有词汇的词向量表示
两种训练方式:CBOW Skipgram
CBOW
properties 复制代码
核心思想:给一段文本,选择一定的窗口,然后利用上下文预测中间目标词
  • 实现过程
properties 复制代码
假设我们给定的训练语料只有一句话: Hope can set you free (愿你自由成长),
窗口大小为3,因此模型的第一个训练样本来自Hope can set,
因为是CBOW模式,所以将使用Hope和set作为输入,can作为输出,在模型训练时, Hope,can,set等词汇都使用它们的one-hot编码.
如图所示: 每个one-hot编码的单词与各自的变换矩阵(即参数矩阵3x5, 这里的3是指最后得到的词向量维度)相乘之后再相加, 得到上下文表示矩阵(3x1)
properties 复制代码
接着, 将上下文表示矩阵与变换矩阵(参数矩阵5x3, 所有的变换矩阵共享参数)相乘, 
得到5x1的结果矩阵, 它将与我们真正的目标矩阵即can的one-hot编码矩阵(5x1)进行损失的计算,
然后更新网络参数完成一次模型迭代.
properties 复制代码
最后窗口按序向后移动,重新更新参数,直到所有语料被遍历完成,得到最终的变换矩阵(3x5),这个变换矩阵与每个词汇的one-hot编码(5x1)相乘,得到的3x1的矩阵就是该词汇的word2vec张量表示.
skip-gram
properties 复制代码
核心思想: 给出一段文本,选择一定窗口获取数据集,利用中间词来预测上下文,
每个窗口要更新n-1次,训练更充分
Fasttext训练word2vec
  • 基本过程
properties 复制代码
1.获取数据
2.训练模型(训练词向量)  pip install fasttext-wheel
3.向量的检验
4.超参数设定
5.模型的保存和加载
  • 代码实现
python 复制代码
# coding: utf-8
import fasttext


# 1 获取训练数据,已完成
# 2 词向量的训练保存加载
def dm_fasttext_train_save_load():
    # 01 训练模型
    my_model = fasttext.train_unsupervised('./data/file')
    # 02 保存模型
    my_model.save_model('./data/file.bin')
    # 03 加载模型
    my_model = fasttext.load_model('./data/file.bin')


# 3 查看单词对应的词向量
# 通过get_word_vector方法来获得指定词汇的词向量, 默认词向量训练出来是1个单词100特征
def dm_fasttext_get_word_vector():
    # 01 加载模型
    my_model = fasttext.load_model("./data/file.bin")
    # 02 查询某个词汇的词向量
    result = my_model.get_word_vector("the")
    print(f'the的词向量是{type(result)}')
    print(f'the的词向量是{result.shape}')
    print(f'the的词向量是{result}')


# 4 检验模型效果
# 查找"运动"的邻近单词, 可以发现"体育网", "运动汽车", "运动服"等
def dm_fasttext_get_nearest_neighbors():
    # 01 加载模型
    my_model = fasttext.load_model("data/file.bin")
    # 02 查询sports的临近单词
    results1 = my_model.get_nearest_neighbors("sports")
    print(f'sports的邻居--》{results1}')
    # 查询music的临近单词
    results2 = my_model.get_nearest_neighbors("music")
    print(f'music的邻居--》{results2}')
    # 查询music的临近单词
    results3 = my_model.get_nearest_neighbors("dog")
    print(f'dog的邻居--》{results3}')


# 5 模型超参数设定
def dm_fasttext_train_args():
    # 训练模型 设置超参数
    my_model = fasttext.train_unsupervised('./data/file',
                                           "cbow",
                                           epoch=1,
                                           lr=0.1,
                                           dim=300,
                                           thread=8)

    # # 保存模型
    # my_model.save_model('./data/file.bin')


if __name__ == '__main__':
    # dm_fasttext_train_save_load()
    # dm_fasttext_get_word_vector()
    dm_fasttext_get_nearest_neighbors()
    # dm_fasttext_train_args()

3.4 词嵌入Word Embedding

【word2vec缺点】

复制代码
静态的固定的vec表示方法,多义词效果不佳
  • 实现过程
properties 复制代码
借助nn.Embedding(vocab_size, embed_dim): vocab_size代表词汇(去重之后)的总量,embed_dim是我们设定的词向量维度;本质创建一个权重矩阵(充当向量矩阵),矩阵参数会随着模型的训练迭代更新
  • 代码实现
python 复制代码
# coding:utf-8
import torch
import torch.nn as nn
from torch.utils.tensorboard import SummaryWriter
import tensorflow as tf
import tensorboard as tb
from tensorflow.keras.preprocessing.text import Tokenizer
import jieba
from rich import print


# 实验:nn.Embedding层词向量可视化分析
# 1 对句子分词 word_list
# 2 对句子word2id求my_token_list,对句子文本数值化sentence2id
# 3 创建nn.Embedding层,查看每个token的词向量数据

def dm_embedding_show():
    # 1 获取语料
    sentence1 = '我爱我的祖国'
    sentence2 = "我爱自然语言处理"
    sentences = [sentence1, sentence2]

    # 2 对句子分词 word_list
    word_list = []
    for s in sentences:
        word_list.append(jieba.lcut(s))
    print(f'word_list--》{word_list}')

    # 3 实例化Tokenizer
    my_tokenizer = Tokenizer()
    my_tokenizer.fit_on_texts(word_list)
    print(f'my_tokenizer.word_index--》{my_tokenizer.word_index}')
    print(f'my_tokenizer.index_word--》{my_tokenizer.index_word}')
    print('*' * 80)

    # 4 拿到所有的单词
    # my_token_list = list(my_tokenizer.index_word.values())
    my_token_list = my_tokenizer.index_word.values()
    print(my_token_list)
    print('*' * 80)

    # 5 打印句子2id
    sequence2id = my_tokenizer.texts_to_sequences(word_list)
    print(f'sequence2id--》{sequence2id}')

    # 6 获得embedding
    my_embed = nn.Embedding(num_embeddings=len(my_token_list), embedding_dim=8)
    print(f'my_embed--》{my_embed.weight.shape}')
    print(my_embed.weight.data)

    # 7 查询词汇的向量
    for idx in range(len(my_tokenizer.index_word)):
        temp_v = my_embed(torch.tensor(idx))
        word = my_tokenizer.index_word[idx + 1]
        print(f'{word}--->:词汇对用的向量是:{temp_v}')

    # 8 可视化
    my_summary = SummaryWriter()
    my_summary.add_embedding(my_embed.weight.data, my_token_list)
    my_summary.close()
    # 终端操作可视化:tensorboard --logdir=runs --host 0.0.0.0


if __name__ == '__main__':
    dm_embedding_show()
  • 可视化工具:

    • 工具:tensorboard
    • 命令:tensorboard --logdir=runs --host 0.0.0.0

4 文本数据分析

【文本数据分析有哪些方法】

复制代码
1、标签数量分布;2、句子长度分布;3、词频统计和词云

4.1 文本数据分析的作用

properties 复制代码
1: 帮助我们理解语料
2: 可以分析语料中可能存在的问题,指导我们设定模型的超参数等功能

4.2 标签数量分布

properties 复制代码
目的: 查询样本类别是否均衡,如果样本过大,需要减少数据;如果样本过少,需要增加数据
  • 代码实现
python 复制代码
import jieba
import jieba.posseg as pseg
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
from itertools import chain
from wordcloud import WordCloud


def dm_label_sns_countplot():
    '''
    获取标签数量分布
    0 什么标签数量分布:求标签0有多少个 标签1有多少个 标签2有多少个
    1 设置显示风格plt.style.use('fivethirtyeight')
    2 pd.read_csv(path, sep='\t') 读取训练集 验证集
    csv: 使用逗号, 作为列与列之间的分隔符; tsv: 使用制表符(Tab,\t)作为分隔符。
    3 sns.countplot() 统计label标签的0、1分组数量
    4 画图展示 plt.title() plt.show()
    '''
    # 1 设置显示风格
    plt.style.use('fivethirtyeight')
    # plt.style.use('Solarize_Light2')
    # 2 读取数据
    train_data = pd.read_csv('./cn_data/train.tsv', sep="\t")
    print(f'train_data--》{train_data.head()}')
    print(f'train_data--》{type(train_data)}')
    dev_data = pd.read_csv('./cn_data/dev.tsv', sep="\t")
    # 3 统计训练集label标签的0、1分组数量
    # hue="label"表示根据"label"显示不同的颜色
    sns.countplot(x="label", data=train_data, hue="label")
    # sns.countplot(y="label", data=train_data)
    # sns.countplot(x=train_data["label"])
    plt.title("train_data")
    plt.show()
    # 4 统计验证集label标签的0、1分组数量
    sns.countplot(x="label", data=dev_data, hue="label")
    plt.title("dev_data")
    plt.show()

4.3 句子长度分布

properties 复制代码
目的: 模型一般规定需要输入固定的尺寸,也就是长度统一,通过分析句子长度,可以明确大部分样本属于什么长度范围,然后进行句子的长短补齐或截断
  • 代码实现:(柱状图、曲线图)
python 复制代码
def dm_len_sns_countplot_distplot():
    '''
    获取句子长度分布
    '''
    # 1 设置显示风格
    plt.style.use('fivethirtyeight')
    # 2 读取数据
    train_data = pd.read_csv('./cn_data/train.tsv', sep="\t")
    dev_data = pd.read_csv('./cn_data/dev.tsv', sep="\t")

    # 3 添加一列 句子长度
    train_data["sentence_length"] = list(map(lambda x: len(x), train_data["sentence"]))
    print(f'修改后的train_data--》{train_data.head()}')
    dev_data["sentence_length"] = list(map(lambda x: len(x), dev_data["sentence"]))
    print(f'修改后的dev_data--》{dev_data.head()}')
    # 4 画图训练集
    # countplot 柱状图、displot 直方图、kde=True 生成核密度曲线
    # plt.xticks([]) 不显示任何 x 轴的刻度标签,设置与否都是为了观看
    sns.countplot(x="sentence_length", data=train_data)
    plt.xticks([])
    # plt.yticks([i for i in range(0, 100, 10)])
    plt.show()

    sns.displot(x="sentence_length", data=train_data, kde=True)
    plt.xticks([i for i in range(0, 3500, 200)])
    # plt.yticks([i for i in range(0, 100, 10)])
    plt.show()

    # 5 画图验证集
    sns.countplot(x="sentence_length", data=dev_data)
    plt.xticks([])
    plt.show()

    sns.displot(x="sentence_length", data=dev_data, kde=True)
    plt.yticks([])
    plt.show()
  • 代码实现(散点图)
python 复制代码
def dm_sns_stripplot():
    '''
    获取正负样本长度散点分布
    '''
    # 1 设置显示风格
    plt.style.use('fivethirtyeight')
    # 2 读取数据
    train_data = pd.read_csv('./cn_data/train.tsv', sep="\t")
    dev_data = pd.read_csv('./cn_data/dev.tsv', sep="\t")

    # 3 添加一列 句子长度
    train_data["sentence_length"] = list(map(lambda x: len(x), train_data["sentence"]))
    dev_data["sentence_length"] = list(map(lambda x: len(x), dev_data["sentence"]))
    # 4 画图训练集
    sns.stripplot(y="sentence_length", x="label", data=train_data, hue="label")
    plt.show()
    # 5 画图验证集
    sns.stripplot(y="sentence_length", x="label", data=dev_data)
    plt.show()

4.4 词频和高频词云

properties 复制代码
词频: 这里指的是统计样本中词汇的总数量(需要去重)
高频词云目的: 可以方便我们查看数据集中是否存在脏数据,进而实现人工的审核和清洗
  • 词频:词汇总数统计
python 复制代码
def dm_tj_words_counts():
    '''
    获取不同词汇总数统计
    '''
    # 1 读取数据
    train_data = pd.read_csv('./cn_data/train.tsv', sep="\t")
    # print(f'train_data--》{train_data.head()}')
    dev_data = pd.read_csv('./cn_data/dev.tsv', sep="\t")
    # 2 获取训练数据语料的词语数量
    # chain(*) 扁平化处理
    train_vocab = set(chain(*map(lambda x: jieba.lcut(x), train_data["sentence"])))
    print(f'训练集词语数量---》{len(train_vocab)}')
    # 3 获取验证数据语料的词语数量
    dev_vocab = set(chain(*map(lambda x: jieba.lcut(x), dev_data["sentence"])))
    print(f'验证集词语数量---》{len(dev_vocab)}')
  • 高频词云
python 复制代码
# 7 获取训练集高频形容词词云
# 7.1 获取每个句子的形容词列表
def get_a_list(text):
    r = []
    for g in pseg.lcut(text):
        # g.flag 词性;g.word 具体str
        if g.flag == "a":
            r.append(g.word)
    return r


# 7.2 根据词云列表产生词云
def get_word_cloud(keywords_list):
    # 实例化词云对象
    my_wordcloud = WordCloud(font_path='./cn_data/SimHei.ttf', max_words=100, background_color="white")
    # 准备数据,要有分隔符,一个str
    a_str = " ".join(keywords_list)
    # 产生词云
    my_wordcloud.generate(a_str)
    # 画图展示
    plt.figure()
    # interpolation="bilinear" 指定图像在显示时的插值方法,用于根据已知数据点估计未知数据点的值
    # "bilinear" 插值是一种常用插值方法,它使用四个最近邻像素的加权平均来估计新像素的值
    plt.imshow(my_wordcloud, interpolation="bilinear")
    # off 关闭或隐藏坐标轴
    plt.axis("off")
    plt.show()


# 7.3 生成词云
def dm_word_cloud():
    # 1 获取数据
    train_data = pd.read_csv('./cn_data/train.tsv', sep="\t")
    # 2 获取积极的评论样本
    p_train_data = train_data[train_data["label"] == 1]["sentence"]
    # print(f'p_train_data--》{p_train_data.head()}')
    # 3 获取每个句子中形容的列表
    p_a_words = list(chain(*map(lambda x: get_a_list(x), p_train_data)))
    # print(f'p_a_words--》{p_a_words[:3]}')
    # print(f'p_a_words--》{len(p_a_words)}')
    get_word_cloud(p_a_words)
    # 4 获取消极的评论样本
    n_train_data = train_data[train_data["label"] == 0]["sentence"]
    # print(f'n_train_data--》{n_train_data.head()}')
    # 5 获取每个句子中形容的列表
    n_a_words = list(chain(*map(lambda x: get_a_list(x), n_train_data)))
    get_word_cloud(n_a_words)

5 文本特征处理

【介绍一下n-gram】

复制代码
将n个连续相邻的token组合到一起,n-gram特征

【为什么要规范文本长度】

复制代码
模型的输入需要【每个batch】或者【整个数据集】,统一句子长度
properties 复制代码
对语料添加普适性的特征:n-gram
对语料进行规范长度:适配模型的输入

5.1 添加N-Gram特征

properties 复制代码
定义: 将连续的相邻的词或者字组合到一块,就称为n-gram特征
  • 代码实现
python 复制代码
# coding:utf-8
def add_n_gram(a: list):
    n_gram = 2
    print(f'列表推导式结果--》{[a[i:] for i in range(n_gram)]}')
    # * 把list中每个元素作为独立的部分 传给zip
    return set(zip(*[a[i:] for i in range(n_gram)]))


result = add_n_gram(a=[1, 3, 2, 1, 5, 3])
print(result)

5.2 文本长度规范

properties 复制代码
意义: 模型一般需要固定尺寸的输入,因此需要对文本句子进行补齐(一般用0补齐)或者截断
  • 代码实现
python 复制代码
# coding:utf-8
from keras.preprocessing import sequence


# 1 使用 api 填充
def padding(x_train):
    max_len = 10
    return sequence.pad_sequences(x_train, max_len, padding="post", truncating="pre")


# 假定x_train里面有两条文本, 一条长度大于10, 一天小于10
x_train = [[1, 23, 5, 32, 55, 63, 2, 21, 78, 32, 23, 1],
           [2, 32, 1, 23, 1]]


# 2 自定义填充
def my_padding(x: list):
    max_len = 5
    # paddiing
    x = x + (max_len - len(x)) * [0]
    # truncating
    x = x[:max_len]
    return x


a = my_padding(x=[1, 2, 3, 45, 5, 6, 7, 8])
print(a)

6 文本数据增强

properties 复制代码
目的: 增加数据集(扩展数据集)

6.1 回译数据增强

properties 复制代码
定义: 通过将一种语言翻译成不同的语言,再转换回来的一种方式
eg: 中文---韩文----英语---中文
相关推荐
Mr.Lee jack4 小时前
体验GPT-OSS-120B:在PH8平台上探索超大规模语言模型的强大能力
人工智能·gpt·语言模型·openai·deepseek
余衫马4 小时前
大语言模型(LLM)领域细分方向解析
人工智能·语言模型·自然语言处理·llm·领域方向
小关会打代码4 小时前
自然语言处理(NLP)之分词
人工智能·自然语言处理
阿里-于怀4 小时前
阿里云发布《AI 原生应用架构白皮书》
人工智能·阿里云·ai·架构·白皮书·ai原生
AI新兵4 小时前
AI大事记12:Transformer 架构——重塑 NLP 的革命性技术(中)
人工智能·自然语言处理·transformer
开放知识图谱4 小时前
论文浅尝 | 基于知识的视觉问答中模态感知与大语言模型的集成(ACL2024)
人工智能·语言模型·自然语言处理
赴3354 小时前
LSTM自然语言处理情感分析项目(四)整合调用各类与方法形成主程序
人工智能·自然语言处理·lstm
Elastic 中国社区官方博客4 小时前
Simple MCP Client - 连接到 Elasticsearch MCP 并进行自然语言搜索
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索
三年呀4 小时前
深度剖析Mixture of Experts(MoE)架构:从原理到实践的全面指南
人工智能·深度学习·架构·模型优化·大规模模型