【Python】科研代码学习:五 Data Collator,Datasets Data Collator Default data collator DefaultDataCollator DataCollatorWithPadding 其他 Data Collator Datasets
Data Collator
HF官网API:Data Collator Transformers源码阅读:transformers data_collator小记 提到输入训练集/验证集数据 ,就基本绕不开 Data Collator
它的作用是将多个数据进行批处理(Batch) ,并转换成 train_dataset
和 eval_dataset
相同的数据类型 为了让它工作顺利,可能会做一些处理(padding
/ random masking
) 但是我发现,在 Datasets
的一些API中,或者单独使用 Data Collator
的情况很少啊 再仔细查看发现,其作用主要是 给 Trainer
的初始化创建提供了一个 Data Collator
,让 Trainer
在训练和评估的时候会自己去对数据进行批处理或特殊处理 下面看一下 Data Collator 里面的东西吧。
Default data collator
首先,它是一个方法,首先 输入类型,其实就是一个任意的列表 InputDataClass = NewType("InputDataClass", Any)
然后可以指定用 pytorch / tensorflow / numpy
中的一个版本,大部分都是使用 pt
发现,首先他把 features
也就是输入通过 vars()
转成了字典 然后它处理了标签 ,也就是 label
或 label_ids
看下API描述: label: handles a single value (int or float) per object label_ids: handles a list of values per object 哦,就是单标签和多标签的区别。 最后做了些类型转换 ,输出打包为 Dict[str, Any]
DefaultDataCollator
上面是一个函数,这里是一个类(需要实例化) 调用它相当于调用了上述的函数
DataCollatorWithPadding
如果不知道 Padding的,可以看一下后面的补充知识 这里看一下源码和参数含义 需要提供 tokenizer
,以及 padding
策略。其他过程和上述 DefaultDataCollator
差不多。
Padding
知乎:LLM padding 细节 可以翻译成对齐吧 简单来说就是,输入经过词嵌入后,产生的 List[int]
词嵌入数组长度不一致,很难进行并行处理 我们通过把所有数组长度统一到其中最长的那个数组长度 ,也就是其中添加 tokenizer.pad_token
即可。 例如 tokenizer(prompts, return_tensors="pt", padding=True)
,其中 attention_mask 中的 0 表示 padding
但是 padding 会增加无用字符,浪费训练资源,所以还有其他不用 padding 的训练方式。 其他的技术细节请参考上述知乎链接。
其他 Data Collator
针对不同任务,也提供了不同的 Data Collator
,看一眼吧: DataCollatorForTokenClassification
:给token分类的 DataCollatorForSeq2Seq
:给s2s任务的 DataCollatorForLanguageModeling
:给LM用的,mlm
参数给 MLM任务使用 DataCollatorForWholeWordMask
:给LM用的,(used for language modeling that masks entire words) DataCollatorForPermutationLanguageModeling
:给(permutation language modeling)用的
Datasets
HF官网API:Datasets 前面介绍的都在 transformers
库里的,而这个是在 Datasets
库的 主要功能就是从 HF 中加载与上传数据集,给 Audio,CV,NLP任务用途的。 它比较简单,最主要的方法也就是下面这个
load_dataset
来看一下源码 它参数比较多,我就选择重要参数介绍吧。详细请去API查看 path
:数据集的名字 (请去HF中查找)或本地路径 (json, csv, text等格式)或数据集脚本 ( dataset script,一个py文件) split
:默认 None
,不划分训练集和测试集,最终直接返回一个 DatasetDict
。若指定 train / test / validation
(这个真难找,图片在下方),则返回 Dataset
类型。 data_dir
:设置保存路径。 看一下例子: 通过HF加载数据集 (ds = dataset缩写,是一个规范)
from datasets import load_dataset
ds = load_dataset( 'rotten_tomatoes' , split= 'train' ) data_files = { 'train' : 'train.csv' , 'test' : 'test.csv' }
ds = load_dataset( 'namespace/your_dataset_name' , data_files= data_files)
通过本地加载数据集,通过 csv / json / loading_script
加载
from datasets import load_dataset
ds = load_dataset( 'csv' , data_files= 'path/to/local/my_dataset.csv' ) from datasets import load_dataset
ds = load_dataset( 'json' , data_files= 'path/to/local/my_dataset.json' ) from datasets import load_dataset
ds = load_dataset( 'path/to/local/loading_script/loading_script.py' , split= 'train' )
如果通过自动下载后,可以使用下面方法来设置数据存储到本地目录 通过 save_to_disk
存到本地后,需要使用 load_from_disk
加载
dataset. save_to_disk( dataset_dict_path= './data/ChnSentiCorp' )
dataset = load_from_disk( './data/ChnSentiCorp' )
其他一些基本操作
HuggingFace学习笔记(3) 数据集工具datasets 参考上面的知乎笔记,可以学到一些内容: 1)dataset = dataset['train']
可以直接获得其中的训练子集 2)Dataset
内核和 pandas.dataframe
差不多 3)索引 :ds[i]
取出第 i 条记录 4)排序 :sorted_ds = ds.sort("colum_name")
5)打乱 :shuffled_ds = ds.shuffle(seed=42)
6)采样 :ds.select([0,10,11,...])
表示拿出哪些记录 7)训练测试集拆分 :ds.train_test_split(test_size=0.1)
,即9:1拆成训练集与测试集 8)重命名列 :ds.rename_column('bef', 'aft')
9)删除列 :ds.remove_columns(['colum_name'])
10)过滤 :dataset.filter(func)
比如
def func ( data) : return data[ 'text' ] . startswith( '非常不错' )
11)遍历修改 :new_ds = ds.map(func)
,这个比较常用 比如
def f ( data) : data[ 'text' ] = 'My sentence: ' + data[ 'text' ] return data
12)批处理加速 :filter()、map()两个函数都支持批处理加速 添加如下关键词即可,注意 num_proc
表示使用的进程数。
maped_datatset = dataset. map ( function= f, batched= True , batch_size= 1000 , num_proc= 4 )