本文首发于微信公众号:有三AI
作者:小米粥
1 玻尔兹曼机
玻尔兹曼机属于另一种显式概率模型,它是一种基于能量的模型。训练玻尔兹曼机同样需要基于极大似然的思想,但在计算极大似然的梯度时,运用了一种不同于变分法的近似算法。玻尔兹曼机已经较少引起关注,故在此我们只简述。
在能量模型中,通常将样本的概率
其中,

在RBM中,可见变量和隐藏变量的联合概率分布由能量函数给出,即
其中能量函数的表达式为
配分函数
考虑到二分图的特殊结构,发现在隐藏变量已知时,可见变量之间彼此独立;当可见变量已知时,隐藏变量之间也彼此独立,即有
以及
进一步地,可得到离散概率的具体表达式:
为了使得RBM与能量模型有一致的表达式,定义可见变量
其中
配分函数
可以看出,RBM明确定义了可见变量的概率密度函数,但它并不易求解,因为计算配分函数
分析其梯度表达式,其中不易计算的部分在于对可见变量
玻尔兹曼机依赖马尔可夫链来训练模型或者使用模型生成样本,但是这种技术现在已经很少被使用了,很可能是因为马尔可夫链近似技术不能被适用于像ImageNet的生成问题。并且,即便是马尔可夫链方法可以很好的用于训练,但是使用一个基于马尔可夫链的模型生成样本是需要花费很大计算代价。
2 玻尔兹曼机代码
受限玻尔兹曼机的完整代码如下:
import numpy as np
import torch
import torch.utils.data
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torchvision import datasets, transforms
from torchvision.utils import make_grid, save_image
import matplotlib.pyplot as plt
batch_size = 64
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor()])),batch_size=batch_size)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data', train=False, transform=transforms.Compose([
transforms.ToTensor()])),batch_size=batch_size)
class RBM(nn.Module):
def __init__(self, n_vis=784, n_hin=500, k=5):
super(RBM, self).__init__()
self.W = nn.Parameter(torch.randn(n_hin, n_vis) * 1e-2)
self.v_bias = nn.Parameter(torch.zeros(n_vis))
self.h_bias = nn.Parameter(torch.zeros(n_hin))
self.k = k
def sample_from_p(self, p):
return F.relu(torch.sign(p - Variable(torch.rand(p.size()))))
def v_to_h(self, v):
p_h = F.sigmoid(F.linear(v, self.W, self.h_bias))
sample_h = self.sample_from_p(p_h)
return p_h, sample_h
def h_to_v(self, h):
p_v = F.sigmoid(F.linear(h, self.W.t(), self.v_bias))
sample_v = self.sample_from_p(p_v)
return p_v, sample_v
def forward(self, v):
pre_h1, h1 = self.v_to_h(v)
h_ = h1
for _ in range(self.k):
pre_v_, v_ = self.h_to_v(h_)
pre_h_, h_ = self.v_to_h(v_)
return v, v_
def free_energy(self, v):
vbias_term = v.mv(self.v_bias)
wx_b = F.linear(v, self.W, self.h_bias)
hidden_term = wx_b.exp().add(1).log().sum(1)
return (-hidden_term - vbias_term).mean()
rbm = RBM(k=1)
train_op = optim.SGD(rbm.parameters(),0.1)
for epoch in range(10):
loss_ = []
for _, (data, target) in enumerate(train_loader):
data = Variable(data.view(-1, 784))
sample_data = data.bernoulli()
print(sample_data[0])
v, v1 = rbm(sample_data)
loss = rbm.free_energy(v) - rbm.free_energy(v1)
#loss_.append(loss.data[0])
train_op.zero_grad()
loss.backward()
train_op.step()
print np.mean(loss_)
show_adn_save("real",make_grid(v.view(32,1,28,28).data))
show_adn_save("generate",make_grid(v1.view(32,1,28,28).data))
def show_adn_save(file_name,img):
npimg = np.transpose(img.numpy(),(1,2,0))
f = "./%s.png" % file_name
plt.imshow(npimg)
plt.imsave(f, npimg)
要了解更多,请跳转阅读:
小米粥:生成模型大观(1)-无监督生成模型
小米粥:生成模型大观(2)-极大似然法
小米粥:生成模型大观(3)-完全可见置信网络
小米粥:生成模型大观(4)-流模型
小米粥:生成模型大观(5)-VAE
小米粥:生成模型大观(7)-隐式生成模型
最后
以上就是传统方盒最近收集整理的关于受限玻尔兹曼机_生成模型大观(6)-玻尔兹曼机的全部内容,更多相关受限玻尔兹曼机_生成模型大观(6)-玻尔兹曼机内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复