# 受限玻尔兹曼机的实现及其在推荐系统中的应用

```import numpy as np

num_hidden = 2
num_visible = 6
np_rng = np.random.RandomState(1234)
weights = np.asarray(np_rng.uniform(
low=-0.1 * np.sqrt(6. / (num_hidden + num_visible)),
high=0.1 * np.sqrt(6. / (num_hidden + num_visible)),
size=(num_visible, num_hidden)))
weights```

```array([[-0.0534304 ,  0.02114986],
[-0.01078587,  0.04942556],
[ 0.04849323, -0.03938812],
[-0.03871753,  0.05228579],
[ 0.07935206,  0.06511344],
[-0.02462677,  0.00017236]])```

```# 加入bias unit.
weights = np.insert(weights, 0, 0, axis=0)
weights = np.insert(weights, 0, 0, axis=1)
weights```

```array([[ 0.        ,  0.        ,  0.        ],
[ 0.        , -0.0534304 ,  0.02114986],
[ 0.        , -0.01078587,  0.04942556],
[ 0.        ,  0.04849323, -0.03938812],
[ 0.        , -0.03871753,  0.05228579],
[ 0.        ,  0.07935206,  0.06511344],
[ 0.        , -0.02462677,  0.00017236]])```

```data = np.array([[1,1,1,0,0,0],[1,0,1,0,0,0],[1,1,1,0,0,0],[0,0,1,1,1,0], [0,0,1,1,0,0],[0,0,1,1,1,0]])
num_examples = data.shape[0]
data = np.insert(data, 0, 1, axis=1)
data```

```array([[1, 1, 1, 1, 0, 0, 0],
[1, 1, 0, 1, 0, 0, 0],
[1, 1, 1, 1, 0, 0, 0],
[1, 0, 0, 1, 1, 1, 0],
[1, 0, 0, 1, 1, 0, 0],
[1, 0, 0, 1, 1, 1, 0]])```

```pos_hidden_activations = np.dot(data, weights)
pos_hidden_activations```

```array([[ 0.        , -0.01572304,  0.0311873 ],
[ 0.        , -0.00493717, -0.01823826],
[ 0.        , -0.01572304,  0.0311873 ],
[ 0.        ,  0.08912777,  0.07801112],
[ 0.        ,  0.00977571,  0.01289768],
[ 0.        ,  0.08912777,  0.07801112]])```

```def logistic(x):
return 1.0 / (1 + np.exp(-x))
pos_hidden_probs = logistic(pos_hidden_activations)
pos_hidden_probs[:, 0] = 1
pos_hidden_probs```

```array([[1.        , 0.49606932, 0.50779619],
[1.        , 0.49876571, 0.49544056],
[1.        , 0.49606932, 0.50779619],
[1.        , 0.5222672 , 0.5194929 ],
[1.        , 0.50244391, 0.50322437],
[1.        , 0.5222672 , 0.5194929 ]])```

rand函数会随机生成一个处于0到1之间的数，将上述算出的节点激活概率与一个这样的随机数比较大小来决定是否激活此节点，这意味着即使此时某次训练中某隐藏结点的激活概率为0.99，也是有可能不被激活的。

```pos_hidden_states = pos_hidden_probs > np.random.rand(num_examples, num_hidden + 1)
pos_hidden_states```

```array([[ True,  True,  True],
[ True, False, False],
[ True, False, False],
[ True,  True,  True],
[ True, False,  True],
[ True, False,  True]])```

```pos_associations = np.dot(data.T, pos_hidden_probs)
pos_associations```

```array([[6.        , 3.03788267, 3.05324311],
[3.        , 1.49090435, 1.51103295],
[2.        , 0.99213864, 1.01559239],
[6.        , 3.03788267, 3.05324311],
[3.        , 1.54697831, 1.54221017],
[2.        , 1.04453441, 1.03898579],
[0.        , 0.        , 0.        ]])```

```r = RBM(num_visible = 6, num_hidden = 2)
training_data = np.array([[1,1,1,0,0,0],[1,0,1,0,0,0],[1,1,1,0,0,0],[0,0,1,1,1,0], [0,0,1,1,0,0],[0,0,1,1,1,0]])
r.train(training_data, max_epochs = 5000)
print(r.weights[1:, 1:])```

```[[-8.09650002  3.95552071]
[-5.45512759  1.42845858]
[ 1.74474585  4.06127352]
[ 7.74906751 -3.54062571]
[ 3.18686136 -7.33215302]
[-2.46868951 -2.60826581]]```