sum产品流:一个易于扩展的sum产品网络库

spflow的Python项目详细描述


pypilicense构建状态

spflow:一个简单且可扩展的sum产品网络库

spflow,一个开源的python库,提供了一个简单的推理接口, 深度可处理概率模型的学习和操作程序,称为和积网络(SPN)。 该库允许用户从数据和通过领域特定语言(DSL)快速创建SPN。 它有效地实现了一些概率推理程序,如计算边缘、条件和(近似的)最可能解释(mpes) 以及用于序列化、绘图和结构化SPN统计信息的采样和实用程序。

此外,spflow具有极强的可扩展性和可定制性,允许用户迅速创建新的推理和学习例程。 通过将自定义代码注入轻量级面向功能的api框架。

开始

这些说明将为您提供一份项目的副本,并在本地计算机上运行,以便进行开发和测试。

安装

使用pip安装最新版本的spflow

pip3 install spflow

示例

我们首先创建一个spn。使用领域特定语言(DSL),我们可以快速创建 像这样保留节点:

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))

我们可以使用对象层次结构创建相同的spn:

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn

p参数表示概率,scope表示我们正在建模的变量。

我们现在可以使用:

fromspn.io.Graphicsimportplot_spnplot_spn(spn,'basicspn.png')

basicpn.png

边缘化spn意味着将所有其他不相关的变量相加。 所以,如果我们想把上面的spn边缘化,并求出所有其他变量的和,只剩下变量1和2,我们可以做到:

fromspn.algorithms.Marginalizationimportmarginalizespn_marg=marginalize(spn,[1,2])

在这里,我们将所有不在[1,2]中的变量边缘化,并创建一个对前一个变量一无所知的新结构 也不是关于变量0。

我们可以使用这个新的spn来做所有我们感兴趣的操作。这意味着,我们也可以策划它!

plot_spn(spn_marg,'marginalspn.png')

basicpn.png

我们还可以将SPN转储为文本:

fromspn.io.Textimportspn_to_str_equationtxt=spn_to_str_equation(spn_marg)print(txt)

输出为:

(0.6*((Categorical(V1|p=[0.3,0.7])*Categorical(V2|p=[0.4,0.6])))+0.12000000000000002*((Categorical(V1|p=[0.3,0.7])*Categorical(V2|p=[0.4,0.6])))+0.27999999999999997*((Categorical(V1|p=[0.5,0.5])*Categorical(V2|p=[0.6,0.4]))))

然而,spns最有趣的方面是可处理的推断。下面是一个如何从上面评估SPN的示例。 由于我们有3个变量,我们希望创建一个包含3列和1行的2d numpy数组。

importnumpyasnptest_data=np.array([1.0,0.0,1.0]).reshape(-1,3)

然后我们计算对数似然:

pip3 install spflow
0

输出为:

pip3 install spflow
1

我们还可以计算边际spn的对数似然:

pip3 install spflow
2

注意,我们使用了相同的test_数据输入,因为spn仍然需要一个包含数据的numpy数组在列1和列2处,忽略列0。 输出为:

pip3 install spflow
3

另一种选择是对原始spn进行边缘推理。这是通过设置为np.nan来完成的,我们希望在运行中边缘化这个特性。 它不会改变结构。

pip3 install spflow
4

输出与边际SPN的评估完全相同:

pip3 install spflow
3

我们可以使用tensorflow在gpu中进行评估:

pip3 install spflow
6

输出与预期一样,等于python中的输出:

pip3 install spflow
1

我们还可以使用tensorflow在gpu中进行参数优化:

pip3 install spflow
8

当然,输出的可能性更高:

pip3 install spflow
9

我们可以根据SPN捕获的联合分布生成新样本!

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
0

在这里,我们创建了5个新实例,它们遵循分布

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
1

np.nan值表示要采样的列。

我们也可以做条件抽样,也就是说,如果我们有一些变量的证据,我们可以传递这些信息 其他变量的SPN和样本:

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
2

在这里,我们创建了5个新实例,它们的证据是v1=0和v2=0

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
3

通过从数据中学习SPN,然后比较给定类的概率,我们可以进行分类: 假设我们有以下数据集:

basicpng

由两个均值为(5,5)和(10,10)的高斯函数生成,我们将(5,5)处的簇标记为0类,将(10,10)处的簇标记为1类。

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
4

我们可以从以下数据中学习SPN:

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
5

在这里,我们将问题建模为包含3个特征,两个高斯坐标和一个分类标签。 我们指定标签在第2列中,并创建相应的SPN。

现在,假设我们要对两个实例进行分类,一个位于(3,4),另一个位于(12,8)。 为此,我们首先创建一个包含两行和三列的数组。我们将最后一列设置为np.nan,表示我们不知道标签。 并相应地设置2d数组中的其余值。

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
6

第一行是第一个实例,第二行是第二个实例。

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
7

我们可以通过近似最可能解释(mpe)进行分类。 在这里,我们希望第一个实例标记为0,第二个实例标记为1。

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
8

如我们所见,两个实例都被正确分类,因为在最后一列中设置了正确的标签

fromspn.structure.leaves.parametric.ParametricimportCategoricalspn=0.4*(Categorical(p=[0.2,0.8],scope=0)*(0.3*(Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))+0.7*(Categorical(p=[0.5,0.5],scope=1)*Categorical(p=[0.6,0.4],scope=2))))+0.6*(Categorical(p=[0.2,0.8],scope=0)*Categorical(p=[0.3,0.7],scope=1)*Categorical(p=[0.4,0.6],scope=2))
9

我们可以从数据中学习mspn和参数spn:

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
0

在这里,我们有一个包含四个特征的数据集,两个离散和两个实值。

我们可以使用以下命令学习mspn:

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
1

我们可以使用:

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
2

多变量叶

我们可以学习多变量叶的spn。例如,以周柳树(clts)为多变量叶的spn可以通过以下方法学习:

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
3

割集网络(CNET)

利用spflow,我们可以学习cnets的结构和参数,这是一种以clts为叶子的特殊的spns,它提供了精确的mpe推断,用:

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
4

期望和时刻

spns允许您通过直接计算树结构来计算所表示概率函数的一阶和高阶矩。它有三个主要功能。

expectations函数允许您直接计算给定SPN的第一阶矩,以及(可选)需要期望的特征列表和一系列证据。

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
5

如果您通过了功能范围,则只返回对这些功能的期望:

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
6

最后,您还可以将证据传递给计算条件期望的网络:

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
7

实用程序

最后,我们有一些基本实用程序可用于处理SPN:

我们可以确保我们使用的SPN是有效的,也就是说,它是一致和完整的。

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
8

输出表明SPN有效,并且没有调试错误消息:

fromspn.structure.leaves.parametric.ParametricimportCategoricalfromspn.structure.BaseimportSum,Productfromspn.structure.Baseimportassign_ids,rebuild_scopes_bottom_upp0=Product(children=[Categorical(p=[0.3,0.7],scope=1),Categorical(p=[0.4,0.6],scope=2)])p1=Product(children=[Categorical(p=[0.5,0.5],scope=1),Categorical(p=[0.6,0.4],scope=2)])s1=Sum(weights=[0.3,0.7],children=[p0,p1])p2=Product(children=[Categorical(p=[0.2,0.8],scope=0),s1])p3=Product(children=[Categorical(p=[0.2,0.8],scope=0),Categorical(p=[0.3,0.7],scope=1)])p4=Product(children=[p3,Categorical(p=[0.4,0.6],scope=2)])spn=Sum(weights=[0.4,0.6],children=[p2,p4])assign_ids(spn)rebuild_scopes_bottom_up(spn)returnspn
9

计算SPN结构的基本统计信息:

fromspn.io.Graphicsimportplot_spnplot_spn(spn,'basicspn.png')
0

扩展库

如我们所见,使用SPN相对容易。但是,如果我们想使用新的发行版,我们可能需要扩展它。

想象一下,我们想要创建一个新的叶子类型来模拟pareto分布。 我们首先创建一个新类:

fromspn.io.Graphicsimportplot_spnplot_spn(spn,'basicspn.png')
1

现在,如果我们想用这种新的节点类型进行推理,我们只需实现相应的似然函数:

fromspn.io.Graphicsimportplot_spnplot_spn(spn,'basicspn.png')
2

此函数接收节点、计算概率的数据以及结果的numpy数据类型。

现在,我们只需注册此功能,它就可以无缝地供基础结构的其他部分使用:

fromspn.io.Graphicsimportplot_spnplot_spn(spn,'basicspn.png')
3

现在,我们可以创建使用新发行版的SPN,并对其进行评估。

fromspn.io.Graphicsimportplot_spnplot_spn(spn,'basicspn.png')
4

这将产生输出:

fromspn.io.Graphicsimportplot_spnplot_spn(spn,'basicspn.png')
5

SPN库的所有其他方面都可以以类似的方式进行扩展。

spflow可以复制纸张

  • 尼古拉·迪莫罗、安东尼奥·维加里、特雷莎·M.A·巴兹勒、弗洛里安娜·埃斯波西托。"具有极随机割集网络的快速准确密度估计。输入:ECML/PKDD,2017。
  • 尼古拉·迪莫罗、安东尼奥·维加里和特蕾莎·M.A.巴兹勒。"学习贝叶斯随机割集森林"。在ISMIS 2015,LNAI 9384,第1-11页,斯普林格,2015。
  • 尼古拉·迪莫罗、安东尼奥·维加里和弗洛里安娜·埃斯波西托。"利用可分解性学习精确割集网络。在AI*IA。2015年,LNAI 9336,1-12,斯普林格,2015年。
  • 安东尼奥·维加里、尼古拉·迪莫罗和弗洛里安娜·埃斯波西托。"简化、规范和加强和积网络结构学习"。在ECML/PKDD,LNCS,343-358,斯普林格。2015、

在spflow中实现的论文

  • 莫利纳、亚历杭德罗、斯利拉姆·纳塔拉扬和克里斯蒂安·克尔斯汀。"泊松和积网络:可处理多元泊松分布的深层结构〉,载于AAAI,2357-2363页。2017、

  • 莫利纳、亚历杭德罗、安东尼奥·维加里、尼古拉·迪毛罗、斯利拉姆·纳塔拉扬、弗洛里安娜·埃斯波西托和克里斯蒂安·克尔斯汀。"混合和产品网络:混合领域的深层架构〉,《人工智能会议论文集》。2018、

引文

如果您觉得spflow有用,请在您的工作中引用我们:

fromspn.io.Graphicsimportplot_spnplot_spn(spn,'basicspn.png')
6

作者

  • 亚历杭德罗·莫利纳-杜达姆施塔特
  • Antonio Vergari-马克斯普朗克学院
  • Karl Stelzner-Tu Darmstadt
  • 罗伯特·佩哈兹-剑桥大学
  • 尼科拉·迪·毛罗-巴里大学奥尔多·莫罗分校
  • 克里斯汀-杜达姆施塔特

另请参见参与此项目的贡献者列表。

贡献者

  • 莫里茨·库莱萨-杜达姆施塔特
  • 克拉斯·沃克尔
  • 西蒙·罗斯勒-卡尔斯鲁厄理工学院
  • 史蒂文·朗

许可证

此项目是在2.0版apache许可下授权的-有关详细信息,请参见license.md文件

致谢

  • 部分SPEFULL及其激励研究得到了德国科学基金会(DFG)——AIPHES、GRK 1994和CAML、KE 1686/3-1作为SPP 1999的一部分的支持和联邦教育和研究部(BBF)——InDaS,01IS17063B。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
maven字段#getGenericType()抛出java。lang.TypeNotPresentException   用java绘制三角形的几何图形   java无法下载主题和发件人地址(rediff)   java如何使代码线程安全   java在尝试转换FileInputStream中的文件时,我遇到了一个FileNotFound异常   java Moxy和Jackson如何将Json映射到Pojo   在foreach循环中使用BufferedWriter生成新行的java问题   java为什么我的测试在单次执行中运行时间小于1秒,而在maven构建中运行时间大于20秒?   java如何显示下载附件的进度条   了解java rmi的良好实践   .net可以将Java portlet嵌入ASP。网页?   循环如何多次执行Java方法?   java如何确保用户输入在给定的有效范围内?   java单元测试定理   java如何在IntelliJ上运行外部构建项目?   JAVA:试图编写一个检查字符串是否为数字的方法。总是返回错误   javahadoop将特定键的所有map方法生成的所有值都发送到一个reduce方法,对吗?   在java中读取和使用文件