Skip to main content

数据视图

Dataviews 是 ClearML Enterprise 中一个强大且易于使用的功能,用于创建和管理远程数据集的本地视图。Dataviews 可以使用复杂的查询从数据集的子集或数据集的组合中输入数据。

数据视图支持:

  • Filter by ROI tags, frame metadata, and data sources
  • 数据去偏以调整不平衡数据
  • ROI 标签映射(标签翻译)
  • Class Label Enumeration
  • 控制帧迭代的方式,例如顺序或随机迭代,有限或无限迭代,以及可重复性。

Dataviews 是惰性的并优化处理。当实验脚本在本地环境中运行时,Dataview 指针会被初始化。如果实验被克隆或扩展,并且新克隆或扩展的实验被调整并运行,只有更改的指针会被初始化。未更改的指针会被重用。

Dataview 状态

数据视图可以处于草稿已发布状态。

一个草稿 Dataview 是可编辑的。一个已发布 Dataview 是只读的,这确保了实验的可重复性并保留了 Dataview 的设置。

过滤

Dataview 使用一个或多个帧过滤器来过滤实验输入数据。帧过滤器定义了 Dataview 迭代选择 SingleFrames 的标准。

帧过滤器包含以下条件:

  • 数据集版本 - 选择过滤器是应用于一个版本还是数据集的所有版本。

  • 以下规则的任意组合:

    • ROI 规则 - 包含或排除包含至少一个 ROI 的帧,这些 ROI 具有数据集版本中的任何标签组合。 可选地,限制每帧匹配的 ROI(实例)数量,和/或限制标签的置信度。
      例如:包含标记为 catdog 的两到四个 ROI 的帧,置信度从 0.81.0
    • 帧规则 - 通过帧元数据键值对或 ROI 标签进行过滤。
      例如:如果某些帧包含元数据键 dangerous,其值为 yesno,则过滤 (meta.dangerous:'yes')
    • 来源规则 - 通过帧 source 字典键值对进行过滤。
      例如:通过来源 ID (source.id:00) 进行过滤。
  • A ratio (weight) used to debias the input data and adjust the imbalance in SingleFrames iterated by Dataview (optional).

使用这些帧过滤器的组合来构建复杂的查询。

去偏输入数据

对每个帧过滤器应用去偏置,以调整输入数据中的不平衡。比率(权重)允许根据帧过滤器中的任何标准(包括ROI标签、帧元数据和来源)以及每个数据集版本与其他版本的比较,设置输入帧的比例。

例如,数据中标记为daylight的帧数可能是标记为nighttime的五倍,但您希望输入相同数量的两者。为了消除数据偏差,创建两个帧过滤器,一个用于daylight,比例为1,另一个用于nighttime,比例为5。Dataview将为每个SingleFrame迭代大致相同的次数。

ROI 标签映射(标签翻译)

ROI标签映射(标签翻译)适用于新模型。例如,应用映射到:

  • 将不同的标签组合在另一个更通用的标签下。
  • 整合包含不同名称的ROI的不同数据集。
  • Hide labeled objects during training.

类标签枚举

为新模型定义类别标签,并为每个标签分配整数,以保持多个代码库和数据集之间的数据一致性。为所有重要标签设置枚举值非常重要。

数据增强

即时数据增强应用于SingleFrames,无需创建新数据即可转换图像。按步骤应用数据增强,其中每个步骤由方法、操作和强度组成,如下所示:

  • 仿射增强方法 - 将图像的几何形状转换为二维平面上的另一个位置。 使用以下任意操作:

    • 旋转
    • 水平反射 - 水平翻转图像
    • 垂直反射 - 垂直翻转图像
    • 缩放
    • 剪切 - 倾斜
    • 无操作 - 随机选择未转换的SingleFrames(跳过)。如果实验再次运行,并且迭代控制中的随机种子不变,则相同的SingleFrames不会被增强。
  • 像素增强方法 - 通过修改像素值来转换图像,同时保留形状和透视。
    使用以下任意操作:

    • 模糊 - 高斯平滑
    • 噪声 - ClearML Enterprise 自有的噪声增强,包括:
      • 噪声 - 类似于模拟电视信号弱时的雪花
      • 噪声 - 类似于图像局部区域放大的低分辨率图像
    • 重新着色 - 使用内部 RGB 查找表
    • 无操作 - 随机选择未转换的 SingleFrames(跳过)。如果实验再次运行,并且 迭代控制 中的随机种子未更改,则相同的 SingleFrames 不会被增强。
  • 强度 - 用于调整转换程度的数字。推荐的强度如下:

    • 0.0 - 无效果
    • 0.5 - 低(弱)
    • 1.0 - 中(推荐)
    • 2.0 - 高(强)

迭代控制

输入数据的迭代控制设置决定了Dataview迭代SingleFrames的顺序、数量、时间和可重复性。根据迭代控制设置的组合,可能不会迭代所有的SingleFrames,有些可能会重复。设置包括以下内容:

  • 顺序 - 迭代返回的SingleFrames的顺序,可以是以下之一:

    • 顺序 - 按上下文ID和时间戳排序迭代SingleFrames。
    • 随机 - 使用可设置的随机种子随机迭代SingleFrames(见下面的随机种子)。
  • 重复 - SingleFrames的重复,与顺序结合,决定是否返回所有SingleFrames,以及是否有任何可能重复。重复设置及其对迭代的影响如下:

    • 每帧使用一次 - 所有SingleFrame都会被迭代。如果顺序是连续的,那么没有SingleFrame会重复。如果顺序是随机的,那么一些SingleFrame可能会重复。

    • 限制帧数 - 要迭代的最大单帧数,除非实际单帧数少于最大值,则迭代实际单帧数。如果顺序是连续的,则不会重复任何单帧。如果顺序是随机的,则可能会重复某些单帧。

    • 无限迭代 - 迭代SingleFrames直到实验手动终止。如果顺序是连续的,那么所有SingleFrames都会被迭代(除非实验在所有迭代之前手动终止)并且SingleFrames会重复。如果顺序是随机的,那么可能不会迭代所有SingleFrames,并且某些SingleFrames可能会重复。

  • 随机种子 - 如果实验重新运行且种子保持不变,SingleFrames迭代是相同的。

  • 剪辑长度 - 对于视频数据源,表示从剪辑中连续单帧的数量进行迭代。

用法

创建数据视图

使用allegroai.DataView类来创建一个DataView对象。实例化DataView对象时,指定迭代设置和控制查询迭代的额外迭代参数。

from allegroai import DataView, IterationOrder
# Create a DataView object that iterates randomly until terminated by the user
myDataView = DataView(iteration_order=IterationOrder.random, iteration_infinite=True)

添加查询

Dataview过滤器是通过向Dataview添加过滤器查询来创建的。要向DataView添加查询,请使用DataView.add_query()并指定数据集版本、ROI和/或帧查询以及其他条件。

使用 dataset_nameversion_name 参数来指定查询适用的数据集版本。

Multi-version queries

dataset_nameversion_name 支持通配符输入 (*),分别表示所有 Dataview 数据集或所有 Dataview 版本。 至少一个 Dataview 查询必须明确指定一个数据集,以便“所有 Dataview 数据集”有意义

roi_queryframe_query 参数指定了可能的查询:

  • roi_query 可以通过标签名称或Lucene查询分配ROI标签。
  • frame_query 必须分配一个 Lucene 查询。

通过多次调用DataView.add_query()来应用多个过滤器(使用相同或不同的查询)。

使用 DataView.add_multi_query() 在同一查询中指定多个 ROI 规则。

您可以使用DataView.to_list()DataView.to_dict()DataView.get_iterator() (参见访问帧)来检索Dataview帧。

ROI 查询:

  • 单个标签的投资回报率查询

此示例使用ROI查询来过滤包含至少一个标签为cat的ROI的帧:

# Create a Dataview object for an iterator that randomly returns frames according to queries
myDataView = DataView(iteration_order=IterationOrder.random, iteration_infinite=False)

# Add a query for a Dataset version
myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='cat'
)

# retrieving the actual SingleFrames / FrameGroups
# you can also iterate over the frames with `for frame in myDataView.get_iterator():`
list_of_frames = myDataView.to_list()
  • 一个标签或另一个标签的ROI查询

此示例使用ROI查询来筛选包含至少一个标签为catdog的ROI的帧:

# Add a query for a Dataset version 
myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='cat'
)

myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='dog'
)

# retrieving the actual SingleFrames / FrameGroups
# you can also iterate over the frames with `for frame in myDataView.get_iterator():`
list_of_frames = myDataView.to_list()
  • 在同一ROI中查询两个特定标签的ROI

此示例使用ROI查询来过滤包含至少一个具有标签Car和标签partly_occluded的ROI的帧:

# Add a query for a Dataset version
myDataView.add_query(
dataset_name='myDataset',
version_name='training',
roi_query=['Car','partly_occluded']
)

# retrieving the actual SingleFrames / FrameGroups
# you can also iterate over the frames with `for frame in myDataView.get_iterator():`
list_of_frames = myDataView.to_list()
  • 一个标签的ROI查询而不是另一个(Lucene查询)

此示例使用ROI查询来筛选包含至少一个标签为Car且不包含标签partly_occluded的ROI的帧:

# Add a query for a Dataset version
# Use a Lucene Query
# "label" is a key in the rois dictionary of a frame
# In this Lucene Query, specify two values for the label key and use a Logical AND NOT
myDataView.add_query(
dataset_name='myDataset',
version_name='training',
roi_query='label.keyword:\"Car\" AND NOT label.keyword:\"partly_occluded\"'
)

# retrieving the actual SingleFrames / FrameGroups
# you can also iterate over the frames with `for frame in myDataView.get_iterator():`
list_of_frames = myDataView.to_list()
  • 在不同ROI中查询一个标签和另一个标签的ROI

此示例使用ROI查询来过滤包含至少一个标签为Car的ROI和至少一个标签为Person的ROI的帧。该示例演示了如何使用DataView.add_multi_query()roi_queries参数,以及一个DataView.RoiQuery对象列表:

myDataview = DataView()
myDataview.add_multi_query(
dataset_id=self._dataset_id,
version_id=self._version_id,
roi_queries=[DataView.RoiQuery(label='car'), DataView.RoiQuery(label='person')],
)
# retrieving the actual SingleFrames / FrameGroups
# you can also iterate over the frames with `for frame in myDataView.get_iterator():`
list_of_frames = myDataView.to_list()
  • 在不同ROI中查询一个标签且不包含另一个标签的ROI

此示例使用ROI查询来筛选包含至少一个标签为Car的ROI且不包含标签为Person的ROI的帧。要排除某个ROI,请在DataView.RoiQuery对象中传递must_not=True

myDataview = DataView()
myDataview.add_multi_query(
dataset_id=self._dataset_id,
version_id=self._version_id,
roi_queries=[DataView.RoiQuery(label='car'), DataView.RoiQuery(label='person', must_not=True)],
)

# retrieving the actual SingleFrames / FrameGroups
# you can also iterate over the frames with `for frame in myDataView.get_iterator():`
list_of_frames = myDataView.to_list()

查询多个数据集和版本

此示例演示了一个ROI查询过滤,用于从一个数据集的两个版本和另一个数据集的一个版本中筛选包含ROI标签cartruckbicycle的帧:

# Add queries:

# The 1st Dataset version
myDataView.add_query(
dataset_name='dataset_1',
version_name='version_1',
roi_query='label.keyword:\"car\" OR label.keyword:\"truck\" OR '
'label.keyword:\"bicycle\"'
)

# The 1st Dataset, but a different version
myDataView.add_query(
dataset_name='dataset_1',
version_name='version_2',
roi_query='label.keyword:\"car\" OR label.keyword:\"truck\" OR '
'label.keyword:\"bicycle\"'
)

# A 2nd Dataset (version)
myDataView.add_query(
dataset_name='dataset_2',
version_name='some_version',
roi_query='label.keyword:\"car\" OR label.keyword:\"truck\" OR '
'label.keyword:\"bicycle\"'
)

# retrieving the actual SingleFrames / FrameGroups
# you can also iterate over the frames with `for frame in myDataView.get_iterator():`
list_of_frames = myDataView.to_list()

框架查询

使用帧查询通过ROI标签和/或帧元数据键值对来过滤帧,这些键值对是帧必须包含或排除的,以便数据视图返回该帧。

帧查询匹配帧元键值对、ROI标签或两者。 它们使用与ROI查询相同的逻辑OR、AND、NOT AND匹配。

此示例演示了一个帧查询过滤,用于包含元键city值为bremen的帧:

# Add a frame query for frames with the meta key "city" value of "bremen"
myDataView.add_query(
dataset_name='myDataset',
version_name='version',
frame_query='meta.city:"bremen"'
)

# retrieving the actual SingleFrames / FrameGroups
# you can also iterate over the frames with `for frame in myDataView.get_iterator():`
list_of_frames = myDataView.to_list()

控制查询迭代

使用 DataView.set_iteration_parameters() 来管理训练帧的顺序、数量、时间和可重复性。

无限迭代帧

此示例演示了如何创建一个Dataview并设置其参数以无限迭代,直到脚本被手动终止:

# Create a Dataview object for an iterator that returns frames
myDataView = DataView()

# Set Iteration Parameters (overrides parameters in constructing the DataView object
myDataView.set_iteration_parameters(order=IterationOrder.random, infinite=True)

迭代所有匹配查询的帧

此示例演示了如何创建一个DataView并设置其参数以迭代并返回与查询匹配的所有帧:

# Create a Dataview object for an iterator for frames
myDataView = DataView(iteration_order=IterationOrder.random, iteration_infinite=False)

# Set Iteration Parameters (overrides parameters in constructing the DataView object
myDataView.set_iteration_parameters(
order=IterationOrder.random,
infinite=False
)

# Add a query for a Dataset version
myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='cat'
)

# retrieving the actual SingleFrames / FrameGroups
# you can also iterate over the frames with `for frame in myDataView.get_iterator():`
list_of_frames = myDataView.to_list()

迭代最大帧数

此示例演示了如何创建一个Dataview并设置其参数以迭代特定数量的帧。如果数据集版本中包含的与查询匹配的帧数少于该数量,则迭代器返回的帧数也会减少。

# Create a Dataview object for an iterator for frames
myDataView = DataView(iteration_order=IterationOrder.random, iteration_infinite=True)

# Set Iteration Parameters (overrides parameters in constructing the DataView object
myDataView.set_iteration_parameters(
order=IterationOrder.random,
infinite=False,
maximum_number_of_frames=5000
)

去偏输入数据

使用DataView.add_query方法的weight参数来添加权重,以消除输入数据的偏差。这是相同的DataView.add_query方法,可用于指定数据集版本、ROI查询和帧查询。

此示例调整输入数据中的不平衡,以改进对Car ROI的训练,这些ROI也是largely occluded(被遮挡的)。对于每一帧包含至少一个标记为Car的ROI,大约会有五帧包含至少一个同时标记为Carlargely_occluded的ROI被输入。

myDataView = DataView(iteration_order=IterationOrder.random, iteration_infinite=True)

myDataView.add_query(
dataset_name='myDataset',
version_name='training',
roi_query='Car',
weight = 1
)

myDataView.add_query(
dataset_name='myDataset',
version_name='training',
roi_query='label.keyword:\"Car\" AND label.keyword:\"largely_occluded\"',
weight = 5
)

设置标签枚举值

设置标签枚举值以维护多个代码库和数据集之间的数据一致性。 为所有重要标签设置枚举值非常重要。 未分配值的标签的默认值为-1

要为标签分配枚举值,请使用DataView.set_labels方法,在Dataview对象中设置标签(字符串)到整数的映射,用于ROI标签。

如果某些ROI标签从某些标签映射到其他标签,则在设置枚举值时使用您映射到的标签。例如,如果标签truckvancar被映射到vehicle,则为vehicle设置枚举。

# Create a Dataview object for an iterator that randomly returns frames according to queries
myDataView = DataView(iteration_order=IterationOrder.random, iteration_infinite=True)

# Add a query for a Dataset version
myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='cat'
)

myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='dog'
)

myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='bird'
)

myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='sheep'
)

myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='cow'
)

# Set the enumeration label values
myDataView.set_labels(
{"cat": 1, "dog": 2, "bird": 3, "sheep": 4, "cow": 5, "ignore": -1,}
)

映射ROI标签

ROI标签翻译(标签映射)使得可以结合标签进行训练,结合不同的数据集,并在训练时隐藏某些标签。

这个示例演示了如何整合两个不同的数据集。两个数据集版本使用car(小写字母“c”),但第三个使用Car(大写字母“C”)。 该示例将Car(大写字母“C”)映射到car(小写字母“c”):

# Create a Dataview object for an iterator that randomly returns frames according to queries 
myDataView = DataView(iteration_order=IterationOrder.random, iteration_infinite=True)

# The 1st Dataset (version) - "car" with lowercase "c"
myDataView.add_query(
dataset_name='myDataset',
version_name='myVersion',
roi_query='car'
)

# The 2nd Dataset (version) - "car" with lowercase "c"
myDataView.add_query(
dataset_name='dataset_2',
version_name='aVersion',
roi_query='car'
)

# A 3rd Dataset (version) - "Car" with uppercase "C"
myDataView.add_query(
dataset_name='dataset_3',
version_name='training',
roi_query='Car'
)

# Use a mapping rule to translate "Car" (uppercase) to "car" (lowercase)
myDataView.add_mapping_rule(
dataset_name='dataset_3',
version_name='training',
from_labels=['Car'],
to_label='car'
)

访问框架

可以通过使用DataView.get类方法,通过Dataview ID或名称检索Dataview对象。

my_dataview = DataView.get(dataview_id='<dataview_id>')

将Dataview的帧作为Python列表、字典或通过Python迭代器访问。

DataView.to_list() 将Dataview查询结果返回为Python列表。

DataView.to_dict() 返回一个字典列表,其中每个字典代表一个帧。使用 projection 参数来指定要包含在结果中的帧字段的子集。输入一个字符串列表, 其中每个字符串代表一个帧字段或子字段(使用点分隔符号)。

例如,下面的代码指定了帧字典应仅包含idsources字段以及dataset.id子字段:

my_dataview = DataView.get(dataview_id='<dataview_id>')
my_dataview.to_dict(projection=['id', 'dataset.id', 'sources'])

该方法返回一个字典列表,看起来像这样:

[   
{
"id": "<dataview_id>",
"dataset": {
"id": "<dataset_id>"
},
"sources": [
{
"id": "<id>",
"uri": "<uri>",
"timestamp": <timestamp>,
"preview": {
"uri": "<uri>",
"timestamp": <timestamp>
}
}
]
},
# additional dictionaries with the same format here
]

由于to_list/to_dict方法返回Dataview中的所有帧,建议使用DataView.get_iterator方法,该方法返回Dataview的迭代器。您还可以在此方法中使用projection参数指定所需的帧字段,就像上面描述的DataView.to_dict方法一样。