深度学习笔记(8)预训练模型

news2024/11/15 15:33:44

深度学习笔记(8)预训练模型

文章目录

  • 深度学习笔记(8)预训练模型
  • 一、预训练模型构建
  • 一、微调模型,训练自己的数据
    • 1.导入数据集
    • 2.数据集处理方法
    • 3.完形填空训练
  • 使用分词器将文本转换为模型的输入格式
  • 参数 return_tensors="pt" 表示返回PyTorch张量格式
  • 执行模型预测


一、预训练模型构建

加载模型和之前一样,用别人弄好的

# 导入warnings模块,用于忽略后续代码中可能出现的警告信息
import warnings
# 设置warnings模块,使其忽略所有警告
warnings.filterwarnings("ignore")

# 从transformers库中导入AutoModelForMaskedLM类,该类用于预训练的掩码语言模型
from transformers import AutoModelForMaskedLM

# 指定模型检查点,这里使用的是distilbert-base-uncased模型
model_checkpoint = "distilbert-base-uncased"
# 使用from_pretrained方法加载预训练的模型,该方法将从指定的检查点加载模型
model = AutoModelForMaskedLM.from_pretrained(model_checkpoint)

咱们的任务就是去预测MASK到底是个啥

text = "This is a great "  # 定义一个文本字符串

# 从指定的模型检查点加载分词器
# model_checkpoint 是之前定义的模型检查点路径,用于加载与模型配套的分词器
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)

# 使用分词器将文本转换为模型的输入格式
# 参数 return_tensors="pt" 表示返回PyTorch张量格式
inputs = tokenizer(text, return_tensors="pt")

# inputs 现在是一个包含模型输入的张量或字典,可以用于模型推理
{'input_ids': tensor([[ 101, 2023, 2003, 1037, 2307,  103, 1012,  102]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1, 1]])}

下面的代码可以看到mask的id是103

tokenizer.mask_token_id
103

一、微调模型,训练自己的数据

1.导入数据集

from datasets import load_dataset  # 从datasets库中导入load_dataset函数

imdb_dataset = load_dataset("imdb")  # 使用load_dataset函数加载IMDB数据集

这段代码是使用 datasets 库来加载 IMDB 数据集。IMDB 数据集是一个用于情感分析的经典数据集,包含了两类电影评论:正面和负面。
本身是带标签的 正面和负面

  • 0 表示negative
  • 1表示positive

先查看下数据集的数据

 sample = imdb_dataset["train"].shuffle(seed=42).select(range(3))  # 从训练数据中随机选择3个样本
 for row in sample:
    print(f"\n'>>> Review: {row['text']}'")  # 打印样本的文本内容
    print(f"'>>> Label: {row['label']}'")   # 打印样本的标签

其中一个如下

'>>> Review: This movie is a great. The plot is very true to the book which is a classic written by Mark Twain. The movie starts of with a scene where Hank sings a song with a bunch of kids called "when you stub your toe on the moon" It reminds me of Sinatra's song High Hopes, it is fun and inspirational. The Music is great throughout and my favorite song is sung by the King, Hank (bing Crosby) and Sir "Saggy" Sagamore. OVerall a great family movie or even a great Date movie. This is a movie you can watch over and over again. The princess played by Rhonda Fleming is gorgeous. I love this movie!! If you liked Danny Kaye in the Court Jester then you will definitely like this movie.'
'>>> Label: 1'

但是我们要做完形填空,标签是没用的

2.数据集处理方法

这里文本长度要统一

  • 计算每一个文本的长度(word_ids)
  • 指定chunk_size,然后将所有数据按块进行拆分,比如每块128个,句子是700字节,要分成128,128,。。。。这种

先定义个函数,这样下面使用可以直接调用

def tokenize_function(examples):
    # 调用分词器(tokenizer)的函数,传入输入的文本数据集
    result = tokenizer(examples["text"])
    
    # 如果分词器支持快速模式,则生成单词索引(word_ids)
    if tokenizer.is_fast:
        result["word_ids"] = [result.word_ids(i) for i in range(len(result["input_ids"]))]
    
    # 返回转换后的结果
    return result

进行文本处理

tokenized_datasets = imdb_dataset.map(
    tokenize_function,  # 应用tokenize_function函数到每个样本
    batched=True,       # 是否将数据分成批次处理
    remove_columns=["text", "label"]  # 要从数据集中移除的列
)

首先,imdb_dataset.map() 方法被用来应用 tokenize_function 函数到 imdb_dataset 的 train 部分。这个方法会对数据集中的每个样本应用指定的函数,并返回一个新的数据集,其中包含应用函数后的结果。

batched=True 参数告诉 map 方法将输入数据分成批次进行处理。这通常是为了提高效率,尤其是在处理大型数据集时。

remove_columns=[“text”, “label”] 参数告诉 map 方法在处理数据时移除指定的列。在这个例子中,它移除了 text 和 label 列,因为 text 列已经被处理为模型的输入,而 label 列不再需要,因为咱们是完形填空任务,不需要标签。

然后进行切分

tokenizer.model_max_length
chunk_size = 128

tokenizer.model_max_length 是一个属性,它表示模型能够接受的最大输入长度。这个属性通常用于序列标注任务,以确保输入的长度不超过模型的最大接受长度。

chunk_size 是一个参数,用于指定将输入序列分割成小块的大小。这个参数通常用于处理过长的输入序列,以便将其分割成多个小块,然后分别处理这些小块。
因为上限是512 所以你切分要是64 128 256这种

切分的时候也可以先看下文本长度

# 看看每一个都多长
tokenized_samples = tokenized_datasets["train"][:3]

for idx, sample in enumerate(tokenized_samples["input_ids"]):
    print(f"'>>> Review {idx} length: {len(sample)}'")
'>>> Review 0 length: 363'
'>>> Review 1 length: 304'
'>>> Review 2 length: 133'

这里看出128切分比较合适
先拿着三个试试

concatenated_examples = {
    k: sum(tokenized_samples[k], []) for k in tokenized_samples.keys()#计算拼一起有多少个,
}
total_length = len(concatenated_examples["input_ids"])
print(f"'>>> Concatenated reviews length: {total_length}'")
'>>> Concatenated reviews length: 800'

下面进行切分

chunks = {
    # 使用字典推导式(dict comprehension)创建一个新的字典,其中键是序列的键(k),值是分割后的块
    k: [t[i : i + chunk_size] for i in range(0, total_length, chunk_size)]
    # 遍历concatenated_examples字典中的每个键值对
    for k, t in concatenated_examples.items()
}

for chunk in chunks["input_ids"]:
    # 打印每个chunk的长度
    print(f"'>>> Chunk length: {len(chunk)}'")
'>>> Chunk length: 128'
'>>> Chunk length: 128'
'>>> Chunk length: 128'
'>>> Chunk length: 128'
'>>> Chunk length: 128'
'>>> Chunk length: 128'
'>>> Chunk length: 32'

最后那个不够数,直接给他丢弃

def group_texts(examples):
    # 将所有的文本实例拼接到一起
    concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()}
    
    # 计算拼接后的总长度
    total_length = len(concatenated_examples[list(examples.keys())[0]])
    
    # 使用整除运算符(//)计算每个chunk的长度,然后乘以chunk_size,以确保不会出现多余的文本
    total_length = (total_length // chunk_size) * chunk_size
    
    # 根据计算出的总长度,对拼接后的文本进行切分
    result = {
        # 使用字典推导式(dict comprehension)创建一个新的字典,其中键是原始字典的键(k),值是切分后的块
        k: [t[i : i + chunk_size] for i in range(0, total_length, chunk_size)]
        # 遍历concatenated_examples字典中的每个键值对
        for k, t in concatenated_examples.items()
    }
    
    # 如果完型填空任务需要使用标签,则将标签复制到结果字典中
    result["labels"] = result["input_ids"].copy()
    
    # 返回分割后的结果
    return result

使用整除运算符(//)计算每个chunk的长度,然后乘以chunk_size这个就是说如果小于128 整除后就得0,就没了

  train: Dataset({
        features: ['input_ids', 'attention_mask', 'word_ids', 'labels'],
        num_rows: 61291
    })
    test: Dataset({
        features: ['input_ids', 'attention_mask', 'word_ids', 'labels'],
        num_rows: 59904
    })
    unsupervised: Dataset({
        features: ['input_ids', 'attention_mask', 'word_ids', 'labels'],
        num_rows: 122957
    })
})

会发现数据量大了

3.完形填空训练

from transformers import DataCollatorForLanguageModeling  # 从transformers库中导入DataCollatorForLanguageModeling类

data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm_probability=0.15)  # 创建一个数据收集器

然后再举个例子看看mask长啥样

samples = [lm_datasets["train"][i] for i in range(2)]  # 从训练数据中选择2个样本
for sample in samples:
    _ = sample.pop("word_ids")  # 移除样本中的"word_ids"键,因为发现没啥用
    print(sample)
 for chunk in data_collator(samples)["input_ids"]:
 print(f"\n'>>> {tokenizer.decode(chunk)}'")#tokenizer.decode(chunk)是为了让被隐藏的更明显点,所以直接decode出来
 print(len(chunk))

训练过程

from transformers import TrainingArguments  # 从transformers库中导入TrainingArguments类

batch_size = 64  # 定义训练和评估时的批次大小
# 计算每个epoch打印结果的步数
logging_steps = len(downsampled_dataset["train"]) // batch_size
model_name = model_checkpoint.split("/")[-1]  # 从模型检查点路径中提取模型名称

training_args = TrainingArguments(
    output_dir=f"{model_name}-finetuned-imdb",  # 指定输出目录,其中包含微调后的模型和日志文件
    overwrite_output_dir=True,  # 是否覆盖现有的输出目录
    evaluation_strategy="epoch",  # 指定评估策略,这里为每个epoch评估一次
    learning_rate=2e-5,  # 学习率
    weight_decay=0.01,  # 权重衰减系数
    per_device_train_batch_size=batch_size,  # 每个GPU的训练批次大小
    per_device_eval_batch_size=batch_size,  # 每个GPU的评估批次大小
    logging_steps=logging_steps,  # 指定每个epoch打印结果的步数
    num_train_epochs=1,  # 指定训练的epoch数量
    save_strategy='epoch',  # 指定保存策略,这里为每个epoch保存一次模型
)

生成的模型在这里插入图片描述

from transformers import Trainer  # 从transformers库中导入Trainer类

trainer = Trainer(
    model=model,  # 指定要训练的模型实例
    args=training_args,  # 指定训练参数对象
    train_dataset=downsampled_dataset["train"],  # 指定训练数据集
    eval_dataset=downsampled_dataset["test"],  # 指定评估数据集
    data_collator=data_collator,  # 指定数据收集器
)

评估标准使用困惑度

import math  # 导入math模块,用于计算对数和指数

eval_results = trainer.evaluate()  # 使用Trainer的evaluate方法评估模型

print(f">>> Perplexity: {math.exp(eval_results['eval_loss']):.2f}")  # 打印评估结果中的对数

人话就是你不得在mask那挑啥词合适吗,平均挑了多少个才能答对

训练模型

trainer.train() 
eval_results = trainer.evaluate()
print(f">>> Perplexity: {math.exp(eval_results['eval_loss']):.2f}")

发现困惑度降低了

from transformers import AutoModelForMaskedLM

model_checkpoint  = "./distilbert-base-uncased"
model = AutoModelForMaskedLM.from_pretrained("./distilbert-base-uncased-finetuned-imdb/checkpoint-157")

加载自己的模型
import torch # 导入torch库,用于处理张量

使用分词器将文本转换为模型的输入格式

参数 return_tensors=“pt” 表示返回PyTorch张量格式

inputs = tokenizer(text, return_tensors=“pt”)

执行模型预测

# model 是一个预训练的BERT模型实例
# **inputs 表示将inputs字典中的所有键值对作为关键字参数传递给model
token_logits = model(**inputs).logits

# 找到遮蔽词在输入中的索引
# inputs["input_ids"] 是模型输入的词汇索引张量
# tokenizer.mask_token_id 是遮蔽词的词汇索引
mask_token_index = torch.where(inputs["input_ids"] == tokenizer.mask_token_id)[1]

# 获取遮蔽词的预测logits
# mask_token_index 是遮蔽词在输入中的索引张量
# token_logits 是模型输出的预测logits张量
mask_token_logits = token_logits[0, mask_token_index, :]

# 找到前5个最可能的替换词
# torch.topk 函数用于找到最大k个值及其索引
# dim=1 表示在第二个维度(即词汇维度)上进行排序
top_5_tokens = torch.topk(mask_token_logits, 5, dim=1).indices[0].tolist()

# 打印每个最可能的替换词及其替换后的文本
for token in top_5_tokens:
    # 使用 tokenizer.decode 方法将索引转换为文本
    # text 是原始文本
    # tokenizer.mask_token 是遮蔽词
    # [token] 是替换词的索引列表
    print(f"'>>> {text.replace(tokenizer.mask_token, tokenizer.decode([token]))}'")
'>>> This is a great deal.'
'>>> This is a great idea.'
'>>> This is a great adventure.'
'>>> This is a great film.'
'>>> This is a great movie.'

可以看到结果和上面的通用的不一样了,这里是film movie这些针对你的训练数据的了--------

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

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

相关文章

C++迭代器 iterator详解

目录 什么是迭代器 迭代器的类型 迭代器的用法 三种迭代器 范围for 什么是迭代器 它提供了一种访问容器(如列表、集合等)中元素的方法,而无需暴露容器的内部表示。迭代器使得程序员能够以统一的方式遍历不同的数据结构,而无需…

项目集成sharding-jdbc

目录 项目集成sharding-jdbc 1.业务分析 2.数据库构建 3.分库分表策略 项目配置默认数据源 一:导入sharding-jdbc依赖 二:在application文件中编写配置 三:注释掉主配置文件中配置的数据源 注意:这里添加了spring.main.allow…

基于51单片机的矿井安全检测系统

基于51单片机的矿井安全检测系统使用51单片机作为系统主控,LCD1602进行显示同时系统集成了ADC0808和烟雾传感器、甲烷传感器,二者结合测量环境烟雾值,同时使用DHT11温湿度传感器获取环境温湿度值,使用L298N驱动风扇,利…

2009考研数学真题解析-数二:

第一题: 解析:先找间断点:分母不能等于0,分母是sinΠx, 因此不难看出间断点是x0,-1,-2,-3。。。。。 接着一个一个来算这些点是什么间断点。 ,从x趋于2开始,分…

2024年一区极光优化+分解+深度学习!VMD-PLO-Transformer-GRU多变量时间序列光伏功率预测

2024年一区极光优化分解深度学习!VMD-PLO-Transformer-GRU多变量时间序列光伏功率预测 目录 2024年一区极光优化分解深度学习!VMD-PLO-Transformer-GRU多变量时间序列光伏功率预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.中秋献礼&#…

FiBiNET模型实现推荐算法

1. 项目简介 A031-FiBiNET模型项目是一个基于深度学习的推荐系统算法实现,旨在提升推荐系统的性能和精度。该项目的背景源于当今互联网平台中,推荐算法在电商、社交、内容分发等领域的广泛应用。推荐系统通过分析用户的历史行为和兴趣偏好,预…

小球轻重的测量

设有12个小球。其中11个小球的重量相同,称为好球;有一个小球的重量与11个好球的重量不同(或轻或重),称这个小球为坏球。试编写一个算法,用一个无砝码的天平称三次找出这个坏球,并确定其比好球轻…

GAMES101(15节,辐射,BRDF)

Irradiance辐射度量学 辐射度量学在渲染领域,可以帮助理解基于物理的光照模型 radiant energy辐射能量Q,累计总能量(单位J joule焦耳),就像太阳能板,光照时间越长接收能量越多,收到的能量总和…

02_RabbitMQ消息丢失解决方案及死信队列

一、数据丢失 第一种:生产者弄丢了数据。生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络问题,都有可能。 第二种:RabbitMQ 弄丢了数据。MQ还没有持久化自己挂了。 第三种:消费端…

Attention is All You Need精读

原文开头,不是搬运 dog。All attention is all you need Abstract 摘要 这篇文章的内容源于基于编码器-解码器架构的RNN模型,在其他人的工作中,我们可以发现注意力机制对于提升编码器-解码器架构模型的性能很重要。这篇文章提出了一个比较简…

《代码整洁之道:程序员的职业素养》

作者:【美】Robert C. Martin 第1章 专业主义 专业主义就意味着担当责任,软件开发太复杂了,不可能没什么 bug。但很不幸,这并不能为你开脱。人体太复杂了,不可能尽知其全部,但医生仍要发誓不伤害病人。如…

隐藏excel单元格数据的两个方法

在Excel中,公式是用来计算数据和结果的非常重要的一部分。但是,有时候您可能希望隐藏公式,以保护其不被他人修改或查看。那么今天小编就来给大家分享隐藏excel单元格数据的方法。 一、使用“隐藏”功能 在Excel中,我们还可以使用…

ZYNQ学习--AXI总线协议

一、AXI 总线简介 AXI(Advanced Extensible Interface)高级拓展总线是AMBA(Advanced Microcontroller Bus Architecture)高级微控制总线架构中的一个高性能总线协议,由ARM公司开发。AXI总线协议被广泛应用于高带宽、低…

大语言模型超参数调优:开启 AI 潜能的钥匙

前言 在人工智能的广袤领域中,大语言模型(LLM)凭借其强大的实力,不断重塑着我们对机器理解语言的认知。然而,要使这些模型在特定应用场景中发挥最大效能,关键在于巧妙调整其超参数。本文将引领你深入探究 …

x-cmd pkg | bat: cat 命令现代化替代品,终端用户必备工具

目录 简介快速上手安装使用与第三方工具组合使用 功能特点竞品和相关作品进一步阅读 简介 bat 是由 github.com/sharkdp 用 Rust 开发的 cat 命令现代化替代品。它比 cat 命令扩展了更多的现代化功能,如语法高亮、自动分页、Git集成等,能为用户提供更为…

python如何跨文件调用自己定义的函数

当自己定义函数过多时,只有一个python文件时代码会很长,不易理清代码框架,比如下面这段代码,如何隐藏具体函数细节呢?也就是把def函数放到另外一个python文件里步骤如下: 一个python文件代码篇幅过长 imp…

结构体对齐、函数传参、库移植

结构体字节对齐 按固定位大小匹配地址&#xff0c;a:10b:1020位 <32位4字节 202040位>32位 所以ab20作为一个int型&#xff0c;int c:20 单独做4个字节&#xff08;int&#xff09; 101020 &#xff08;int&#xff09;4个字节 &#xff0c;20&#xff08;int&#x…

算法之逻辑斯蒂回归(Logistic regression)

简介&#xff1a;个人学习分享&#xff0c;如有错误&#xff0c;欢迎批评指正。 逻辑斯蒂回归&#xff08;Logistic Regression&#xff09;是统计学中一种广泛应用于二分类问题的算法。它的主要目标是预测二分类问题中的事件发生的概率。尽管名字里有“回归”&#xff0c;但逻…

wordpress迁移到别的服务器

wordpress论坛网站搭建 于2023/11/16写的该文章 一-配置环境 配置LNMP&#xff08;linuxnginxmysqlphpphpmyadmin&#xff09;环境或者LAMP&#xff08;apache&#xff09; 可以选择集成了这些软件的套件 下载链接&#xff1a;https://www.xp.cn/download.html 手动下载这…

https加密原理

以为http的数据都是以明文传送&#xff0c;会有很大的安全问题&#xff0c;所以出现的https协议。https就是在http协议的基础上增加了一个安全层&#xff0c;可以对数据进行加密和解密(例如SSL、TLS等)。 https加密解密的原理&#xff1a;证书非对称加密对称加密 在讲解原理前…