35、深入探索数据处理与模型构建

深入探索数据处理与模型构建

1. 文本分类数据准备

在数据处理过程中,我们常常会遇到输入和目标分离为两个独立对象的情况,这并非我们所期望的。而 Datasets 可以解决这个问题。

Datasets 能够并行地对同一个原始对象应用两个或更多的转换管道,并将结果组合成一个元组。它会自动完成设置工作,当我们对 Datasets 进行索引操作时,会得到一个包含每个管道结果的元组。

以下是文本分类数据准备的具体步骤:
1. 定义转换管道

x_tfms = [Tokenizer.from_folder(path), Numericalize]
y_tfms = [parent_label, Categorize()]
  1. 创建 Datasets 对象
dsets = Datasets(files, [x_tfms, y_tfms], splits=splits)
  1. 解码处理后的元组
t = dsets.valid[0]
dsets.decode(t)
  1. 转换为 DataLoaders
dls = dsets.dataloaders(bs=64, before_batch=pad_input)

DataLoader 负责将数据集中的项目整理成批次,它有几个重要的自定义点:
| 自定义点 | 作用 |
| ---- | ---- |
| after_item | 在从数据集中获取每个项目后应用,等同于 DataBlock 中的 item_tfms |
| before_batch | 在项目整理成批次之前应用,是对项目进行填充以使其大小一致的理想位置 |
| after_batch | 在批次构建完成后应用,等同于 DataBlock 中的 batch_tfms |

完整的文本分类数据准备代码如下:

tfms = [[Tokenizer.from_folder(path), Numericalize], [parent_label, Categorize]]
files = get_text_files(path, folders = ['train', 'test'])
splits = GrandparentSplitter(valid_name='test')(files)
dsets = Datasets(files, tfms, splits=splits)
dls = dsets.dataloaders(dl_type=SortedDL, before_batch=pad_input)
2. 计算机视觉中的应用 - 暹罗对数据准备

暹罗模型需要处理两个图像,并判断它们是否属于同一类别。我们以宠物数据集为例,为预测两只宠物图像是否属于同一品种的模型准备数据。

  1. 获取图像数据
from fastai.vision.all import *
path = untar_data(URLs.PETS)
files = get_image_files(path/"images")
  1. 创建自定义类型 SiameseImage
class SiameseImage(Tuple):
    def show(self, ctx=None, **kwargs):
        img1,img2,same_breed = self
        if not isinstance(img1, Tensor):
            if img2.size != img1.size: img2 = img2.resize(img1.size)
            t1,t2 = tensor(img1),tensor(img2)
            t1,t2 = t1.permute(2,0,1),t2.permute(2,0,1)
        else: t1,t2 = img1,img2
        line = t1.new_zeros(t1.shape[0], t1.shape[1], 10)
        return show_image(torch.cat([t1,line,t2], dim=2),
                          title=same_breed, ctx=ctx)
  1. 测试 show 方法
img = PILImage.create(files[0])
s = SiameseImage(img, img, True)
s.show()

img1 = PILImage.create(files[1])
s1 = SiameseImage(img, img1, False)
s1.show()
  1. 应用变换
s2 = Resize(224)(s1)
s2.show()
  1. 构建 SiameseTransform
def label_func(fname):
    return re.match(r'^(.*)_\d+.jpg$', fname.name).groups()[0]

class SiameseTransform(Transform):
    def __init__(self, files, label_func, splits):
        self.labels = files.map(label_func).unique()
        self.lbl2files = {l: L(f for f in files if label_func(f) == l)
                          for l in self.labels}
        self.label_func = label_func
        self.valid = {f: self._draw(f) for f in files[splits[1]]}
    def encodes(self, f):
        f2,t = self.valid.get(f, self._draw(f))
        img1,img2 = PILImage.create(f),PILImage.create(f2)
        return SiameseImage(img1, img2, t)
    def _draw(self, f):
        same = random.random() < 0.5
        cls = self.label_func(f)
        if not same:
            cls = random.choice(L(l for l in self.labels if l != cls))
        return random.choice(self.lbl2files[cls]),same

splits = RandomSplitter()(files)
tfm = SiameseTransform(files, label_func, splits)
tfm(files[0]).show()
  1. 创建 TfmdLists DataLoaders
tls = TfmdLists(files, tfm, splits=splits)
show_at(tls.valid, 0)

dls = tls.dataloaders(after_item=[Resize(224), ToTensor],
    after_batch=[IntToFloatTensor, Normalize.from_stats(*imagenet_stats)])
3. 语言模型从零开始构建

在深入学习深度学习的过程中,我们从语言模型开始探索。首先,我们需要准备一个简单的数据集来快速原型化各种模型,这里我们使用 Human Numbers 数据集。

  1. 数据准备
from fastai.text.all import *
path = untar_data(URLs.HUMAN_NUMBERS)
path.ls()

lines = L()
with open(path/'train.txt') as f: lines += L(*f.readlines())
with open(path/'valid.txt') as f: lines += L(*f.readlines())

text = ' . '.join([l.strip() for l in lines])
tokens = text.split(' ')

vocab = L(*tokens).unique()
word2idx = {w:i for i,w in enumerate(vocab)}
nums = L(word2idx[i] for i in tokens)
  1. 创建序列数据
seqs = L((tensor(nums[i:i+3]), nums[i+3]) for i in range(0,len(nums)-4,3))
  1. 创建 DataLoaders
bs = 64
cut = int(len(seqs) * 0.8)
dls = DataLoaders.from_dsets(seqs[:cut], seqs[cut:], bs=64, shuffle=False)
  1. 构建神经网络架构
    我们使用三个标准线性层,但有两个调整:
    - 第一个线性层仅使用第一个单词的嵌入作为激活。
    - 第二个层使用第二个单词的嵌入加上第一层的输出激活。
    - 第三个层使用第三个单词的嵌入加上第二层的输出激活。
graph TD;
    A[输入三个单词] --> B[第一个线性层];
    B --> C[第二个线性层];
    C --> D[第三个线性层];
    D --> E[预测下一个单词的概率];

通过以上步骤,我们完成了文本分类、计算机视觉和语言模型的数据准备和模型构建的初步探索。这些方法和技术为我们进一步深入学习和实践提供了坚实的基础。

深入探索数据处理与模型构建

4. 技术点分析与总结

在上述的文本分类、计算机视觉和语言模型的实践中,涉及到了多个关键的技术点,下面我们对这些技术点进行详细分析和总结。

4.1 Datasets TfmdLists
  • 功能对比
    | 对象 | 功能 | 应用场景 |
    | ---- | ---- | ---- |
    | Datasets | 并行应用多个转换管道到同一原始对象,将结果组合成元组,可用于文本分类等场景 | 当需要同时处理输入和目标的转换时使用 |
    | TfmdLists | 应用单个转换管道到一组项目 | 当已经有一个能生成所需元组的转换时使用,如暹罗对数据处理 |
  • 使用流程
graph LR;
    A[原始数据] --> B[定义转换管道];
    B --> C{选择对象};
    C -->|Datasets| D[创建Datasets对象];
    C -->|TfmdLists| E[创建TfmdLists对象];
    D --> F[转换为DataLoaders];
    E --> F;
4.2 转换(Transform)
  • 关键方法
    • encodes :用于对输入进行编码转换,如 SiameseTransform 中的 encodes 方法将文件转换为 SiameseImage 对象。
    • decode :用于对编码结果进行解码,恢复原始数据格式。
    • setup :用于进行一些初始化设置,如在某些转换中创建词汇表等。
  • 自定义转换示例
    在暹罗对数据处理中,我们自定义了 SiameseTransform ,其步骤如下:
    1. 初始化:根据文件和标签函数,创建标签到文件的映射,以及验证集的固定抽取结果。
      python def __init__(self, files, label_func, splits): self.labels = files.map(label_func).unique() self.lbl2files = {l: L(f for f in files if label_func(f) == l) for l in self.labels} self.label_func = label_func self.valid = {f: self._draw(f) for f in files[splits[1]]}
    2. 编码:根据文件路径,抽取配对文件和标签,创建 SiameseImage 对象。
      python def encodes(self, f): f2,t = self.valid.get(f, self._draw(f)) img1,img2 = PILImage.create(f),PILImage.create(f2) return SiameseImage(img1, img2, t)
    3. 抽取函数:以 0.5 的概率抽取同一类或不同类的文件。
      python def _draw(self, f): same = random.random() < 0.5 cls = self.label_func(f) if not same: cls = random.choice(L(l for l in self.labels if l != cls)) return random.choice(self.lbl2files[cls]),same
4.3 DataLoaders
  • 自定义点
    • after_item :在从数据集中获取每个项目后应用,常用于图像的大小调整和转换为张量等操作。
    • before_batch :在项目整理成批次之前应用,如对文本序列进行填充以使其长度一致。
    • after_batch :在批次构建完成后应用,如将整数张量转换为浮点数张量并进行归一化。
  • 创建步骤
    1. Datasets TfmdLists 创建:
      ```python

    从Datasets创建

    dls = dsets.dataloaders(bs=64, before_batch=pad_input)

    从TfmdLists创建

    dls = tls.dataloaders(after_item=[Resize(224), ToTensor],
    after_batch=[IntToFloatTensor, Normalize.from_stats(*imagenet_stats)])
    ```

5. 实际应用建议

在实际应用中,我们可以根据不同的任务需求,灵活运用上述技术。以下是一些具体的建议:

5.1 文本分类
  • 数据准备 :使用 Datasets 并行处理输入文本和目标标签的转换,确保输入和目标的一致性。
  • 模型训练 :根据数据集的特点,选择合适的神经网络架构,如多层感知机或循环神经网络。
  • 优化技巧 :在 DataLoaders 中使用 before_batch 进行填充操作,提高训练效率。
5.2 计算机视觉 - 暹罗对
  • 自定义类型 :创建自定义类型如 SiameseImage ,方便数据的展示和处理。
  • 数据增强 :利用 after_item 对图像进行数据增强,如调整大小、旋转等。
  • 模型设计 :设计适合暹罗对任务的模型,如使用卷积神经网络提取图像特征。
5.3 语言模型
  • 数据集选择 :选择简单的数据集如 Human Numbers 进行快速原型开发,验证模型的可行性。
  • 模型架构 :使用线性层结合词嵌入,考虑上下文信息,提高语言模型的性能。
  • 训练策略 :使用 DataLoaders 进行数据批量处理,加速训练过程。

通过以上的深入分析和实践,我们对数据处理和模型构建有了更全面的理解。在实际应用中,我们可以根据具体任务需求,灵活运用这些技术,不断优化模型性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值