speechbrain.utils.depgraph 模块

用于寻找评估顺序的依赖图。

示例

>>> # The basic use case is that you have a bunch of keys
>>> # and some of them depend on each other:
>>> database = []
>>> functions = {'read': {'func': lambda: (0,1,2),
...                       'needs': []},
...              'process': {'func': lambda X: [x**2 for x in X],
...                          'needs': ['read']},
...              'save': {'func': lambda x: database.append(x),
...                       'needs': ['process']},
...              'print': {'func': lambda x,y: print(x, "became", y),
...                        'needs': ['read', 'process']},
...              'auxiliary': {'func': lambda: (1,2,3),
...                            'needs': []}}
>>> # If this is user supplied info, so you can't just hardcode the order,
>>> # a dependency graph may be needed.
>>> dg = DependencyGraph()
>>> # In simple cases, you can just encode the dependencies directly:
>>> for key, conf in functions.items():
...     for needed in conf["needs"]:
...         dg.add_edge(key, needed)
>>> # Now we can evaluate:
>>> outputs = {}
>>> for node in dg.get_evaluation_order():
...     f = functions[node.key]['func']
...     args = [outputs[needed] for needed in functions[node.key]['needs']]
...     outputs[node.key] = f(*args)
(0, 1, 2) became [0, 1, 4]
>>> # This added nodes implicitly.
>>> # However, since 'auxiliary' didn't depend on anything,
>>> # it didn't get added!
>>> assert 'auxiliary' not in outputs
>>> # So to be careful, we should also manually add nodes for any thing that
>>> # is not an intermediate step.
>>> _ = dg.add_node('auxiliary')
>>> assert 'auxiliary' in (node.key for node in dg.get_evaluation_order())
>>> # Arbitrary data can be added to nodes:
>>> dg2 = DependencyGraph()
>>> for key, conf in functions.items():
...     _ = dg2.add_node(key, conf)
...     for needed in conf["needs"]:
...         dg2.add_edge(key, needed)
>>> # Now we get access to the data in evaluation:
>>> outputs2 = {}
>>> for key, _, conf in dg2.get_evaluation_order():
...     f = conf['func']
...     args = [outputs[needed] for needed in conf['needs']]
...     outputs[key] = f(*args)
(0, 1, 2) became [0, 1, 4]
作者
  • Aku Rouhe 2020

摘要

异常

CircularDependencyError

在 DependencyGraph 中搜索评估顺序时遇到循环依赖项导致的错误。

DGNode

DGNode(key, edges, data)

DependencyGraph

通用依赖图。

参考

exception speechbrain.utils.depgraph.CircularDependencyError[source]

基类:ValueError

在 DependencyGraph 中搜索评估顺序时遇到循环依赖项导致的错误。

class speechbrain.utils.depgraph.DGNode(key, edges, data)

基类:tuple

data

字段 2 的别名

edges

字段 1 的别名

key

字段 0 的别名

class speechbrain.utils.depgraph.DependencyGraph[source]

基类:object

通用依赖图。

本质上是一个有向无环图。通常用于寻找例如变量替换的评估顺序。边 A -> B 表示的关系是:“A 依赖于 B,即 B 应该在 A 之前评估”

节点可以显式添加,或者在添加边时隐式创建。节点具有键,键应该是可哈希的值,用于标识图中代表的元素。例如,它们可以是您想要替换的变量名。但是,如果需要,更一般地说,您可以将任何数据附加到节点(例如,树中的路径),并且如果需要,可以为您创建一个唯一的键。您只需要在向/从该节点添加边时知道该键。隐式键和显式键也可以混合使用。

static get_unique_key()[source]

返回一个唯一的、可哈希的标识符。

add_node(key=None, data=None)[source]

显式添加一个节点。

参数:
  • key (可哈希, 可选) – 如果未给出,将为您创建一个键。

  • data (任意类型, 可选) – 您希望附加到此节点的任何额外数据。

返回:

使用的键(可以是您的,也可以是生成的)。

返回类型:

可哈希

抛出:

ValueError – 如果具有给定键的节点已通过此方法(而非 “add_edge”)显式添加。

add_edge(from_key, to_key)[source]

添加一条边,并隐式创建之前未见的键的节点。这不允许您向节点添加数据。此关系编码为:“from_key 依赖于 to_key”(to_key 必须在 from_key 之前评估)。

参数:
  • from_key (可哈希) – 依赖的键。

  • to_key (可哈希) – 被依赖的键。

is_valid()[source]

检查是否可以找到评估顺序。

如果不存在循环依赖项,即图是无环的,则依赖图是可评估的。

返回:

指示图是否可评估。

返回类型:

bool

get_evaluation_order(selected_keys=None)[source]

找到一个有效的评估顺序。

可能存在许多不同的有效顺序。注意:一次生成一个 DGNode 的输出。在找到循环依赖项之前可能会生成 DGNodes。如果您确实需要知道是否可以找到顺序,请先检查 is_valid()。然而,查找循环的算法本质上与查找评估顺序的算法相同,所以对于非常大的图... 嗯,也许那时您应该使用其他解决方案了。

参数:

selected_keys (list, None) – 键列表。如果不是 None,则评估顺序中只保证包含选定的键(以及它们依赖的键)。

生成:

DGNode – 按有效评估顺序添加的 DGNodes。请参阅上面的 DGNode namedtuple。

抛出:

CircularDependencyError – 如果发现循环依赖项。