RBM我们添加了将可见输入转换为隐藏表示以及将隐藏表示转换回重构的可见输入的方法。两种方法都返回激活概率,而sample_h方法也返回观察到的隐藏状态
<pre><code>
class RBM():
def __init__(self, visible_dim, hidden_dim, gaussian_hidden_distribution=False):
self.visible_dim = visible_dim
self.hidden_dim = hidden_dim
self.gaussian_hidden_distribution = gaussian_hidden_distribution
# intialize parameters
self.W = torch.randn(visible_dim, hidden_dim) * 0.1
self.h_bias = torch.zeros(hidden_dim) # visible --> hidden
self.v_bias = torch.zeros(visible_dim) # hidden --> visible
# parameters for learning with momentum
self.W_momentum = torch.zeros(visible_dim, hidden_dim)
self.h_bias_momentum = torch.zeros(hidden_dim)
self.v_bias_momentum = torch.zeros(visible_dim)
def sample_h(self, v):
activation = torch.mm(v, self.W) + self.h_bias
if self.gaussian_hidden_distribution:
return activation, torch.normal(activation, torch.tensor([1]))
else:
p = torch.sigmoid(activation)
return p, torch.bernoulli(p)
def sample_v(self, h):
"""Get visible activation probabilities"""
activation = torch.mm(h, self.W.t()) + self.v_bias
p = torch.sigmoid(activation)
return p
def update_weights(self, v0, vk, ph0, phk, lr,
momentum_coef, weight_decay, batch_size):
self.W_momentum *= momentum_coef
self.W_momentum += torch.mm(v0.t(), ph0) - torch.mm(vk.t(), phk)
self.h_bias_momentum *= momentum_coef
self.h_bias_momentum += torch.sum((ph0 - phk), 0)
self.v_bias_momentum *= momentum_coef
self.v_bias_momentum += torch.sum((v0 - vk), 0)
self.W += lr*self.W_momentum/batch_size
self.h_bias += lr*self.h_bias_momentum/batch_size
self.v_bias += lr*self.v_bias_momentum/batch_size
self.W -= self.W * weight_decay # L2 weight decay
</code></pre>
训练RBM在训练模型时,我收到“RuntimeError:self must be a matrix”,有人能帮我一下,告诉我应该在代码中做什么修改吗?
<pre><code>
models = [] # store trained RBM models
visible_dim = 784
rbm_train_dl = train_dl_flat
for hidden_dim in [1000, 500, 250, 2]:
# configs - we have a different configuration for the last layer
num_epochs = 30 if hidden_dim == 2 else 10
lr = 1e-3 if hidden_dim == 2 else 0.1
use_gaussian = hidden_dim == 2
# train RBM
rbm = RBM(visible_dim=visible_dim, hidden_dim=hidden_dim,
gaussian_hidden_distribution=use_gaussian)
for epoch in range(num_epochs):
for i, data_list in enumerate(train_dl):
v0 = data_list[0]
# get reconstructed input via Gibbs sampling with k=1
_, hk = rbm.sample_h(v0)
pvk = rbm.sample_v(hk)
# update weights
rbm.update_weights(v0, pvk, rbm.sample_h(v0)[0], rbm.sample_h(pvk)[0], lr,
momentum_coef=0.5 if epoch < 5 else 0.9,
weight_decay=2e-4,
batch_size=sample_data.shape[0])
models.append(rbm)
# rederive new data loader based on hidden activations of trained model
new_data = [model.sample_h(data_list[0])[0].detach().numpy() for data_list in rbm_train_dl]
rbm_train_dl = DataLoader(
TensorDataset(torch.Tensor(np.concatenate(new_data))),
batch_size=64, shuffle=False
)
visible_dim = hidden_dim
</code></pre>
错误
<pre><code>
RuntimeError Traceback (most recent call last)
<ipython-input-3-53fe4223334d> in <module>()
16
17 # get reconstructed input via Gibbs sampling with k=1
---> 18 _, hk = rbm.sample_h(v0)
19 pvk = rbm.sample_v(hk)
20 # update weights
<ipython-input-1-49d2abc1da92> in sample_h(self, v)
15 def sample_h(self, v):
16 """Get sample hidden values and activation probabilities"""
---> 17 activation = torch.mm(v, self.W) + self.h_bias
18 if self.gaussian_hidden_distribution:
19 return activation, torch.normal(activation, torch.tensor([1]))
RuntimeError: self must be a matrix
</code></pre>
1条答案
按热度按时间xtfmy6hx1#
看起来你需要广播(因为你在2D矩阵上乘以1D向量)。
请尝试改用
torch.matmul
。此链接用于了解
mm
和matmul
之间的区别:What's the difference between torch.mm, torch.matmul and torch.mul?