深入探索数据处理与模型构建
1. 文本分类数据准备
在数据处理过程中,我们常常会遇到输入和目标分离为两个独立对象的情况,这并非我们所期望的。而
Datasets
可以解决这个问题。
Datasets
能够并行地对同一个原始对象应用两个或更多的转换管道,并将结果组合成一个元组。它会自动完成设置工作,当我们对
Datasets
进行索引操作时,会得到一个包含每个管道结果的元组。
以下是文本分类数据准备的具体步骤:
1.
定义转换管道
x_tfms = [Tokenizer.from_folder(path), Numericalize]
y_tfms = [parent_label, Categorize()]
-
创建
Datasets对象
dsets = Datasets(files, [x_tfms, y_tfms], splits=splits)
- 解码处理后的元组
t = dsets.valid[0]
dsets.decode(t)
-
转换为
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. 计算机视觉中的应用 - 暹罗对数据准备
暹罗模型需要处理两个图像,并判断它们是否属于同一类别。我们以宠物数据集为例,为预测两只宠物图像是否属于同一品种的模型准备数据。
- 获取图像数据
from fastai.vision.all import *
path = untar_data(URLs.PETS)
files = get_image_files(path/"images")
-
创建自定义类型
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)
-
测试
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()
- 应用变换
s2 = Resize(224)(s1)
s2.show()
-
构建
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()
-
创建
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
数据集。
- 数据准备
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)
- 创建序列数据
seqs = L((tensor(nums[i:i+3]), nums[i+3]) for i in range(0,len(nums)-4,3))
-
创建
DataLoaders
bs = 64
cut = int(len(seqs) * 0.8)
dls = DataLoaders.from_dsets(seqs[:cut], seqs[cut:], bs=64, shuffle=False)
-
构建神经网络架构
我们使用三个标准线性层,但有两个调整:
- 第一个线性层仅使用第一个单词的嵌入作为激活。
- 第二个层使用第二个单词的嵌入加上第一层的输出激活。
- 第三个层使用第三个单词的嵌入加上第二层的输出激活。
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,其步骤如下:-
初始化:根据文件和标签函数,创建标签到文件的映射,以及验证集的固定抽取结果。
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]]} -
编码:根据文件路径,抽取配对文件和标签,创建
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) -
抽取函数:以 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:在批次构建完成后应用,如将整数张量转换为浮点数张量并进行归一化。
-
-
创建步骤
-
从
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进行数据批量处理,加速训练过程。
通过以上的深入分析和实践,我们对数据处理和模型构建有了更全面的理解。在实际应用中,我们可以根据具体任务需求,灵活运用这些技术,不断优化模型性能。
超级会员免费看

被折叠的 条评论
为什么被折叠?



