拓展在pytorch上的深度生成模型的库(Probabilistic Torch)实现半监督MNIST与概率编程

Song • 416 次浏览 • 0 个回复 • 2018年01月31日

Probabilistic Torch是拓展在pytorch上的深度生成模型的库,与EdwardPyro的精神和设计目标相似,与后者共享许多设计特征。

Probabilistic Torch的设计旨在尽可能像PyTorch一样。Probabilistic Torch模型的写法就像编写任何PyTorch模型一样,但要使用三个附加的构造:

  • 一个重新参数化分布库,实现对日志概率质量和密度函数进行采样和评估的方法
  • 一个微量跟踪数据结构,其既用于实例化并存储的随机变量。
  • 使用Monte Carlo重要性加权估计量近似对数边际可能性下限的目标函数。

这个知识库来自NIPS 2017论文:

@inproceedings{siddharth2017learning,
    title = {Learning Disentangled Representations with Semi-Supervised Deep Generative Models},
    author = {Siddharth, N. and Paige, Brooks and van de Meent, Jan-Willem and Desmaison, Alban and Goodman, Noah D. and Kohli, Pushmeet and Wood, 
Frank and Torr, Philip},
    booktitle = {Advances in Neural Information Processing Systems 30},
    editor = {I. Guyon and U. V. Luxburg and S. Bengio and H. Wallach and R. Fergus and S. Vishwanathan and R. Garnett},
    pages = {5927--5937},
    year = {2017},
    publisher = {Curran Associates, Inc.},
    url = {http://papers.nips.cc/paper/7174-learning-disentangled-representations-with-semi-supervised-deep-generative-models.pdf}
}

安装

  • 1、安装PyTorch
  • 2、从源代码安装此存储库
    pip install git+git://github.com/probtorch/probtorch
  • 3、请参阅Jupyte笔记说明的使用情况的examples/子目录。
  • 4、构建和阅读API文档,请执行以下操作
git clone git://github.com/probtorch/probtorch
cd probtorch/docs
pip install -r requirements.txt
make html
open build/html/index.html

教程:半监督MNIST

Probabilistic Torch中的模型定义了变分自动编码器。编码器和解码器模型都可以作为PyTorch模型来实现nn.Module子类的标准。

__init__方法中,我们初始化网络层,就像在PyTorch模型中一样。在forward方法中,我们另外初始化一个Trace变量,它是一个一次写入类似字典的对象。该Trace数据结构实现了实例名为随机变量,其值和对数概率存储为指定项下的方法。

这是一个标准的半监督VAE的编码器的实现,由Kingma和他的同事们介绍[1]

import torch
import torch.nn as nn
import probtorch

class Encoder(nn.Module):
    def __init__(self, num_pixels=784, num_hidden=50, num_digits=10, num_style=2):
        super(self.__class__, self).__init__()
        self.h = nn.Sequential(
                    nn.Linear(num_pixels, num_hidden), 
                    nn.ReLU())
        self.y_log_weights = nn.Linear(num_hidden, num_digits)
        self.z_mean = nn.Linear(num_hidden + num_digits, num_style)
        self.z_log_std = nn.Linear(num_hidden + num_digits, num_style)

    def forward(self, x, y_values=None, num_samples=10):
        q = probtorch.Trace()
        x = x.expand(num_samples, *x.size())
        if y_values is not None:
            y_values = y_values.expand(num_samples, *y_values.size())
        h = self.h(x)
        y = q.concrete(self.y_log_weights(h), 0.66,
                       value=y_values, name='y')
        h2 = torch.cat([y, h], -1)
        z = q.normal(self.z_mean(h2), 
                     torch.exp(self.z_log_std(h2)), 
                     name='z')
        return q

在上面的代码中,q.concrete根据y_values是否提供监督值,抽样或观察Concrete/Gumbel-Softmax的离散分布。该方法q.normal来自一个正态分布的单变量。

产生的结果跟随q现在包含两个条目q['y']q['z'],这是一个实例RandomVariable的类,其存储两个值和与变量相关的对数概率。所存储的值现在用于调节解码器模型的执行:

from torch.autograd import Variable

def binary_cross_entropy(x_mean, x, EPS=1e-9):
    return - (torch.log(x_mean + EPS) * x + 
              torch.log(1 - x_mean + EPS) * (1 - x)).sum(-1)

class Decoder(nn.Module):
    def __init__(self, num_pixels=784, num_hidden=50, num_digits=10, num_style=2):
        super(self.__class__, self).__init__()
        self.num_digits = num_digits
        self.h = nn.Sequential(
                   nn.Linear(num_style + num_digits, num_hidden),
                   nn.ReLU())
        self.x_mean = nn.Sequential(
                        nn.Linear(num_hidden, num_pixels),
                        nn.Sigmoid())

    def forward(self, x, q=None):
        if q is None:
            q = probtorch.Trace()
        p = probtorch.Trace()
        y = p.concrete(Variable(torch.zeros(x.size(0), self.num_digits)), 0.66,
                       value=q['y'], name='y')
        z = p.normal(0.0, 1.0, value=q['z'], name='z')
        h = self.h(torch.cat([y, z], -1))
        p.loss(binary_cross_entropy, self.x_mean(h), x, name='x')
        return p

上述模型既可用于条件正向执行,也可用于生成。这样做的原因是,对于未被实例化的变量名kq[k]没有返回任何值。

为了训练上面的模型组件,Probabilistic Torch提供了计算对数边界可能性下限的估计的目标,现在可以使用标准的PyTorch优化器

from probtorch.objectives.montecarlo import elbo
from random import rand
# initialize model and optimizer
enc = Encoder()
dec = Decoder()
optimizer =  torch.optim.Adam(list(enc.parameters())
                              + list(dec.parameters()))
# define subset of batches that will be supervised
supervise = [rand() < 0.01 for _ in data]
# train model for 10 epochs
for epoch in range(10):
    for b, (x, y) in data:
        x = Variable(x)
        if supervise[b]:
            y = Variable(y)
            q = enc(x, y)
        else:
            q = enc(x)
        p = dec(x, q)
        loss = -elbo(q, p, sample_dim=0, batch_dim=1)
        loss.backward()
        optimizer.step()

有关更多详细信息,请参阅examples/子目录中的Jupyter笔记

参考

KingmaDiederik PDanilo J RezendeShakir MohamedMax Welling。“深度生成模型的半监督式学习”,http://arxiv.org/abs/1406.5298

贡献者(按加入顺序)

项目地址:probtorch/probtorch

  • Jan-Willem van de Meent
  • Siddharth Narayanaswamy
  • 布鲁克斯·佩奇
  • 奥尔本Desmaison
  • 阿利坎Bozkurt
  • Amirsina Torfi

原创文章,转载请注明 :拓展在pytorch上的深度生成模型的库(Probabilistic Torch)实现半监督MNIST与概率编程 - pytorch中文网
原文出处: https://ptorch.com/news/120.html
问题交流群 :168117787
提交评论
要回复文章请先登录注册
用户评论
  • 没有评论
Pytorch是什么?关于Pytorch! Pytorch的高级训练,数据增强和实用程序(torchsample/Keras)