Access weights in RESTRICTED BOLTZMANN MACHINES

How to access weights

Hy, for any given layer of a model which you define in pytorch, it’s weights can be accessed using this.

model.layer[index].weight
1 Like

But I am not able to figure it out for Restricted Boltzmann Machines. Will you help me with this?

import pandas as pd
import torch

import torch.nn.parallel

import torch.utils.data

x_dataset = pd.read_csv(r"C:\Users\Kunal Dapse\Downloads\AI-DataTrain.csv")
#y_dataset = pd.read_csv(r"C:\Users\Kunal Dapse\Downloads\AI-DataTest.csv")
training_dataset = x_dataset.iloc[:900,1:11].values
test_dataset     =x_dataset.iloc[900:,1:11].values

training_dataset = torch.FloatTensor(training_dataset)
test_dataset = torch.FloatTensor(test_dataset)


class RBM():
    def __init__(self,nv,nh):
        self.W = torch.randn(nh,nv)
        self.a = torch.randn(1, nh)
        self.b = torch.randn(1, nv)
    def sample_h(self, x):
        wx = torch.mm(x, self.W.t())
        activation = wx + self.a.expand_as(wx)
        p_h_given_v = torch.sigmoid(activation)
        return p_h_given_v, torch.bernoulli(p_h_given_v)
    def sample_v(self, y):
        wy = torch.mm(y,self.W)
        activation = wy + self.b.expand_as(wy)
        p_v_given_h = torch.sigmoid(activation)
        return p_v_given_h, torch.bernoulli(p_v_given_h)
    def train(self, v0, vk, ph0, phk):
        self.W += (torch.mm(v0.t(), ph0) - torch.mm(vk.t(), phk)).t()
        self.b += torch.sum((v0-vk), 0)
        self.a += torch.sum((ph0-phk), 0)

nv = len(training_dataset[0])
nh = 100
batch_size = 100
rbm = RBM(nv, nh)


#Training the RBM
nb_epoch = 10
for epoch in range(1, nb_epoch + 1):
    train_loss = 0
    s = 0.
    for id_examinee in range(0,1000 -  batch_size, batch_size):
        vk = training_dataset[id_examinee:id_examinee + batch_size]
        v0 = training_dataset[id_examinee:id_examinee + batch_size]
        ph0,_ =rbm.sample_h(v0)
        for k in range(10):
            _,hk = rbm.sample_h(vk)
            _,vk = rbm.sample_v(hk)
        phk,_ = rbm.sample_h(vk)
        rbm.train(v0, vk, ph0, phk)
        train_loss += torch.mean(torch.abs(v0 - vk))
        s += 1.
    print('epoch: '+ str(epoch)+' loss: '+str(train_loss/s))

#Testing the RBM

test_loss = 0
s = 0.
for id_examinee in range(0, 1000):
    v = training_dataset[id_examinee:id_examinee+1]
    vt = test_dataset[id_examinee:id_examinee +1]

    if len(vt[vt>=0]) > 0:
       _,h = rbm.sample_h(v)
       _,v = rbm.sample_v(h)

       test_loss += torch.mean(torch.abs(vt[vt>=0] - v[vt>=0]))
       s += 1.
print('test loss: '+str(test_loss/s))

Hy Kunal, Sure.
First you need to extend your class from torch.nn.Module to create model class.

class RBM(nn.Module):
       def __init__(self):
              super(RBM,self).__init()
              //code 
              self.W = nn.Parameter(torch.randn(nh,nv))
              self.v_bias = nn.Parameter(torch.randn(1,nh))
              self.h_bias = nn.Parameter(torch.zeros(1,nv))
      def forward(self,input):
              self.layer(input)

You can define the rest of the function inside the class and call them in forward function.

1 Like

I need help again. I tried to figure it out but I am stuck. I want a list of weights but I am not able to solve this error AttributeError: ‘RBM’ object has no attribute 'layer.

import pandas as pd
import torch
import torch.nn as nn
import torch.nn.parallel

import torch.utils.data

x_dataset = pd.read_csv(r"C:\Users\Kunal Dapse\Downloads\AI-DataTrain.csv")
y_dataset = pd.read_csv(r"C:\Users\Kunal Dapse\Downloads\AI-DataTest.csv")
training_dataset = x_dataset.iloc[:900,1:11].values
test_dataset     =x_dataset.iloc[900:,1:11].values

training_dataset = torch.FloatTensor(training_dataset)
test_dataset = torch.FloatTensor(test_dataset)


class RBM(nn.Module):
    def __init__(self, nv, nh):
              super(RBM,self).__init__()
              
              self.W = nn.Parameter(torch.randn(nh,nv))
              self.a = nn.Parameter(torch.randn(1,nh))
              self.b = nn.Parameter(torch.zeros(1,nv))
    def forward(self,input):
              out = self.layer(input)
              return out
    def sample_h(self, x):
        wx = torch.mm(x, self.W.t())
        activation = wx + self.a.expand_as(wx)
        p_h_given_v = torch.sigmoid(activation)
        return p_h_given_v, torch.bernoulli(p_h_given_v)
    def sample_v(self, y):
        wy = torch.mm(y,self.W)
        activation = wy + self.b.expand_as(wy)
        p_v_given_h = torch.sigmoid(activation)
        return p_v_given_h, torch.bernoulli(p_v_given_h)
    def train(self, v0, vk, ph0, phk):
        with torch.no_grad():
            
            self.W += (torch.mm(v0.t(), ph0) - torch.mm(vk.t(), phk)).t()
            self.b += torch.sum((v0-vk), 0)
            self.a += torch.sum((ph0-phk), 0)

nv = len(training_dataset[0])
nh = 100
batch_size = 100
rbm = RBM(nv, nh)


#Training the RBM
nb_epoch = 10
for epoch in range(1, nb_epoch + 1):
    train_loss = 0
    s = 0.
    for id_examinee in range(0,1000 -  batch_size, batch_size):
        vk = training_dataset[id_examinee:id_examinee + batch_size]
        v0 = training_dataset[id_examinee:id_examinee + batch_size]
        ph0,_ =rbm.sample_h(v0)
        for k in range(10):
            _,hk = rbm.sample_h(vk)
            _,vk = rbm.sample_v(hk)
        phk,_ = rbm.sample_h(vk)
        rbm.train(v0, vk, ph0, phk)
        train_loss += torch.mean(torch.abs(v0 - vk))
        s += 1.
    print('epoch: '+ str(epoch)+' loss: '+str(train_loss/s))

#Testing the RBM

test_loss = 0
s = 0.
for id_examinee in range(0, 1000):
    v = training_dataset[id_examinee:id_examinee+1]
    vt = test_dataset[id_examinee:id_examinee +1]

    if len(vt[vt>=0]) > 0:
       _,h = rbm.sample_h(v)
       _,v = rbm.sample_v(h)

       test_loss += torch.mean(torch.abs(vt[vt>=0] - v[vt>=0]))
       s += 1.
print('***test loss: '+str(test_loss/s))

Questions = ['Q1', 'Q2', 'Q3','Q4','Q5', 'Q6', 'Q7', 'Q8', 'Q9', 'Q10']
model_1 = RBM(nv,nh) ## ERROR!!!
Weights = model_1.layer[0].weight
df = pd.DataFrame({'Questions': Questions,
                   'Weights': Weights
                   })

Since in RBM implementation, that you have done weights are initialized here, you can just access them by a return call.

def get_weights():
        return self.W

Also you should look at some other implementation of rbm, I liked this one much better.

1 Like

But I am trying to create the list of weights assigned which I couldn’t do it. As you said I used model.layer[index].weight but I am facing an Attribute Error.

Would you please guide me I am new to Deep learning currently working on a project.

Hy @Kunal_Dapse, I would highly recommend you read some tutorials first, you’re totaly misunderstanding me here. The way we construct models in pytorch is by inheriting them through nn.Module class.
Something like this

import torch.nn as nn
class Net(nn.Module):
       nn.Linear(input_channels,output_channels)
       /// Further layer.

Now I have declared a single Linear (MLP) inside my model using torch.nn.Linear, this layer contains all the attributes an MLP should have, weights bias etc.
Which we can later access like this which I explained first.

Now, for this what you can do is.

You can append these weights in a list during training and access them later.

1 Like

Thanks @Usama_Hasan, I really appreciate your help. My problem is solved :slightly_smiling_face: :innocent:

That’s good to hear. :slight_smile:

1 Like