注意重要的是:石榴v1.0.0是使用Pytorch作为计算后端而不是Cython的石榴的地面改写。尽管支持相同的功能,但API却显着不同。请参阅教程和示例文件夹以帮助重写您的代码。
readthedocs |教程|例子
石榴是用于概率建模的库,其模块化实施和对所有模型作为其概率分布的处理定义。模块化实现使人们可以轻松地将正常分布置于混合模型中,以创建高斯混合模型,就像将伽玛和泊松分布掉入混合物模型中以创建异质混合物一样容易。但这不是全部!由于每个模型都被视为概率分布,因此可以像正态分布一样容易地将贝叶斯网络掉入混合物中,并且可以将隐藏的Markov模型放入贝叶斯分类器中,以使分类器通过序列制作分类器。这两个设计选择共同使在任何其他概率建模软件包中都看不到灵活性。
最近,石榴(v1.0.0)使用Pytorch从头开始重写,以取代过时的Cython后端。这种改写使我有机会解决我作为BB软件工程师做出的许多不良设计选择。不幸的是,这些更改中的许多都不是向后兼容的,并且会破坏工作流程。另一方面,这些变化显着加强了大多数方法,改进和简化了代码,修复了多年来社区提出的许多问题,并使贡献变得更加容易。我在下面写了更多文章,但是您现在很可能在这里,因为您的代码被打破了,这是TL; DR。
特别向Numfocus大喊大叫,以通过特殊的开发赠款来支持这项工作。
pip install pomegranate
如果您需要在重写之前的最后一个Cython版本,请使用pip install pomegranate==0.14.8 。您可能需要在V3之前手动安装Cython版本。
这一重写是由四个主要原因引起的:
torch.nn.Module的实例torch.masked.MaskedTensor对象支持丢失值NormalDistribution现在是NormalFactorGraph作为一流的公民DenseHMM和SparseHMM模型,这些模型在过渡矩阵的编码方式上有所不同,在真正的密集图上, DenseHMM对象明显更快NaiveBayes已被永久删除,因为它与BayesClassifier是多余的MarkovNetwork尚未实施石榴v1.0.0中的大多数模型和方法比早期版本中的模型和方法要快。这通常是按复杂性扩展的,在小型数据集上,只需看到小速度即可进行简单的分布,但是在大数据集中,更复杂的模型,例如隐藏的马尔可夫模型培训或贝叶斯网络推断。目前值得注意的例外是,除了Chow-liu树建筑以外,贝叶斯网络结构学习仍然不完整,而且速度并不快。在下面的示例中, torchegranate是指用于开发石榴v1.0.0和pomegranate暂时存储库,是指石榴v0.14.8。
谁知道这里发生了什么?荒野。

致密过渡矩阵(CPU)

稀疏过渡矩阵(CPU)

训练具有密集过渡矩阵的125个节点模型



请注意,请参阅Tutorials文件夹以获取代码示例。
从Cython的后端切换到Pytorch后端已启用或扩展了大量功能。由于重写是Pytorch上的薄包装器,因为新功能可以用于Pytorch,因此可以将其应用于石榴型号,而无需我的新版本。
石榴中的所有分布和方法现在都有GPU支持。因为每个分布都是torch.nn.Module 。这意味着模型和数据都必须由用户移至GPU。例如:
> >> X = torch . exp ( torch . randn ( 50 , 4 ))
# Will execute on the CPU
> >> d = Exponential (). fit ( X )
> >> d . scales
Parameter containing :
tensor ([ 1.8627 , 1.3132 , 1.7187 , 1.4957 ])
# Will execute on a GPU
> >> d = Exponential (). cuda (). fit ( X . cuda ())
> >> d . scales
Parameter containing :
tensor ([ 1.8627 , 1.3132 , 1.7187 , 1.4957 ], device = 'cuda:0' )同样,所有模型均为分布,因此可以在GPU上使用。当模型移至GPU时,与IT相关的所有模型(例如分布)也将移至GPU。
> >> X = torch . exp ( torch . randn ( 50 , 4 )). cuda ()
> >> model = GeneralMixtureModel ([ Exponential (), Exponential ()]). cuda ()
> >> model . fit ( X )
[ 1 ] Improvement : 1.26068115234375 , Time : 0.001134 s
[ 2 ] Improvement : 0.168121337890625 , Time : 0.001097 s
[ 3 ] Improvement : 0.037841796875 , Time : 0.001095 s
>> > model . distributions [ 0 ]. scales
Parameter containing :
>> > model . distributions [ 1 ]. scales
tensor ([ 0.9141 , 1.0835 , 2.7503 , 2.2475 ], device = 'cuda:0' )
Parameter containing :
tensor ([ 1.9902 , 2.3871 , 0.8984 , 1.2215 ], device = 'cuda:0' )从理论上讲,石榴模型可以与其他Pytorch模块相同的混合或低精度制度运行。但是,由于石榴比大多数神经网络使用更复杂的操作,因此这有时在实践中无效或没有帮助,因为这些操作尚未在低精度制度中进行优化或实施。因此,希望此功能会随着时间的流逝而变得更加有用。
> >> X = torch . randn ( 100 , 4 )
> >> d = Normal ( covariance_type = 'diag' )
> >>
>> > with torch . autocast ( 'cuda' , dtype = torch . bfloat16 ):
> >> d . fit ( X )石榴分布都是torch.nn.Module的所有实例,因此序列化与任何其他Pytorch模型相同。
保存:
> >> X = torch . exp ( torch . randn ( 50 , 4 )). cuda ()
> >> model = GeneralMixtureModel ([ Exponential (), Exponential ()], verbose = True )
> >> model . cuda ()
> >> model . fit ( X )
> >> torch . save ( model , "test.torch" )加载中:
> >> model = torch . load ( "test.torch" )请注意,
torch.compile正在由Pytorch团队积极开发,并可能会迅速改善。目前,您可能需要传递check_data=False初始化模型以避免兼容性问题。
在Pytorch v2.0.0中, torch.compile被引入了围绕工具的灵活包装纸,该工具将操作融合在一起,使用CUDA图,并通常尝试在GPU执行中删除I/O瓶颈。由于这些瓶颈在小型至中等大小的数据设置中可能非常重要,因此许多石榴用户都面临着,因此torch.compile似乎非常有价值。您不应针对整个模型(主要是编译forward方法),而是应该从对象中编译单个方法。
# Create your object as normal
> >> mu = torch . exp ( torch . randn ( 100 ))
> >> d = Exponential ( mu ). cuda ()
# Create some data
> >> X = torch . exp ( torch . randn ( 1000 , 100 ))
> >> d . log_probability ( X )
# Compile the `log_probability` method!
> >> d . log_probability = torch . compile ( d . log_probability , mode = 'reduce-overhead' , fullgraph = True )
> >> d . log_probability ( X )不幸的是,当以嵌套方式调用方法时,我很难在编译混合模型的predict方法时,在其中调用了每个分布的log_probability方法时,我torch.compile工作。我试图以避免其中一些错误的方式组织代码,但是由于现在的错误消息是不透明的,所以我遇到了一些困难。
石榴支持通过torch.masked.MaskedTensor对象处理具有缺失值的数据。简而言之,只需对丢失的值戴口罩即可。
> >> X = < your tensor with NaN for the missing values >
> >> mask = ~ torch . isnan ( X )
>> > X_masked = torch . masked . MaskedTensor ( X , mask = mask )
>> > d = Normal ( covariance_type = 'diag' ). fit ( X_masked )
>> > d . means
Parameter containing :
tensor ([ 0.2271 , 0.0290 , 0.0763 , 0.0135 ])当前所有算法都将失踪性视为要忽略的东西。例如,当计算具有缺失值的列的平均值时,平均值将仅是当前值的平均值。不估算缺失值,因为不当的插补会偏向您的数据,产生不太可能估计哪些分布扭曲的分布以及缩小差异。
因为并非所有操作都适用于蒙版,所以尚未支持以下分布缺失值:伯努利,分类,正常,完全协方差,统一
石榴v1.0.0中的一项新功能能够通过混合模型,贝叶斯分类器和隐藏的马尔可夫模型的每个观察结果传递先前的概率。在评估可能性之前,观察结果属于模型的一部分,并且应在0到1之间。当这些值包括1.0以进行观察时,它被视为标签,因为它被视为标签,因为可能的可能性不再重要,因为将观察结果分配给州。因此,当每个观测值对某些状态,半监督的学习均为1.0时,可以使用这些先前的概率进行标记的训练,而当观察值的子集(包括仅在序列中仅针对隐藏的马可比模型部分标记序列),或者在值为0和1之间的更复杂的权重形式。
