Gradient descent training method for FCM_FTS

This commit is contained in:
Petrônio Cândido 2020-01-29 14:29:30 -03:00
parent 2abc070f1d
commit dd5ac3de20
4 changed files with 64 additions and 49 deletions

View File

@ -3,9 +3,9 @@ import numpy as np
def step(x, deriv=False): def step(x, deriv=False):
if deriv: if deriv:
1 * (x == 0) return np.abs(1 * (x == 0))
else: else:
return 1 * (x > 0) return np.abs(1 * (x > 0))
def sigmoid(x, deriv=False): def sigmoid(x, deriv=False):
@ -26,14 +26,14 @@ def softmax(x, deriv=False):
def tanh(x, deriv=False): def tanh(x, deriv=False):
if deriv: if deriv:
pass return 1 - np.tanh(x)**2
else: else:
return np.tanh(x) return np.tanh(x)
def relu(x, deriv=False): def relu(x, deriv=False):
if deriv: if deriv:
return 1. * (x > 0) return np.abs(1. * (x > 0))
else: else:
return x * (x > 0) return np.abs(x * (x > 0))

View File

@ -1,30 +1,36 @@
import numpy as np import numpy as np
def GD(data, model, alpha, momentum=0.5): def GD(data, model, **kwargs):
alpha = kwargs.get('alpha', 0.1)
momentum = kwargs.get('momentum', None)
iterations = kwargs.get('iterations', 1)
num_concepts = model.partitioner.partitions num_concepts = model.partitioner.partitions
weights=[np.random.normal(0,.01,(num_concepts,num_concepts)) for k in range(model.order)] weights = [np.random.normal(0,.01,(num_concepts,num_concepts)) for k in range(model.order)]
last_gradient = [None for k in range(model.order) ] last_gradient = [None for k in range(model.order) ]
for i in np.arange(model.order, len(data)): for it in np.arange(iterations):
sample = data[i-model.order : i] for i in np.arange(model.order, len(data)):
target = data[i] #i = np.random.randint(model.order, len(data)-model.order)
model.fcm.weights = weights sample = data[i-model.order : i]
inputs = model.partitioner.fuzzyfy(sample, mode='vector') target = data[i]
activations = [model.fcm.activation_function(inputs[k]) for k in np.arange(model.order)] model.fcm.weights = weights
forecast = model.predict(sample)[0] inputs = model.partitioner.fuzzyfy(sample, mode='vector')
error = target - forecast #)**2 activations = model.fcm.activate(inputs)
if error == np.nan: forecast = model.predict(sample)[0]
pass error = target - forecast #)**2
print(error) if str(error) == 'nan' or error == np.nan or error == np.Inf:
for k in np.arange(model.order): print('error')
deriv = error * model.fcm.activation_function(activations[k], deriv=True) print(error)
if momentum is not None: for k in np.arange(model.order):
if last_gradient[k] is None: deriv = error * model.fcm.activation_function(activations[k], deriv=True)
last_gradient[k] = deriv*inputs[k] if momentum is not None:
if last_gradient[k] is None:
last_gradient[k] = deriv*inputs[k]
tmp_grad = (momentum * last_gradient[k]) + alpha*deriv*inputs[k] tmp_grad = (momentum * last_gradient[k]) + alpha*deriv*inputs[k]
weights[k] -= tmp_grad weights[k] -= tmp_grad
else: last_gradient[k] = tmp_grad
weights[k] -= alpha*deriv*inputs[k] else:
weights[k] -= alpha*deriv*inputs[k]
return weights return weights

View File

@ -11,14 +11,15 @@ class FCM_FTS(hofts.HighOrderFTS):
self.fcm = common.FuzzyCognitiveMap(**kwargs) self.fcm = common.FuzzyCognitiveMap(**kwargs)
def train(self, data, **kwargs): def train(self, data, **kwargs):
''' method = kwargs.get('method','GA')
GA.parameters['num_concepts'] = self.partitioner.partitions if method == 'GA':
GA.parameters['order'] = self.order GA.parameters['num_concepts'] = self.partitioner.partitions
GA.parameters['partitioner'] = self.partitioner GA.parameters['order'] = self.order
ret = GA.execute(data, **kwargs) GA.parameters['partitioner'] = self.partitioner
self.fcm.weights = ret['weights'] ret = GA.execute(data, **kwargs)
''' self.fcm.weights = ret['weights']
self.fcm.weights = GD.GD(data, self, alpha=0.01) elif method == 'GD':
self.fcm.weights = GD.GD(data, self, **kwargs)
def forecast(self, ndata, **kwargs): def forecast(self, ndata, **kwargs):
ret = [] ret = []
@ -33,7 +34,10 @@ class FCM_FTS(hofts.HighOrderFTS):
activation = self.fcm.activate(fuzzyfied) activation = self.fcm.activate(fuzzyfied)
final = np.dot(midpoints, activation)/np.sum(activation) final = np.dot(midpoints, activation)/np.nanmax([1, np.sum(activation)])
if str(final) == 'nan' or final == np.nan or final == np.Inf:
print('error')
ret.append(final) ret.append(final)

View File

@ -18,27 +18,32 @@ data = df['glo_avg'].values[:]
train = data[:7000] train = data[:7000]
test = data[7000:7500] test = data[7000:7500]
fs = Grid.GridPartitioner(data=train, npart=7) fs = Grid.GridPartitioner(data=train, npart=5)
model = fcm_fts.FCM_FTS(partitioner=fs, order=2, activation_function = Activations.relu) model = fcm_fts.FCM_FTS(partitioner=fs, order=2, activation_function = Activations.relu)
model.fit(train,
ngen=30, #number of generations model.fit(train, method='GD', alpha=0.02, momentum=0.8, iteractions=3 )
mgen=7, # stop after mgen generations without improvement
npop=10, # number of individuals on population
pcruz=.5, # crossover percentual of population
pmut=.3, # mutation percentual of population
window_size = 7000,
train_rate = .8,
increment_rate =.2,
experiments=1
)
Util.persist_obj(model, 'fcm_fts10c') Util.persist_obj(model, 'fcm_fts10c')
''' '''
model = Util.load_obj('fcm_fts05c') model = Util.load_obj('fcm_fts05c')
''' '''
#forecasts = model.predict(test)
#print(model)
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=[15,5])
ax.plot(test,label='Original')
forecasts = model.predict(test) forecasts = model.predict(test)
print(model) for w in np.arange(model.order):
forecasts.insert(0,None)
ax.plot(forecasts, label=model.shortname)
plt.show()
print("")