【知识拓展】机器学习基础(一):什么是预处理对象、模型对象 、pipeline、Tokenizer

前言

        公司业务需要一套可离线部署的检索增强生成(RAG)大模型知识库,于是最近花了一周时间了解了AI相关的技术。除了查阅各类高质量技术博客,也自行动手进行了一些demo样例。其中包括huggingface、modelscope等平台,虽能使用,但疑惑还是不少,仅在此记录一些学习中的过程和问题,以便日后自我查阅。

几个关键的概念

        对于机器学习方面的初学者来说,预处理对象、模型对象和 pipeline 是经常见到的,尤其是写过一些demo,它们在数据处理、模型训练和预测等过程中起着重要作用。很多时候官方概念可能难以理解,以下是个人经过查阅资料后,解释这些概念及其作用。

        下面会根据部分Demo代码案例说明。

预处理对象

        对原始数据进行处理和转换的工具或方法,以便将数据转换为适合模型输入的格式。简单的说就是对数据进行预处理,处理成模型所需要的输入格式,例如将文本转化为输入 ID 和其他必要的张量。常见的一些预处理如下:

  • 数据清理:处理缺失值、去除噪声、纠正数据错误等。
  • 特征工程:生成、选择和转换特征,如标准化、归一化、特征缩放等。
  • 数据增强:特别是对于图像数据,可能包括旋转、裁剪、翻转等操作。
  • 编码:将分类变量转换为数值形式(如独热编码)。
  • 拆分数据:将数据集分为训练集、验证集和测试集。

示例一(使用scikit-learn的预处理对象)

from sklearn.preprocessing import StandardScaler

# 创建预处理对象
scaler = StandardScaler()

# 适配数据并进行转换
X_train_scaled = scaler.fit_transform(X_train)

模型对象

        模型对象是由特定的算法和参数组成,经过训练后能够进行预测或分类。模型对象通常包括以下部分:

  • 结构:模型的架构,例如线性回归、决策树、神经网络等。
  • 参数:模型的可调参数,通过训练数据进行学习和优化。
  • 训练方法:用于优化模型参数的方法,例如梯度下降。

示例一(使用scikit-learn的模型对象)

接上述示例一

from sklearn.linear_model import LogisticRegression

# 创建模型对象
model = LogisticRegression()

# 训练模型
model.fit(X_train_scaled, y_train)

Pipeline

        将多个数据处理步骤和模型训练步骤串联起来,以便简化和自动化整个工作流程。它将数据预处理和模型训练过程结合在一起,使得整个过程可以作为一个单独的工作流来处理。简单的说就是将多个步骤封装在一起,使用者无需关注细节,一个高级API

        一个完整的pipeline一般包括了数据的前处理、模型的前向推理、数据的后处理三个过程。

示例一(使用 scikit-learn)

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression

# 创建 pipeline 对象
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('logistic_regression', LogisticRegression())
])

# 训练 pipeline
pipeline.fit(X_train, y_train)

示例二:

        pipeline 简化了整个处理过程,通过内部调用预处理、模型推理和后处理步骤,让用户能够方便地调用复杂的模型并得到结果。

from modelscope.pipelines import pipeline

# 创建 word segmentation pipeline
word_segmentation = pipeline('word-segmentation', model='damo/nlp_structbert_word-segmentation_chinese-base')

# 输入字符串
input_str = '今天天气不错,适合出去游玩'

# 输出分词结果
print(word_segmentation(input_str))

Tokenizer

        标记器,自然语言处理(NLP)中的一个关键工具,用于将文本数据转换为模型可以处理的格式。具体来说,Tokenizer 将输入的文本字符串分割成更小的单元(通常是单词或子词),然后将这些单元映射到整数 ID。这些整数 ID 作为输入传递给机器学习模型。简单的说,用来作为数据细化处理到最小单元token(标记)。主要功能如下:

  • 分词(Tokenization): 将文本分割成更小的单元,如单词或子词。例如,句子“Hello, how are you?” 可以被分割成 ["Hello", ",", "how", "are", "you", "?"]。

  • 映射到 ID(Token to ID Mapping): 将每个 token 映射到一个唯一的整数 ID。这个映射通常基于一个预定义的词汇表。例如,"Hello" 可能被映射为 123,"how" 可能被映射为 456。

  • 添加特殊标记(Special Tokens): 对于一些模型,需要在输入序列的开头和结尾添加特殊标记。例如,在 BERT 模型中,句子的开头和结尾分别添加 [CLS][SEP] 标记。

  • 生成注意力掩码(Attention Mask): 创建一个掩码,指示哪些 token 是实际输入,哪些是填充部分(padding)。填充部分是为了使输入序列达到固定长度。

  • 解码(Decoding): 将整数 ID 序列转换回原始文本或接近原始文本的形式。这在生成任务中非常重要,如文本生成或翻译。

示例一(使用 Hugging Face 的 AutoTokenizer 进行分词和编码)

from transformers import AutoTokenizer

# 指定模型名称
model_name = 'bert-base-uncased'

# 自动加载对应的标记器
tokenizer = AutoTokenizer.from_pretrained(model_name)

# 输入文本
input_text = "Hello, how are you?"

# 分词和编码
encoded_input = tokenizer(input_text, return_tensors='pt')

print(encoded_input)
# 输出:
# {'input_ids': tensor([[  101,  7592,  1010,  2129,  2024,  2017,  1029,  102]]),
#  'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0]]),
#  'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1]])}

示例二(使用BERT 模型的BertTokenizer将输入文本处理成模型可以接受的格式)

from transformers import BertModel, BertTokenizer

model_name = 'bert-base-uncased'
model = BertModel.from_pretrained(model_name)
tokenizer = BertTokenizer.from_pretrained(model_name)

input_text = "Hello, how are you?"
inputs = tokenizer(input_text, return_tensors="pt")

print(inputs)
# 输出:
# {'input_ids': tensor([[  101,  7592,  1010,  2129,  2024,  2017,  1029,  102]]),
#  'token_type_ids': tensor([[0, 0, 0, 0, 0, 0, 0, 0]]),
#  'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1]])}

outputs = model(**inputs)
print(outputs)

BertTokenizer和AutoTokenizer区别

  BertTokenizer专门为 BERT(Bidirectional Encoder Representations from Transformers)模型设计的标记器。

      AutoTokenizer 是一个通用的标记器加载器,能够根据模型名称自动选择合适的标记器。

示例(pipeline传入自定义预处理对象、模型对象)

from modelscope.pipelines import pipeline
from modelscope.models import Model
from modelscope.preprocessors import Preprocessor

# 定义自定义预处理对象
class CustomPreprocessor(Preprocessor):
    def __init__(self):
        super().__init__()
    
    def __call__(self, text):
        # 简单的预处理逻辑:转小写并去除标点符号
        import re
        text = text.lower()
        text = re.sub(r'[^\w\s]', '', text)
        return {'text': text}

# 加载预训练模型
model = Model.from_pretrained('damo/nlp_structbert_sentiment-classification_chinese-base')

# 创建自定义预处理对象实例
custom_preprocessor = CustomPreprocessor()

# 创建 pipeline,传入自定义预处理对象和模型对象
text_classification_pipeline = pipeline(
    task='text-classification',
    model=model,
    preprocessor=custom_preprocessor
)

# 输入文本
input_text = "今天的天气真好!"

# 进行预测
result = text_classification_pipeline(input_text)
print(result)

分析:

  • 自定义预处理对象

    • 我们定义了一个 CustomPreprocessor 类,继承自 Preprocessor
    • __call__ 方法中,实现了简单的文本预处理逻辑:将文本转换为小写并去除标点符号。
  • 加载预训练模型

    • 使用 Model.from_pretrained 方法加载 ModelScope 提供的预训练模型 damo/nlp_structbert_sentiment-classification_chinese-base
  • 创建 pipeline 并传入自定义组件

    • 使用 pipeline 函数创建一个文本分类的 pipeline。
    • 将自定义的预处理对象 custom_preprocessor 和预训练模型对象 model 作为参数传入 pipeline
  • 进行预测

    • 输入文本 input_text 通过 text_classification_pipeline 进行处理和预测,得到结果。

Preprocessor.from_pretrained方法

        用来加载与模型相关的预处理对象。

from modelscope.models import Model
from modelscope.pipelines import pipeline
from modelscope.preprocessors import Preprocessor, TokenClassificationTransformersPreprocessor

# 加载预训练模型
model = Model.from_pretrained('damo/nlp_structbert_word-segmentation_chinese-base')

# 从模型目录中加载预处理器
tokenizer = Preprocessor.from_pretrained(model.model_dir)
# 或者直接调用构造函数创建预处理器对象
# tokenizer = TokenClassificationTransformersPreprocessor(model.model_dir)

# 创建 pipeline,并传入模型和预处理器
word_segmentation = pipeline('word-segmentation', model=model, preprocessor=tokenizer)

# 输入文本
input = '今天天气不错,适合出去游玩'

# 进行分词处理
print(word_segmentation(input))
# 输出:{'output': ['今天', '天气', '不错', ',', '适合', '出去', '游玩']}

方法的作用

用于从指定的目录加载预处理器配置和相关资源。这个方法通常会:

  1. 读取配置文件:在模型目录中,通常有一个或多个配置文件(例如 config.json),其中包含了预处理器的配置参数。
  2. 加载必要的资源:预处理器可能需要一些词汇表、词典、模型权重等文件,这些文件通常也存储在模型目录中。
  3. 初始化预处理器:根据读取的配置和加载的资源,初始化预处理器对象,使其可以执行预处理任务。

典型模型目录结构

根据以上,我们大致能推测出,模型目录中的文件结构应该会有一定标准,典型的结构如下。

model_directory/

├── config.json
├── preprocessor_config.json         #预处理器配置文件(modelscope),包含预处理器的配置信息和参数设置。用于初始化预处理器对象。
├── vocab.txt         #词汇表文件,包含模型使用的词汇列表。每行一个词汇,通常由预训练过程中使用的词汇表生成。
├── tokenizer_config.json         #标记器配置文件,包含标记器的配置信息和参数设置。用于初始化标记器对象。
├── pytorch_model.bin
├── special_tokens_map.json         #特殊标记映射文件,定义了特殊标记(如 [CLS], [SEP], [PAD])的映射关系。
├── added_tokens.json        #新增标记文件,包含训练过程中添加的额外标记及其映射关系。此文件并非所有模型目录中都存在,只有在训练过程中有新增标记时才会出现。
├── model_card.json        #模型卡片文件(modelscope),包含模型的描述、用途、性能、训练数据等信息。用于提供模型的元数据和使用说明。
└── README.md

下面对主要文件进行说明:

config.json

        模型配置文件,包含模型的架构信息和超参数设置。通常由模型的创建者生成,并包含模型的详细配置。

示例:

{
  "hidden_size": 768,
  "num_attention_heads": 12,
  "num_hidden_layers": 12,
  "vocab_size": 30522
}

pytorch_model.bin

       文件是模型的权重文件,是模型文件结构中最重要的部分之一。它包含了模型在训练过程中学习到的所有参数(如权重和偏差),这些参数决定了模型的行为和性能。这个文件通常比较大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/18872.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

扎气球最高分-第13届蓝桥杯选拔赛Python真题精选

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第74讲。 扎气球最高分&…

Spring框架温习

Spring Spring是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层。但是 Spring仍然可以和其他的框架无缝整合。 Spring 特点: 轻量级、控制反转、面向切面、容器、框架集合 Spring 核心组件: Spring 常用模块&…

【Redis】 关于 Redis 有序集合类型

文章目录 🍃前言🌴普通命令介绍🚩zadd🚩zcard🚩zcount🚩zrange🚩zrevrange🚩zrangebyscore🚩zpopmax🚩zpopmin🚩zrank🚩zrevrank&…

Shell脚本的分支语句,循环语句

分支语句 if 表达式 then 命令表 fi 如果表达式为真,则执行命令表中的命令,否则退出。执行fi后的语句。 给文件权限:chmod 0777 文件名 输出: ./文件名 grep 查找用户名,管道wc -l 统计字符 2.多路分支语句 记得给文件名权限喔&#x…

OSPF扩展知识2

FA-转发地址 正常 OSPF 区域收到的 5 类 LSA 不存在 FA 值; 产生 FA 的条件: 1、5类LSA ----假设 R2为 ASBR,90/0 口工作的 OSPF 中,g0/1 口工作在非 ospf 协议或不同 ospf 进程中;若 g0/1 也同时宣告在和 g0/0 相同的 OSPF 进程…

R语言入门 | 使用 ggplot2 进行数据可视化

1.0准备工作 先下好tidyverse包,并进行加载。 install.packages ( "tidyverse" ) library(tidyverse) R 包只需安装一次,但每次开始新会话时都要重新加载。 1.1 数据框 数据框是变量(列)和观测(行&#x…

算法练习——字符串

一确定字符串是否包含唯一字符 1.1涉及知识点 c的输入输出语法 cin>>s; cout<<"NO"; 如何定义字符串 切记&#xff1a;在[]中必须加数字——字符串最大长度&#xff0c;不然编译不通过 char s[101]; 如何获取字符串长度 char s[101];cin>>s;i…

windows10远程桌面端口,修改Windows 10远程桌面端口的步骤

在Windows 10操作系统中&#xff0c;远程桌面功能为企业用户、技术支持人员以及个人用户提供了极大的便利&#xff0c;允许他们远程访问和管理另一台计算机的桌面环境。然而&#xff0c;默认的远程桌面端口&#xff08;通常为3389&#xff09;常常成为安全漏洞的潜在目标&#…

【基础】线段树

超详解线段树(浅显易懂,几乎涵盖所有线段树类型讲解,匠心之作,图文并茂)-CSDN博客 建树 void bui(int id,int l,int r)//创建线段树,id表示存储下标,区间[L,r] {if(l r)//左端点等于右端点&#xff0c;即为叶子节点(区间长度为1)&#xff0c;直接赋值即可{tr[id] a[l];return…

【图像处理与机器视觉】图像处理概述与像素

什么是数字图像处理 改善图像信息&#xff0c;便于作出解释 方便对图像传输&#xff0c;储存&#xff0c;方便机器理解 什么是数字图像 &#xff08;1&#xff09;模拟图像&#xff1a;连续二维函数 f&#xff08;x&#xff0c;y&#xff09;表示&#xff0c;其中 x&#xf…

操作系统真象还原:一些你可能正感到迷惑的问题

第0章-一些你可能正感到迷惑的问题 这是我看操作系统真象还原这本书的一些记录&#xff1a; 4 软件是如何访问硬件的 硬件在输入输出上大体分为串行和并行&#xff0c;相应的接口也就是串行接口和并行接口。串行硬件通过串行接口与 CPU 通信&#xff0c;反过来也是&#xff…

【uni-app】Pinia 持久化

小程序端 Pinia 持久化 说明&#xff1a;Pinia 用法与 Vue3 项目完全一致&#xff0c;uni-app 项目仅需解决持久化插件兼容性问题。 持久化存储插件 安装持久化存储插件&#xff1a; pinia-plugin-persistedstate pnpm i pinia-plugin-persistedstate插件默认使用 localStor…

MySQL——JDBC编程

目录 前言 一、JDBC概述 二、准备工作 1.下载MySQL的JDBC驱动包 2.把jar引入到项目中 三、JDBC编程 1.插入操作 2.查询操作 尾声 前言 本篇文章主要介绍如何利用Java代码进行操作数据库&#xff0c;在实际开发中&#xff0c;绝大多数对数据库的操作我们都是通过代码进行…

aop整理

一、aop基础知识 Spring AOP 详细深入讲解代码示例 二、spring/spring boot/spring cloud中出现的注解/类与概念的对应 Aspect&#xff1a; 标注当前MyAspect是一个切面类&#xff0c;–》对应切面的概念&#xff0c;在切面类中有用Before等注解修饰的方法作为advice,也有用…

uni-app全局弹窗的实现方案

背景 为了解决uni-app 任意位置出现弹窗 解决方案 一、最初方案 受限于uni-app 调用组件需要每个页面都引入注册才可以使用&#xff0c;此方案繁琐&#xff0c;每个页面都要写侵入性比较强 二、改进方案 app端&#xff1a;新建一个页面进行跳转&#xff0c;可以实现伪弹窗…

筛选的艺术:数组元素的精确提取

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、筛选的基本概念 二、筛选的实际应用案例 1. 筛选能被三整除的元素 2. 筛选小于特定值…

C++ list类

目录 0.前言 1.list介绍 1.1优势 1.2劣势 1.3容器属性 2.list使用 2.1构造函数 2.1.1默认构造函数 2.1.2填充构造函数 2.1.3范围构造函数 2.1.4拷贝构造函数 2.1.5初始化列表构造函数 2.2迭代器 2.2.1 begin() 2.2.2 end() 2.2.3 cbegin() 2.2.4 cend() 2.2.…

【C#】中托管与非托管对象区别、托管与非托管DLL区别

C 中的托管与非托管的区别_托管程序和非托管程序-CSDN博客 C# 中托管与非托管对象区别 在C#中&#xff0c;托管对象和非托管对象的主要区别在于内存管理和执行环境&#xff1a; 托管对象 (Managed Objects) 内存管理&#xff1a;托管对象的内存由.NET运行时&#xff08;CLR…

什么是CAS?

CAS&#xff08;比较并交换&#xff0c;Compare And Swap&#xff09;是一种多线程并发编程中的原子操作。它是一种乐观锁技术&#xff0c;用于解决 多线程环境下的数据竞争问题。CAS操作通过比较内存中的值与预期值是否相等来确定是否进行交换&#xff0c;如果相等&#xff0c…

PyMySQL连接池

背景 在用python写后端服务时候&#xff0c;需要与mysql数据库进行一些数据查询或者插入更新等操作。启动服务后接口运行一切正常&#xff0c; 隔了第二天去看服务日志就会报错&#xff0c;问题如下&#xff1a; pymysql.err.OperationalError: (2006, "MySQL server ha…