Hugging Face实战

编程入门 行业动态 更新时间:2024-10-26 10:40:31

Hugging Face<a href=https://www.elefans.com/category/jswz/34/1769775.html style=实战"/>

Hugging Face实战

🚩🚩🚩Hugging Face 实战系列 总目录

有任何问题欢迎在下面留言
本篇文章的代码运行界面均在Jupyter Notebook中进行
本篇文章配套的代码资源已经上传

Hugging Face实战-系列教程10:文本预训练模型构建1
Hugging Face实战-系列教程12:文本预训练模型构建3

3、imdb影评数据集

  1. ​让预训练模型换个领域,训练影评数据
  2. 对模型进行微调,用开源预训练的模型训练另一个开源数据集

首先你需要安装datasets模块:

pip install datasets

加载imdb开源数据集,imdb是一个专门的影评数据集,在后续我会陆续更新怎么做分类、摘要、文本生成、命名实体识别,然后我们对电影进行一个情感分析,是消极还是积极的2分类任务,这组数据集有完整的标签对应。一共有25000个样本,每个样本都对应一个标签,但是由于我们是做一个微调的模型,是模型有一个下游任务具体的通用能力。所以不需要使用这个标签,只需要文本就行了。

from datasets import load_dataset
imdb_dataset = load_dataset("imdb")
imdb_dataset

代码太简单不解释了,打印一下这个数据集:
初次运行会先下载:

这里需要注意的是,下载是需要梯子的,如果没有的话可能无法下载。打印结果

DatasetDict({
  train: Dataset({
    features: [‘text’, ‘label’],
    num_rows: 25000})
  test: Dataset({
    features: [‘text’, ‘label’],
    num_rows: 25000})
  unsupervised: Dataset({
    features: [‘text’, ‘label’],
    num_rows: 50000})
})

里面有两个字段,一个是text一个是label,text是文本label是标签,这是一个情感分类的任务,用户评论电影,评价电影好就是积极的,不好就是消极的。
随机采样3个

sample = imdb_dataset["train"].shuffle(seed=42).select(range(3))
for row in sample:print(f"\n'>>> Review: {row['text']}'")print(f"'>>> Label: {row['label']}'")
  • 从数据集中取出训练集,定义随机种子,取出3个样本
  • 遍历三个样本
  • 打印文本
  • 打印标签
    打印结果:

4、数据集处理方法

  • 计算每一个文本的长度(word_ids)
  • 指定chunk_size,然后将所有数据按块进行拆分

从3中可以得知,一条文本数据是比较长的,我们迭代每条数据的时候,需要保证每条数据都是一样长的。如果设置成是512长度,那些很短的文本可能需要补充特别多的0,本文的任务又是一个bert猜词的任务(不是分类哦),所以我们可以对长的文本进行截断处理就行了,因为当前任务只是需要锻炼出模型的语言能力。
所以这个数据集的文本都进行截断处理,截断长度为128,原来有500长度的文本可能就被截断成3条文本数据了。

4.1 tokenizer分词

def tokenize_function(examples):result = tokenizer(examples["text"])if tokenizer.is_fast:result["word_ids"] = [result.word_ids(i) for i in range(len(result["input_ids"]))]return result
  1. 传进来一条文本
  2. tokenizer分词,text是指定的字段
  3. word_ids可以不用管了

用map方法执行:

完形填空,不需要标签

tokenized_datasets = imdb_dataset.map(tokenize_function, batched=True, remove_columns=["text", "label"]
)
tokenized_datasets

map操作是对这个数据的每一个样本都进行了这样的操作,batched表示批量处理,tokenizer分词处理结果是id,得到这个id即可,文本就不需要了,label也是不要的,因为都删除
打印结果:

DatasetDict({
  train: Dataset({
    features: [‘input_ids’, ‘attention_mask’, ‘word_ids’],
    num_rows: 25000})
  test: Dataset({
    features: [‘input_ids’, ‘attention_mask’, ‘word_ids’],
    num_rows: 25000})
  unsupervised: Dataset({
    features: [‘input_ids’, ‘attention_mask’, ‘word_ids’],
    num_rows: 50000})
})

4.2 设计切分思路

预训练模型能设置的最大值

print(tokenizer.model_max_length)

512

完型填空中尤其我们只需要填空就好了,为了不截断数据和整一堆没用的padding,直接把所有数据首尾拼接,然后指定个固定长度就可以的。如何切分是自己定的,目的就是为了统一长度,定的太长,短句子会添加太多0,定的太短,长句子丢失太多信息,由于我们是mask预测任务,所以可以定成128,长的句子截断成几个句子处理。

打印三个句子的长度:

chunk_size = 128
tokenized_samples = tokenized_datasets["train"][:3]
for idx, sample in enumerate(tokenized_samples["input_ids"]):print(f"'>>> Review {idx} length: {len(sample)}'")
  1. 设置句子长度为128
  2. 取出train数据中的前三条数据
  3. 遍历这三条数据
  4. 打印当前遍历句子长度

打印结果:

‘>>> Review 0 length: 363’
‘>>> Review 1 length: 304’
‘>>> Review 2 length: 133’

计算三句子的总长度,一会要拼起来:

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’

  1. 使用列表推导式,遍历tokenized_samples的键([‘input_ids’, ‘attention_mask’, ‘word_ids’])记为k,当前键对应的值添加到一个空list中,以k为键、这个list为值添加到concatenated_examples 这个字典中。
  2. 计算concatenated_examples中键为input_ids的值对应的长度
  3. 打印长度

打印结果:

dict_keys([‘input_ids’, ‘attention_mask’, ‘word_ids’])
‘>>> Concatenated reviews length: 800’

4.3执行切分操作

按照设置的128进行分块:

chunks = {k: [t[i : i + chunk_size] for i in range(0, total_length, chunk_size)]for k, t in concatenated_examples.items()
}
for chunk in chunks["input_ids"]:print(f"'>>> Chunk length: {len(chunk)}'")
  1. 构建一个字典chunks ,键与值是一个很长的列表推导式得到
    1. for k, t in concatenated_examples.items(),表示将concatenated_examples进行遍历,每次遍历的元素,包含键(记为k)和值(记为t),其中k继续作为chunks 字典的键
    2. [t[i : i + chunk_size] for i in range(0, total_length, chunk_size)]是一个list表示为chunks 字典的值。
    3. t是包含一条文本中很多元素,按照索引[i : i + chunk_size] 来取元素,而这个索引又是一个列表推导式
    4. (0, total_length, chunk_size)则表示从0开始,每次增加chunk_size=128次,一直到total_length=800为止。按照这样取索引的方式对t进行取值,最后保存为一个list作为chunks 字典的值
  2. chunks字典的input_ids键对应的值是一个二维list,遍历这个二维list得到一维list,将每个一维list的长打印出来。

打印结果:

‘>>> Chunk length: 128’
‘>>> Chunk length: 128’
‘>>> Chunk length: 128’
‘>>> Chunk length: 128’
‘>>> Chunk length: 128’
‘>>> Chunk length: 128’
‘>>> Chunk length: 32’

4.4 处理整个数据集

上面的这些内容只是为了分解做理解,把上面的内容打包成一个函数,对整个数据集都做这样的处理:

def group_texts(examples):# 拼接到一起concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()}# 计算长度total_length = len(concatenated_examples[list(examples.keys())[0]])# //就相当于咱们不要最后多余的了total_length = (total_length // chunk_size) * chunk_size# 切分result = {k: [t[i : i + chunk_size] for i in range(0, total_length, chunk_size)]for k, t in concatenated_examples.items()}# 完型填空会用到标签的,也就是原文是啥result["labels"] = result["input_ids"].copy()return result
  1. 首先还是将所有文本都拼接到一起
  2. 计算总长度
  3. total_length // chunk_size),双斜杠的意思是最后一个不足128的不要了,重新调整了总长度
  4. 按照刚刚的方法进行切分
  5. 原来的文本中,标签是什么呢?应该就是原来被mask掉的文本,所以标签是和原来的id是一样的

使用map方法执行这个函数:

lm_datasets = tokenized_datasets.map(group_texts, batched=True)
lm_datasets

打印结果:

DatasetDict({
  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
}) })

现在的数据更多了,做切分之前是2万5千现在是6万多

tokenizer.decode(lm_datasets["train"][1]["input_ids"])

“as the vietnam war and race issues in the united states. in between asking politicians and ordinary denizens of stockholm about their opinions on politics, she has sex with her drama teacher, classmates, and married men. < br / > < br / > what kills me about i am curious - yellow is that 40 years ago, this was considered pornographic. really, the sex and nudity scenes are few and far between, even then it’s not shot like some cheaply made porno. while my countrymen mind find it shocking, in reality sex and nudity are a major staple in swedish cinema. even ingmar bergman,”

打印出来的结果很明显这句话还没有讲完,后面还有逗号呢
Hugging Face实战-系列教程10:文本预训练模型构建1
Hugging Face实战-系列教程12:文本预训练模型构建3

更多推荐

Hugging Face实战

本文发布于:2024-02-13 01:39:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1690211.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:实战   Hugging   Face

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!