Skip to content

Commit

Permalink
learn
Browse files Browse the repository at this point in the history
  • Loading branch information
Freakwill committed Dec 8, 2023
1 parent d78a128 commit ae82af2
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 152 deletions.
18 changes: 16 additions & 2 deletions pyrimidine/learn/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
#!/usr/bin/env python3

from .base import BaseEstimator
from sklearn.base import BaseEstimator as BE

import warnings, os
warnings.filterwarnings("ignore")
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'


class BaseEstimator(BE):

@classmethod
def config(cls, X, Y, *args, **kwargs):
raise NotImplementedError

def fit(self, X, Y, pop=None, warm_start=False):
if warm_start:
self.pop = pop or self.pop or self.config(X, Y)
else:
self.pop = pop or self.config(X, Y)
self._fit(X, Y)
71 changes: 28 additions & 43 deletions pyrimidine/learn/neural_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,81 +5,66 @@
from scipy.special import softmax
from scipy.stats import entropy

from keras.models import Sequential
from keras.layers import Dense
from sklearn.metrics import r2_score
from sklearn.neural_network import MLPRegressor

from pyrimidine import MixedIndividual, FloatChromosome, FloatMatrixChromosome
from pyrimidine.population import HOFPopulation
from pyrimidine.learn.base import BaseEstimator
from .. import MixedIndividual, FloatChromosome, FloatMatrixChromosome
from ..population import HOFPopulation
from ..learn import BaseEstimator


class GAANN(BaseEstimator, Sequential):
class GAANN(BaseEstimator, MLPRegressor):
"""GA for ANN
"""

pop = None

hidden_dim = 4
max_iter = 100
n_layers = 3

@classmethod
def create_model(cls, input_dim, output_dim):
# create Sequential object
hidden_dim = 4
model = Sequential()
model.add(Dense(hidden_dim, activation='relu', input_dim=input_dim))
model.add(Dense(output_dim))
def create_model(cls, *args, **kwargs):
# create MLPRegressor object
model = MLPRegressor(hidden_layer_sizes=(cls.hidden_dim,), max_iter=1, *args, **kwargs)
model.out_activation_ = 'identity'
model.n_layers_ = cls.n_layers
return model

@classmethod
def create(cls, input_dim, output_dim):
def __init__(self, *args, **kwargs):
# create GAANN object
hidden_dim = 4
model = cls()
model.add(Dense(hidden_dim, activation='relu', input_dim=input_dim))
model.add(Dense(output_dim))
return model
super().__init__(hidden_layer_sizes=(self.hidden_dim,), max_iter=1, *args, **kwargs)
self.out_activation_ = 'identity'
self.n_layers_ = 3

@classmethod
def from_data(cls, X, Y):
input_dim = X.shape[1]
output_dim = Y.shape[1]
return cls.create(input_dim, output_dim)
def config(cls, X, Y, n_individuals=10, *args, **kwargs):
# configure the population for GA

@classmethod
def config(cls, X, Y, n_individuals=10):
hidden_dim = 4
input_dim = X.shape[1]
output_dim = Y.shape[1]

class MyIndividual(MixedIndividual):

element_class = FloatMatrixChromosome, FloatChromosome, FloatChromosome, FloatChromosome
element_class = FloatMatrixChromosome, FloatChromosome, FloatMatrixChromosome, FloatChromosome

def _fitness(self):
model = self.decode()
return r2_score(Y, model.predict(X))
return model.score(X, Y)

def decode(self):
model = cls.create_model(input_dim, output_dim)
for k, layer in enumerate(model.layers):
weights = (self.chromosomes[2*k], self.chromosomes[2*k+1])
layer.set_weights(weights)
model = cls.create_model(*args, **kwargs)
model.coefs_ = tuple(map(np.asarray, self[::2]))
model.intercepts_ = tuple(map(np.asarray, self[1::2]))
model.n_layers_ = 3
return model

MyPopulation = HOFPopulation[MyIndividual]

return MyPopulation.random(n_individuals=n_individuals, size=((input_dim, hidden_dim), hidden_dim, (hidden_dim, output_dim), output_dim))

def predict(self, X):
return super().predict(X, verbose=0)
return MyPopulation.random(n_individuals=n_individuals, size=((input_dim, cls.hidden_dim), cls.hidden_dim, (cls.hidden_dim, output_dim), output_dim))

def fit(self, X, Y, pop=None):
self.pop = pop or self.pop or self.config(X, Y)
def _fit(self, X, Y):
self.pop.ezolve(n_iter=self.max_iter)
model_ = self.pop.solution
self.set_weights(model_.get_weights())

def score(self, X, Y):
return r2_score(Y, self.predict(X))
self.coefs_ = model_.coefs_
self.intercepts_ = model_.intercepts_

106 changes: 0 additions & 106 deletions pyrimidine/learn/regression.py

This file was deleted.

17 changes: 16 additions & 1 deletion tests/test_learn.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,31 @@
import numpy as np

from pyrimidine.learn.neural_network import GAANN
from pyrimidine.learn.regression import GALinearRegression


def test_ann():
X = np.array([[0,0], [0,1], [1,0], [1,1]])
Y = np.array([[0,1], [1,0], [1,0], [0,1]])

model = GAANN.from_data(X, Y)
model = GAANN()
pop = GAANN.config(X, Y)
s0 = pop.fitness
model.max_iter = 2
model.fit(X, Y, pop)
s1 = model.score(X, Y)
assert s0 <= s1

def test_lr():
X = np.array([[0,0], [0,1], [1,0], [1,1]])
Y = np.array([2,1,0,0])

model = GALinearRegression()
pop = GALinearRegression.config(X, Y)
for i in pop:
i._fitness()
s0 = pop.fitness
model.max_iter = 2
model.fit(X, Y, pop)
s1 = model.score(X, Y)
assert s0 <= s1

0 comments on commit ae82af2

Please sign in to comment.