speechbrain.utils.depgraph 模块

用于查找评估顺序的依赖关系图。

Example

>>> # 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]
Authors:
  • 阿库·柔赫 2020

摘要

异常:

CircularDependencyError

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

类:

DGNode

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]

显式添加一个节点。

Parameters:
  • key (可哈希的, 可选的) – 如果没有提供,将为你创建一个key。

  • data (Any, optional) – 任何您希望附加到此节点的额外数据。

Returns:

使用的密钥(可能是您的或生成的)。

Return type:

可哈希的

Raises:

ValueError – 如果具有给定键的节点已经显式添加(使用此方法,而不是“add_edge”)。

add_edge(from_key, to_key)[source]

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

Parameters:
  • from_key (hashable) – 依赖的键。

  • to_key (hashable) – 所依赖的键。

is_valid()[source]

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

如果没有循环依赖,即图是无环的,则依赖图是可评估的。

Returns:

指示图表是否可评估。

Return type:

bool

get_evaluation_order(selected_keys=None)[source]

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

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

Parameters:

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

Yields:

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

Raises:

CircularDependencyError – 如果发现循环依赖。