bb = TensorBBox([[-2,-0.5,0.5,1.5], [-0.5,-0.5,0.5,0.5], [1,0.5,0.5,0.75], [-0.5,-0.5,0.5,0.5], [-2, -0.5, -1.5, 0.5]])
bb,lbl = clip_remove_empty(bb, TensorMultiCategory([1,2,3,2,5]))
test_eq(bb, TensorBBox([[-1,-0.5,0.5,1.], [-0.5,-0.5,0.5,0.5], [-0.5,-0.5,0.5,0.5]]))
test_eq(lbl, TensorMultiCategory([1,2,2]))视觉数据
DataLoaders 数据以及更高级类 ImageDataLoaders 的辅助函数此模块中定义的主要类是 ImageDataLoaders 和 SegmentationDataLoaders,因此您可能希望直接跳转到它们的定义。它们提供了工厂方法,是快速准备训练数据的绝佳方式,请参阅视觉教程了解示例。
辅助函数
get_grid
get_grid (n:int, nrows:int=None, ncols:int=None, figsize:tuple=None, double:bool=False, title:str=None, return_fig:bool=False, flatten:bool=True, imsize:int=3, suptitle:str=None, sharex:"bool|Literal['none','all','row','col']"=False, sharey:"bool|Literal['none','all','row','col']"=False, squeeze:bool=True, width_ratios:Sequence[float]|None=None, height_ratios:Sequence[float]|None=None, subplot_kw:dict[str,Any]|None=None, gridspec_kw:dict[str,Any]|None=None)
返回一个包含 n 个轴的网格,按 rows 行 cols 列排列
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| n | int | 返回网格中的轴数量 | |
| nrows | int | None | 返回网格中的行数,默认为 int(math.sqrt(n)) |
| ncols | int | None | 返回网格中的列数,默认为 ceil(n/rows) |
| figsize | tuple | None | 返回图形的宽度、高度(以英寸为单位) |
| double | bool | False | 是否将列数和 n 加倍 |
| title | str | None | 如果传入,则设置为图形的标题 |
| return_fig | bool | False | 是否返回由 subplots 创建的图形 |
| flatten | bool | True | 是否展平 matplot 轴,以便可以使用单个循环进行迭代 |
| imsize | int | 3 | 将在返回图形中显示的图像大小(以英寸为单位) |
| suptitle | str | None | 设置为返回图形的标题 |
| sharex | bool | Literal[‘none’, ‘all’, ‘row’, ‘col’] | False | |
| sharey | bool | Literal[‘none’, ‘all’, ‘row’, ‘col’] | False | |
| squeeze | bool | True | |
| width_ratios | Sequence[float] | None | None | |
| height_ratios | Sequence[float] | None | None | |
| subplot_kw | dict[str, Any] | None | None | |
| gridspec_kw | dict[str, Any] | None | None | |
| 返回值 | (plt.Figure, plt.Axes) | 默认仅返回 axs,如果 return_fig 设置为 True 则返回 (fig, axs) |
这被视觉应用的类型分派版本的 show_batch 和 show_results 使用。默认的 figsize 是 (cols*imsize, rows*imsize+0.6)。imsize 会向下传递给 subplots。suptitle, sharex, sharey, squeeze, subplot_kw 和 gridspec_kw 都会向下传递给 plt.subplots。如果 return_fig 为 True,则返回 fig,axs,否则只返回 axs。
clip_remove_empty
clip_remove_empty (bbox:fastai.vision.core.TensorBBox, label:fastai.torch_core.TensorMultiCategory)
将边界框裁剪到图像边界,并删除空框以及对应的标签
| 类型 | 详情 | |
|---|---|---|
| bbox | TensorBBox | 边界框坐标 |
| label | TensorMultiCategory | 边界框标签 |
这用于 bb_pad
bb_pad
bb_pad (samples:list, pad_idx=0)
收集带有标签边界框的 samples 并用 pad_idx 添加填充的函数。
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| samples | list | 像 (图像, 边界框, 标签) 这样的三元组列表 | |
| pad_idx | int | 0 | 将用于填充每个标签列表的标签 |
这用于 BBoxBlock
img1,img2 = TensorImage(torch.randn(16,16,3)),TensorImage(torch.randn(16,16,3))
bb1 = tensor([[-2,-0.5,0.5,1.5], [-0.5,-0.5,0.5,0.5], [1,0.5,0.5,0.75], [-0.5,-0.5,0.5,0.5]])
lbl1 = tensor([1, 2, 3, 2])
bb2 = tensor([[-0.5,-0.5,0.5,0.5], [-0.5,-0.5,0.5,0.5]])
lbl2 = tensor([2, 2])
samples = [(img1, bb1, lbl1), (img2, bb2, lbl2)]
res = bb_pad(samples)
non_empty = tensor([True,True,False,True])
test_eq(res[0][0], img1)
test_eq(res[0][1], tensor([[-1,-0.5,0.5,1.], [-0.5,-0.5,0.5,0.5], [-0.5,-0.5,0.5,0.5]]))
test_eq(res[0][2], tensor([1,2,2]))
test_eq(res[1][0], img2)
test_eq(res[1][1], tensor([[-0.5,-0.5,0.5,0.5], [-0.5,-0.5,0.5,0.5], [0,0,0,0]]))
test_eq(res[1][2], tensor([2,2,0]))用于视觉应用的 TransformBlock
这些是视觉应用为 data block API 提供的块。
ImageBlock
ImageBlock (cls:fastai.vision.core.PILBase=<class 'fastai.vision.core.PILImage'>)
用于 cls 图像的 TransformBlock
MaskBlock
MaskBlock (codes:list=None)
用于分割掩码的 TransformBlock,可能带有 codes
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| codes | list | None | 分割掩码的词汇标签 |
PointBlock
用于图像中点的 TransformBlock
BBoxBlock
用于图像中边界框的 TransformBlock
BBoxLblBlock
BBoxLblBlock (vocab:list=None, add_na:bool=True)
用于带标签边界框的 TransformBlock,可能带有 vocab
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| vocab | list | None | 边界框的词汇标签 |
| add_na | bool | True | 将 NaN 添加为背景类 |
如果 add_na 为 True,则会为 NaN 添加一个新类别(这将代表背景类)。
ImageDataLoaders
ImageDataLoaders (*loaders, path:str|pathlib.Path='.', device=None)
围绕多个 DataLoader 的基本封装,带有用于计算机视觉问题的工厂方法
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| loaders | VAR_POSITIONAL | 要封装的 DataLoader 对象 |
|
| path | str | pathlib.Path | . | 存储导出对象的路径 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
这个类不应该直接使用,而应该优先使用其中一个工厂方法。所有这些工厂方法都接受以下参数:
item_tfms: 在批量化之前应用于项目的单个或多个转换batch_tfms: 在形成批次后应用于批次的单个或多个转换bs: 批次大小val_bs: 验证DataLoader的批次大小(默认为bs)shuffle_train: 是否打乱训练DataLoaderdevice: 要使用的 PyTorch 设备(默认为default_device())
ImageDataLoaders.from_folder
ImageDataLoaders.from_folder (path, train='train', valid='valid', valid_pct=None, seed=None, vocab=None, item_tfms=None, batch_tfms=None, img_cls=<class 'fastai.vision.core.PILImage'>, bs:int=64, val_bs:int=None, shuffle:bool=True, device=None)
从 path 中具有 train 和 valid 子文件夹的 imagenet 风格数据集创建(或提供 valid_pct)
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| path | str | pathlib.Path | . | 放入 DataLoaders 的路径 |
| train | str | train | |
| valid | str | valid | |
| valid_pct | NoneType | None | |
| seed | NoneType | None | |
| vocab | NoneType | None | |
| item_tfms | NoneType | None | |
| batch_tfms | NoneType | None | |
| img_cls | BypassNewMeta | PILImage | |
| bs | int | 64 | 批次大小 |
| val_bs | int | None | 验证 DataLoader 的批次大小 |
| shuffle | bool | True | 是否打乱数据 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
如果提供了 valid_pct,则通过将该百分比的数据留作验证集来执行随机分割(可选带有 seed),而不是查看祖父文件夹。如果传入了 vocab,则只保留名称在 vocab 中的文件夹。
以下是加载 MNIST 子样本的示例
path = untar_data(URLs.MNIST_TINY)
dls = ImageDataLoaders.from_folder(path, img_cls=PILImageBW)x,y = dls.one_batch()
test_eq(x.shape, [64, 1, 28, 28])传入 valid_pct 将忽略 valid/train 文件夹并执行新的随机分割
dls = ImageDataLoaders.from_folder(path, valid_pct=0.2)
dls.valid_ds.items[:3][Path('/home/jhoward/.fastai/data/mnist_tiny/train/7/9307.png'),
Path('/home/jhoward/.fastai/data/mnist_tiny/train/3/8241.png'),
Path('/home/jhoward/.fastai/data/mnist_tiny/valid/3/8924.png')]
ImageDataLoaders.from_path_func
ImageDataLoaders.from_path_func (path, fnames, label_func, valid_pct=0.2, seed=None, item_tfms=None, batch_tfms=None, img_cls=<class 'fastai.vision.core.PILImage'>, bs:int=64, val_bs:int=None, shuffle:bool=True, device=None)
从 path 中的 fnames 列表和 label_func 创建
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| path | str | pathlib.Path | . | 放入 DataLoaders 的路径 |
| fnames | |||
| label_func | |||
| valid_pct | float | 0.2 | |
| seed | NoneType | None | |
| item_tfms | NoneType | None | |
| batch_tfms | NoneType | None | |
| img_cls | BypassNewMeta | PILImage | |
| bs | int | 64 | 批次大小 |
| val_bs | int | None | 验证 DataLoader 的批次大小 |
| shuffle | bool | True | 是否打乱数据 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
验证集是 valid_pct 的随机 subset,可选使用 seed 创建以保证可重复性。
以下是如何使用 label_func 在 MNIST 数据集上创建与前一个示例相同的 DataLoaders
fnames = get_image_files(path)
def label_func(x): return x.parent.name
dls = ImageDataLoaders.from_path_func(path, fnames, label_func)以下是 pets 数据集上的另一个示例。这里的文件名都在一个名为“images”的文件夹中,其名称格式为 class_name_123.jpg。因此,一种正确标记它们的方法是丢弃最后一个 _ 之后的所有内容
ImageDataLoaders.from_path_re
ImageDataLoaders.from_path_re (path, fnames, pat, valid_pct=0.2, seed=None, item_tfms=None, batch_tfms=None, img_cls=<class 'fastai.vision.core.PILImage'>, bs:int=64, val_bs:int=None, shuffle:bool=True, device=None)
从 path 中的 fnames 列表和正则表达式 pat 创建
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| path | str | pathlib.Path | . | 放入 DataLoaders 的路径 |
| fnames | |||
| pat | |||
| valid_pct | float | 0.2 | |
| seed | NoneType | None | |
| item_tfms | NoneType | None | |
| batch_tfms | NoneType | None | |
| img_cls | BypassNewMeta | PILImage | |
| bs | int | 64 | 批次大小 |
| val_bs | int | None | 验证 DataLoader 的批次大小 |
| shuffle | bool | True | 是否打乱数据 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
验证集是 valid_pct 的随机子集,可选使用 seed 创建以保证可重复性。
以下是如何使用此方法在 MNIST 数据集上创建与前一个示例相同的 DataLoaders(在 Windows 上您需要将开头的两个 / 更改为 )
pat = r'/([^/]*)/\d+.png$'
dls = ImageDataLoaders.from_path_re(path, fnames, pat)ImageDataLoaders.from_name_func
ImageDataLoaders.from_name_func (path:str|Path, fnames:list, label_func:Callable, valid_pct=0.2, seed=None, item_tfms=None, batch_tfms=None, img_cls=<class 'fastai.vision.core.PILImage'>, bs:int=64, val_bs:int=None, shuffle:bool=True, device=None)
从 path 中 fnames 的名称属性和 label_func 创建
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| path | str | Path | 将默认路径设置为 Learner 可用于保存模型等文件的目录 |
|
| fnames | list | 指向单个图像文件的 os.Pathlike 列表 |
|
| label_func | Callable | 接收字符串(文件名)并输出标签的函数 | |
| valid_pct | float | 0.2 | |
| seed | NoneType | None | |
| item_tfms | NoneType | None | |
| batch_tfms | NoneType | None | |
| img_cls | BypassNewMeta | PILImage | |
| bs | int | 64 | 批次大小 |
| val_bs | int | None | 验证 DataLoader 的批次大小 |
| shuffle | bool | True | 是否打乱数据 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
| 返回值 | DataLoaders |
验证集是 valid_pct 的随机子集,可选使用 seed 创建以保证可重复性。此方法的功能与 ImageDataLoaders.from_path_func 相同,只是 label_func 应用于每个文件名的名称,而不是完整路径。
ImageDataLoaders.from_name_re
ImageDataLoaders.from_name_re (path, fnames, pat, bs:int=64, val_bs:int=None, shuffle:bool=True, device=None)
从 path 中 fnames 的名称属性和正则表达式 pat 创建
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| path | str | pathlib.Path | . | 放入 DataLoaders 的路径 |
| fnames | |||
| pat | |||
| bs | int | 64 | 批次大小 |
| val_bs | int | None | 验证 DataLoader 的批次大小 |
| shuffle | bool | True | 是否打乱数据 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
验证集是 valid_pct 的随机子集,可选使用 seed 创建以保证可重复性。此方法的功能与 ImageDataLoaders.from_path_re 相同,只是 pat 应用于每个文件名的名称,而不是完整路径。
ImageDataLoaders.from_df
ImageDataLoaders.from_df (df, path='.', valid_pct=0.2, seed=None, fn_col=0, folder=None, suff='', label_col=1, label_delim=None, y_block=None, valid_col=None, item_tfms=None, batch_tfms=None, img_cls=<class 'fastai.vision.core.PILImage'>, bs:int=64, val_bs:int=None, shuffle:bool=True, device=None)
使用 fn_col 和 label_col 从 df 创建
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| df | |||
| path | str | pathlib.Path | . | 放入 DataLoaders 的路径 |
| valid_pct | float | 0.2 | |
| seed | NoneType | None | |
| fn_col | int | 0 | |
| folder | NoneType | None | |
| suff | str | ||
| label_col | int | 1 | |
| label_delim | NoneType | None | |
| y_block | NoneType | None | |
| valid_col | NoneType | None | |
| item_tfms | NoneType | None | |
| batch_tfms | NoneType | None | |
| img_cls | BypassNewMeta | PILImage | |
| bs | int | 64 | 批次大小 |
| val_bs | int | None | 验证 DataLoader 的批次大小 |
| shuffle | bool | True | 是否打乱数据 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
验证集是 valid_pct 的随机子集,可选使用 seed 创建以保证可重复性。或者,如果您的 df 包含一个 valid_col,请将其名称或索引作为该参数(该列中用于验证集的元素应为 True)。
如果 df 中的文件名不应直接连接到 path,您可以添加一个额外的 folder。如果它们不包含正确的扩展名,您可以添加 suff。如果您的标签列每行包含多个标签,您可以使用 label_delim 通知库您有一个多标签问题。
当库自动选择的任务不正确时,应该传入 y_block,此时应提供 CategoryBlock、MultiCategoryBlock 或 RegressionBlock。对于更高级的用法,应使用 data block API。
前面的 tiny mnist 示例也包含一个 DataFrame 版本
path = untar_data(URLs.MNIST_TINY)
df = pd.read_csv(path/'labels.csv')
df.head()| name | label | |
|---|---|---|
| 0 | train/3/7463.png | 3 |
| 1 | train/3/9829.png | 3 |
| 2 | train/3/7881.png | 3 |
| 3 | train/3/8065.png | 3 |
| 4 | train/3/7046.png | 3 |
以下是如何使用 ImageDataLoaders.from_df 加载它
dls = ImageDataLoaders.from_df(df, path)/home/jhoward/git/fastai/fastai/data/transforms.py:212: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
o = r[c] if isinstance(c, int) or not c in getattr(r, '_fields', []) else getattr(r, c)
以下是多标签问题的另一个示例
path = untar_data(URLs.PASCAL_2007)
df = pd.read_csv(path/'train.csv')
df.head()| fname | labels | is_valid | |
|---|---|---|---|
| 0 | 000005.jpg | chair | True |
| 1 | 000007.jpg | car | True |
| 2 | 000009.jpg | horse person | True |
| 3 | 000012.jpg | car | False |
| 4 | 000016.jpg | bicycle | True |
dls = ImageDataLoaders.from_df(df, path, folder='train', valid_col='is_valid')/home/jhoward/git/fastai/fastai/data/transforms.py:212: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
o = r[c] if isinstance(c, int) or not c in getattr(r, '_fields', []) else getattr(r, c)
请注意,您也可以将 2 传递给 valid_col(索引,从 0 开始)。
ImageDataLoaders.from_csv
ImageDataLoaders.from_csv (path, csv_fname='labels.csv', header='infer', delimiter=None, quoting=0, valid_pct=0.2, seed=None, fn_col=0, folder=None, suff='', label_col=1, label_delim=None, y_block=None, valid_col=None, item_tfms=None, batch_tfms=None, img_cls=<class 'fastai.vision.core.PILImage'>, bs:int=64, val_bs:int=None, shuffle:bool=True, device=None)
使用 fn_col 和 label_col 从 path/csv_fname 创建
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| path | str | pathlib.Path | . | 放入 DataLoaders 的路径 |
| csv_fname | str | labels.csv | |
| header | str | infer | |
| delimiter | NoneType | None | |
| quoting | int | 0 | |
| valid_pct | float | 0.2 | |
| seed | NoneType | None | |
| fn_col | int | 0 | |
| folder | NoneType | None | |
| suff | str | ||
| label_col | int | 1 | |
| label_delim | NoneType | None | |
| y_block | NoneType | None | |
| valid_col | NoneType | None | |
| item_tfms | NoneType | None | |
| batch_tfms | NoneType | None | |
| img_cls | BypassNewMeta | PILImage | |
| bs | int | 64 | 批次大小 |
| val_bs | int | None | 验证 DataLoader 的批次大小 |
| shuffle | bool | True | 是否打乱数据 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
加载文件时使用 header 和 delimiter 后,与 ImageDataLoaders.from_df 相同。
以下是如何使用此方法加载与之前相同的数据集
dls = ImageDataLoaders.from_csv(path, 'train.csv', folder='train', valid_col='is_valid')/home/jhoward/git/fastai/fastai/data/transforms.py:212: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
o = r[c] if isinstance(c, int) or not c in getattr(r, '_fields', []) else getattr(r, c)
ImageDataLoaders.from_lists
ImageDataLoaders.from_lists (path, fnames, labels, valid_pct=0.2, seed:int=None, y_block=None, item_tfms=None, batch_tfms=None, img_cls=<class 'fastai.vision.core.PILImage'>, bs:int=64, val_bs:int=None, shuffle:bool=True, device=None)
从 path 中的 fnames 和 labels 列表创建
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| path | str | pathlib.Path | . | 放入 DataLoaders 的路径 |
| fnames | |||
| labels | |||
| valid_pct | float | 0.2 | |
| seed | int | None | |
| y_block | NoneType | None | |
| item_tfms | NoneType | None | |
| batch_tfms | NoneType | None | |
| img_cls | BypassNewMeta | PILImage | |
| bs | int | 64 | 批次大小 |
| val_bs | int | None | 验证 DataLoader 的批次大小 |
| shuffle | bool | True | 是否打乱数据 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
验证集是 valid_pct 的随机子集,可选使用 seed 创建以保证可重复性。可以传入 y_block 来指定目标的类型。
path = untar_data(URLs.PETS)
fnames = get_image_files(path/"images")
labels = ['_'.join(x.name.split('_')[:-1]) for x in fnames]
dls = ImageDataLoaders.from_lists(path, fnames, labels)SegmentationDataLoaders
SegmentationDataLoaders (*loaders, path:str|pathlib.Path='.', device=None)
围绕多个 DataLoader 的基本封装,带有用于分割问题的工厂方法
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| loaders | VAR_POSITIONAL | 要封装的 DataLoader 对象 |
|
| path | str | pathlib.Path | . | 存储导出对象的路径 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
SegmentationDataLoaders.from_label_func
SegmentationDataLoaders.from_label_func (path, fnames, label_func, valid_pct=0.2, seed=None, codes=None, item_tfms=None, batch_tfms=None, img_cls=<class 'fastai.vision.core.PILImage'>, bs:int=64, val_bs:int=None, shuffle:bool=True, device=None)
从 path 中的 fnames 列表和 label_func 创建。
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| path | str | pathlib.Path | . | 放入 DataLoaders 的路径 |
| fnames | |||
| label_func | |||
| valid_pct | float | 0.2 | |
| seed | NoneType | None | |
| codes | NoneType | None | |
| item_tfms | NoneType | None | |
| batch_tfms | NoneType | None | |
| img_cls | BypassNewMeta | PILImage | |
| bs | int | 64 | 批次大小 |
| val_bs | int | None | 验证 DataLoader 的批次大小 |
| shuffle | bool | True | 是否打乱数据 |
| device | NoneType | None | 放置 DataLoaders 的设备 |
验证集是 valid_pct 的随机子集,可选使用 seed 创建以保证可重复性。codes 包含索引到标签的映射。
path = untar_data(URLs.CAMVID_TINY)
fnames = get_image_files(path/'images')
def label_func(x): return path/'labels'/f'{x.stem}_P{x.suffix}'
codes = np.loadtxt(path/'codes.txt', dtype=str)
dls = SegmentationDataLoaders.from_label_func(path, fnames, label_func, codes=codes)