0
$\begingroup$

I was trying to learn Fuzzy Cognitive Map by Active Hebbian Learning approach from here. What I have understand is that the model learns iteratively, at each step a new concept values enters and tune the weighs until the MSE score in output neurone is very small. I thaught that it is similar to stochastic gradient descent. But I don't see any convergence in output MSE value when a new input comes.

import numpy as np
import matplotlib.pyplot as plt


mean1 = [0, 0]
cov1 = [[1, 0], [0, 1]] 

x1, x2 = np.random.multivariate_normal(mean1, cov1, 10000).T
x1 = x1.reshape([len(x1),1])
x2 = x2.reshape([len(x2),1])


def multivariate_normal(x, d, mean, covariance):
    """pdf of the multivariate normal distribution."""
    x_m = x - mean
    return (1. / (np.sqrt((2 * np.pi)**d * np.linalg.det(covariance))) * 
            np.exp(-(np.linalg.solve(covariance, x_m).T.dot(x_m)) / 2))




def sigmoid(x):
    return 1/(1+np.exp(-x))




def FCM(W,X1,X2,y,lr,gamma):
    y1 = 0
    y2 = 0
    loss = []
    Loss = []
    for i in range(0,2000):
        
        A1 = np.dot(W[0],np.transpose(X1[i]))
        A1 = A1.astype('float')
        A2 = np.dot(W[1],np.transpose(X2[i]))
        A2 = A2.astype('float')  
        y1 = sigmoid(A1 + y[i][0])
        y2 = sigmoid(A2 + y[i][1])  
        temp = ((y1 - y[i][0])**2 + (y2 - y[i][1])**2)/2
        print(i)
        Loss.append(temp) 
        count = 0
        while (count < 1):  
            count += 1
            #print(temp)
            A1 = np.dot(W[0],np.transpose(X1[i]))
            A1 = A1.astype('float')
            A2 = np.dot(W[1],np.transpose(X2[i]))
            A2 = A2.astype('float')  
            y1 = sigmoid(A1 + y[i][0])
            y2 = sigmoid(A2 + y[i][1]) 
            temp1 = (1 - gamma)*W[0] + lr*X1[i]*y[i][0]           
            temp2 = (1 - gamma)*W[1] + lr*X2[i]*y[i][1]
            #print(temp1,temp2)
            W[0] = temp1/(np.sqrt(np.dot(temp1,np.transpose(temp1))+np.dot(temp2,np.transpose(temp2))))
            W[1] = temp2/(np.sqrt(np.dot(temp2,np.transpose(temp2))+np.dot(temp1,np.transpose(temp1))))  
            A1 = np.dot(W[0],np.transpose(X1[i]))
            A1 = A1.astype('float')
            A2 = np.dot(W[1],np.transpose(X2[i]))
            A2 = A2.astype('float')  
            y1 = sigmoid(A1 + y[i][0])
            y2 = sigmoid(A2 + y[i][1]) 
            temp = ((y1 - y[i][0])**2 + (y2 - y[i][1])**2)/2   
            loss.append(temp)     
            if count > 1:
                if loss[len(loss) - 1] > loss[len(loss) - 2]:
                    break
       # Loss.append(temp)        
    return [W,Loss]        



X = np.concatenate((x1,x2),axis = 1)  


"""
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_temp = X
X = sc.fit_transform(X)
"""


y = []   
for i in range(len(X)):
    if multivariate_normal(X[i],2,mean1,cov1) < 0.5:
        y.append([0,1])
    else:
        y.append([1,0])
        
y = np.array(y).astype('float')        

y1 = y[:,1].reshape([len(y[:,1]),1])
y2 = y[:,0].reshape([len(y[:,1]),1])
X1 = np.concatenate((X,y1),axis = 1)
X2 = np.concatenate((X,y2),axis = 1)



W = np.array([[0.2,-0.3,-0.4],[-0.1,0.7,-0.6]])




L = FCM(W,X1,X2,y,0.1,0.1)
W2 = L[0]
loss = L[1]

To check the method, I have used Bi-normal data, data points close to then mean and far from the mean are classified to distinct class. The two output nodes are either [1,0] or [0,1].The two attributes of Bi-normal and the second of output are taken as input states for first node. Similarly, The two attributes of Bi-normal and the another first of output are taken as input states for scond node. The loss when a new data comes have ploted for 2000 iteration, there is no indication of convergence of the weights of the map.enter image description here I expected that the loss will grow doen eventually like stochastic gradient descent.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.