返回介绍

数学基础

统计学习

深度学习

工具

Scala

一、基本概念

发布于 2023-07-17 23:38:23 字数 15882 浏览 0 评论 0 收藏 0

  1. Datasets 是一个用于轻松地访问和共享数据集的库,这些数据集是关于音频、计算机视觉、以及自然语言处理等领域。

    Datasets 可以通过一行来加载一个数据集,并且可以使用 Hugging Face 强大的数据处理方法来快速准备好你的数据集。在 Apache Arrow 格式的支持下,通过 zero-copy read 来处理大型数据集,而没有任何内存限制,从而实现最佳速度和效率。

  2. Arrow 是一种特定的数据格式,以列式的 memory layout 存储数据。这提供了几个显著的优势:

    • Arrow 的标准格式允许 zero-copy read,这实际上是消除了所有的序列化开销。
    • Arrow 是语言无关的,它支持不同的编程语言。
    • Arrow 是面向列的,因此在查询和处理数据切片或列时,它的速度更快。
    • Arrow 允许 copy-free 地移交给标准的机器学习工具,如 Numpy, Pandas, PyTorch, TensorFlow
    • Arrow 支持多种列类型(可能是嵌套类型)。
  3. Datasets 使用 Arrow 作为它的局部缓存系统,这允许 datasetson-disk cache 来支持,这是用于 fast lookup 的内存映射。这种架构允许在设备内存相对较小的机器上使用大型数据集。

    
    import os
    import psutil
    import timeit
    from datasets import load_dataset
    
    
    # Process.memory_info 为字节,因此需要转换为 MB
    mem_before = psutil.Process(os.getpid()).memory_info().rss / (1024 * 1024)
    wiki = load_dataset("wikipedia", "20220301.en", split="train")
    mem_after = psutil.Process(os.getpid()).memory_info().rss / (1024 * 1024)
    print(f"RAM memory used: {(mem_after - mem_before)} MB")
    # RAM memory used: 50 MB

    Arrow 数据实际上是从磁盘进行内存映射的,而不是加载到内存中。内存映射允许访问磁盘上的数据,并利用虚拟内存功能进行 fast lookup

    
    
    xxxxxxxxxx
    s = """batch_size = 1000 for i in range(0, len(wiki), batch_size): batch = wiki[i:i + batch_size] """ time = timeit.timeit(stmt=s, number=1, globals=globals()) print(f"Time to iterate over the {wiki.dataset_size >> 30} GB dataset: {time:.1f} sec, ie. {float(wiki.dataset_size >> 27)/time:.1f} Gb/s") # Time to iterate over the 18 GB dataset: 70.5 sec, ie. 2.1 Gb/s

    在使用 Arrow 的内存映射数据集上进行迭代,速度很快。

  4. 安装:

    
    
    xxxxxxxxxx
    pip install datasets conda install -c huggingface -c conda-forge datasets

    如果希望安装 Audio 特性,执行命令:

    
    
    xxxxxxxxxx
    pip install datasets[audio] sudo apt-get install libsndfile1 # 手动安装 libsndfile pip install 'torchaudio<0.12.0' # 对 MP3 的支持 sudo apt-get install sox # 对 MP3 的支持

    如果希望安装 Image 特性,执行命令:

    
    
    xxxxxxxxxx
    pip install datasets[vision]
  5. 音频数据集就像文本数据集一样被加载。然而,音频数据集的预处理略有不同。你需要一个 feature extractor ,而不是一个 tokenizer 。音频输入也可能需要重新采样其采样率,从而匹配你正在使用的预训练模型的采样率。

    例如:

    
    
    xxxxxxxxxx
    from datasets import load_dataset, Audio from transformers import AutoFeatureExtractor #### feature extractor feature_extractor = AutoFeatureExtractor.from_pretrained("facebook/wav2vec2-base") def preprocess_function(examples): audio_arrays = [x["array"] for x in examples["audio"]] inputs = feature_extractor( audio_arrays, sampling_rate=16000, padding=True, max_length=100000, truncation=True, ) return inputs dataset = load_dataset("PolyAI/minds14", "en-US", split="train") dataset = dataset.cast_column("audio", Audio(sampling_rate=16000)) # 重新采样 dataset = dataset.map(preprocess_function, batched=True) # 逐样本地抽取特征 dataset = dataset.rename_column("intent_class", "labels") #### Pytorch from torch.utils.data import DataLoader dataset.set_format(type="torch", columns=["input_values", "labels"]) dataloader = DataLoader(dataset, batch_size=4) #### TensorFlow import tensorflow as tf tf_dataset = dataset.to_tf_dataset( columns=["input_values"], label_cols=["labels"], batch_size=4, shuffle=True)
  6. 同样地,图像数据集就像文本数据集一样被加载。图像数据集也需要一个 feature extractor ,而不是一个 tokenizer 。对图像进行数据增强在计算机视觉中很常见,你可以随意使用任何数据增强的库。

    例如:

    
    
    xxxxxxxxxx
    from datasets import load_dataset, Image from torchvision.transforms import Compose, ColorJitter, ToTensor #### 数据增强 jitter = Compose([ColorJitter(brightness=0.5, hue=0.5), ToTensor()]) def transforms(examples): examples["pixel_values"] = [jitter(image.convert("RGB")) for image in examples["image"]] return examples dataset = load_dataset("beans", split="train") dataset = dataset.with_transform(transforms) #### Pytorch from torch.utils.data import DataLoader def collate_fn(examples): images = [] labels = [] for example in examples: images.append((example["pixel_values"])) labels.append(example["labels"]) pixel_values = torch.stack(images) labels = torch.tensor(labels) return {"pixel_values": pixel_values, "labels": labels} dataloader = DataLoader(dataset, collate_fn=collate_fn, batch_size=4)
  7. 文本数据集需要一个 tokenizer

    例如:

    
    
    xxxxxxxxxx
    from datasets import load_dataset from transformers import AutoTokenizer dataset = load_dataset("glue", "mrpc", split="train") tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased") #### 编码 def encode(examples): return tokenizer(examples["sentence1"], examples["sentence2"], truncation=True, padding="max_length") dataset = dataset.map(encode, batched=True) dataset = dataset.map(lambda examples: {"labels": examples["label"]}, batched=True) #### Pytorch import torch dataset.set_format(type="torch", columns=["input_ids", "token_type_ids", "attention_mask", "labels"]) dataloader = torch.utils.data.DataLoader(dataset, batch_size=32) #### TensorFlow import tensorflow as tf from transformers import DataCollatorWithPadding data_collator = DataCollatorWithPadding(tokenizer=tokenizer, return_tensors="tf") tf_dataset = dataset.to_tf_dataset( columns=["input_ids", "token_type_ids", "attention_mask"], label_cols=["labels"], batch_size=2, collate_fn=data_collator, shuffle=True)
  8. Hugging Face Hub 包含了很多数据集,我们可以从 Hub 上下载和上传数据集。

    • 下载数据集:

      
      
      xxxxxxxxxx
      from datasets import load_dataset dataset = load_dataset("glue", "mrpc")
    • 上传数据集:

      首先安装必要的库:

      
      
      xxxxxxxxxx
      pip install huggingface_hub

      然后再命令行中登录 Hugging Face 账户:

      
      
      xxxxxxxxxx
      huggingface-cli login

      最后在代码中上传数据集:

      
      
      xxxxxxxxxx
      dataset.push_to_hub("huaxz/dataset_demo")
  9. Datasets 会存储以前下载和处理的数据集,因此当你需要再次使用它们时,可以直接从 cache 中重新加载它们。这避免了重新下载数据集或重新应用处理函数。

    Datasetscache 文件分配一个指纹 fingerprint 。指纹跟踪数据集的当前状态。初始指纹是使用来自Arrow table 的哈希、或 Arrow files 的哈希 (如果数据集在磁盘上)来计算的。通过组合前一状态的指纹、以及哈希最近应用的变换,从而计算随后的指纹。

    
    
    xxxxxxxxxx
    from datasets import Datasets dataset1 = Datasets.from_dict({"a": [0, 1, 2]}) dataset2 = dataset1.map(lambda x: {"a": x["a"] + 1}) print(dataset1._fingerprint) # 85ad8fa07d5f63f5 print(dataset2._fingerprint) # 3761ff563081e590

    注意,需要确保所有的 transform 是可以 pickle 序列化或 dill 序列化的,否则 Datasets 使用一个随机的指纹并且抛出一个警告(此时 transformer 是不可哈希的)。

    当禁用缓存时,Datasets 会重新计算所有的内容。此时,每次都会生成缓存文件并将它们写入临时目录。Python session 结束时,临时目录中的缓存文件将被删除。

  10. Features 定义为数据集的内部结构,它用于指定底层的序列化格式。Features 包含了从列名和类型到ClassLabel 的所有高级信息,因此可以视为是数据集的 backbone

    Features 的格式很简单:dict[column_name, column_type] 。它是列名和列类型的字典。

    
    
    xxxxxxxxxx
    from datasets import load_dataset dataset = load_dataset('glue', 'mrpc', split='train') print(dataset.features) # {'sentence1': Value(dtype='string',>
  11. Batch mapping:以 batch mode 来执行 Dataset.map() 是非常强大的,可以加速数据预处理过程,并自由地控制生成的数据集的规模。

    但是,注意 batch 中每一列的行数应该相同:

    
    
    xxxxxxxxxx
    from datasets import Dataset dataset = Dataset.from_dict({"a": [0, 1, 2]}) # batch 中, 新的列 b 有 6 行,而旧的列 a 有 3 行, 抛出异常 dataset.map(lambda batch: {"b": batch["a"] * 2}, batched=True) # ArrowInvalid: Column 1 named b expected length 3 but got length 6' dataset_with_duplicates = dataset.map(lambda batch: {"b": batch["a"] * 2}, remove_columns=["a"], batched=True)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文