def free_energy(self, v):
"""
:param Variable (batch_size, in_channels, image_height, image_width) - input data (training data)
:return: scalar
"""
batch_size = v.data.shape[0]
in_channels = self.in_channels
real = self.real
if real == 0:
'''
visible layer is 0, 1 (bit)
vbias_term = 1 * SUM(a(i) * v(i))
'''
v_sum = F.sum(v, axis=(2, 3)) # sum over image_height & image_width
# Originally, it should return sum for each batch.
# but it returns scalar, which is sum over batches, since sum is used at the end anyway.
vbias_term = F.sum(F.matmul(v_sum, self.conv.a))
wx_b = self.conv(v)
else:
'''
visible layer takes real value
vbias_term = 0.5 * SUM((v(i)-a(i)) * (v(i) - a(i)))
'''
#TODO: check
#m = Variable(xp.ones((batch_size, 1), dtype=xp.float32))
n = F.reshape(self.conv.a, (1, in_channels, 1, 1))
xp = cuda.get_array_module(n.data)
std_ch = xp.reshape(self.std, (1, in_channels, 1, 1))
#v_ = v - F.matmul(m, n)
v_ = (v - F.broadcast_to(n, v.data.shape)) / std_ch
vbias_term = F.sum(0.5 * v_ * v_)
wx_b = self.conv(v / std_ch)
hidden_term = F.sum(F.log(1 + F.exp(wx_b)))
# print('vbias = ', vbias_term.data, ', hidden = ', hidden_term.data, 'F.exp(wx_b) = ', F.exp(wx_b).data)
return - vbias_term - hidden_term
评论列表
文章目录