Самоорганизующаяся карта не работает идеально, один и тот же класс всегда выводится - PullRequest
1 голос
/ 23 февраля 2020

Я хочу обучить и протестировать Сеть Кохонена , которая является своего рода (самоорганизующимися картами).

Моя проблема заключается в том, что я получаю все выходные данные с одинаковыми значениями либо 0000, либо 1111 каждый раз, хотя я использую матрицу случайных весов, которая будет меняться каждый раз, когда я запускаю код!

Мой набор данных - это 3 крошечных текстовых файла по ссылке ниже: обратите внимание, что я использую примеры сначала из данных моего поезда, чтобы проверить правильность моего кода, прежде чем использовать тестовые данные.

ссылка на наборы данных

#==============================================================
#Import necessary Libraries
#---------------------------
import random
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from Kohonen_Funcs import Train,Test
#=============================================================
# Reading Data
#=============================================================
patient = pd.read_fwf('patient.txt', header = None, delimiter="\t",keep_default_na=False)
control = pd.read_fwf('control.txt', header = None, delimiter="\t",keep_default_na=False)
#-------------------------------------------------------------
test = np.loadtxt('test_dud_ten.txt', delimiter="\t",dtype = str,max_rows=4)
#xt = test[:,0:650].astype(float)
#-------------------------------------------------------------
#=============================================================
# convert Data into Arrays to deal with.
#=============================================================
xp = np.array(patient,dtype = float)
xp = np.roll(xp, 10,axis = 1) # shift data on time axis by 10 to be aligned

xc = np.array(control,dtype = float)
xt = np.vstack((xp[0:2,:],xc[0:2,:]))
#-------------------------------------------------------------
#=========================
# Initial Parameters:
#=========================
Alpha  = 0.6 # Learning Ratio
W = np.random.random((2,650))# Weights random Array 2 Rows 650 Columns
iter = 50 # Number of iterations 
#print(W,'\n')
#========================
# Training
#========================
W_Tr , t_used = Train(xp,xc,W,Alpha,iter)
#print(W_Tr)
#------------------------------------
#========================
# Testing
#========================
Result = Test(xt,W_Tr)
print(Result)
#------------------------------------

А вот функции, которые Я использую:

#==============================================================
#Import necessary Libraries
#---------------------------
import matplotlib.pyplot as plt
import numpy as np
import time
#=============================================================
def winner(dist):            # dist : 2 x 650 array
    D = np.sum(dist,axis=1)  # sum all values on time axis
    first_w  = D[0]
    second_w = D[1]
    if first_w < second_w: # if first w was closer (shorter distance)
        return 0 
    else:
        return 1 
#------------------------------------

#=============================================================
def Train(x1,x2,Wr,a,iterations):
    tic = time.time() # set a timer
    subjects_range = int(2*x1.shape[0]) # 20
    #--------------------------------------
    x1 = np.vstack((x1,x1)) # 20x650
    # Rearrange the array to make each group of 2 rows is similar
    x1 = x1[np.ix_([0,10,1,11,2,12,3,13,4,14,5,15,6,16,7,17,8,18,9,19])]
    #-------------------------------------------------------------------
    x2 = np.vstack((x2,x2)) # 20x650
    # Rearrange the array to make each group of 2 rows is similar
    x2 = x2[np.ix_([0,10,1,11,2,12,3,13,4,14,5,15,6,16,7,17,8,18,9,19])]
    #--------------------------------------
    Dist1 = Dist2 = np.zeros_like(Wr)
    for epoch in range(iterations):
        for subject in range(0,subjects_range,2):
            #-----------------( Dist : 2 x 20 )-----------------------
            # Patient subjects
            Dist1 = (Wr - x1[subject:subject+2,:])**2
            win1 = winner(Dist1)
            Wr[win1,:]+= a*(x1[subject,:]-Wr[win1,:]) # W1 = a * (X1-W1)
            #---------------------------------------------------------
            # Control subjects
            Dist2 = (Wr - x2[subject:subject+2,:])**2
            win2 = winner(Dist2)
            Wr[win2,:]+= a*(x2[subject,:]-Wr[win2,:]) # W2 = a * (X2-W2)
            #---------------------------------------------------------    
        a *= 0.5 # update Learning Ratio after each epoch
    #===============================
    toc = time.time() # reset the timer, and get time used
    t_used = toc - tic
    return Wr , t_used
#------------------------------------
#=============================================================
def Test(test,W):
    output = [] # list to store the output 
    subjects_range = int(2*test.shape[0]) # 8 
    xt = np.vstack((test,test)) # 8 x 650
    # Rearrange the array to make each group of 2 rows is similar
    xt = xt[np.ix_([0,4,1,5,2,6,3,7])]
    dist = np.zeros_like(xt) # 8 x 650
    for subject in range(0,subjects_range,2):
        # for each subject calculate distance
        dist[subject:subject+2,:] = (xt[subject:subject+2,:] - W)**2
        # for each subject get to which class it belongs
        win = winner(dist[subject:subject+2,:])
        print(subject,'win = ',win)
        output.append(win)
    return output

1 Ответ

0 голосов
/ 06 апреля 2020

Вся проблема была в весах, так как они инициализируются случайным образом, нет гарантии, что результат будет правильным, вместо W = np.random.random((2,650)) Я Инициализировал веса вручную и получил правильные результаты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...