Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Golem update #11

Merged
merged 77 commits into from
Jan 30, 2023
Merged
Show file tree
Hide file tree
Changes from 74 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
a688123
Requirements fix
staeros Sep 6, 2022
4c0c168
Graph requirements were extended for convolutional nodes; Added stric…
staeros Sep 9, 2022
d35a340
Fixes for simple mutation bug
staeros Sep 13, 2022
986d869
Fixes for simple mutation bug
staeros Sep 13, 2022
48a6fbc
Added layers repository
staeros Sep 15, 2022
83ca2ea
Pre-refactoring changes. Updating class for graph generation and solv…
staeros Sep 16, 2022
275737b
Possible pool of conv layer types was extended; validation rules upda…
staeros Sep 20, 2022
440241d
Added trainable restrictions.
staeros Sep 23, 2022
32c5547
Fix for trainable restrictions.
staeros Sep 23, 2022
4437dc4
Fix for trainable restrictions.
staeros Sep 24, 2022
fcd69d5
requirements update; serializer error fix
staeros Sep 27, 2022
ff3cc54
val rule update for trainable parameters
staeros Sep 27, 2022
0ccb01c
ResNet builder implementation for initial assumption
staeros Oct 18, 2022
eaf3c8d
ResNet builder updates
staeros Oct 18, 2022
954fc6c
Skip connections fix, minor Resnet builder fixes
staeros Oct 19, 2022
377e470
Memory leak fixing
staeros Nov 7, 2022
aeaae06
Added graph branch manager and class for convert node to layer
staeros Nov 11, 2022
6057be8
Added graph branch manager and class for convert node to layer
staeros Nov 11, 2022
3f0a84c
Refactoring + Updates for model generation
staeros Nov 18, 2022
af5c389
Refactoring; Subcalssing from Keras model was replaced with ModelConv…
staeros Nov 21, 2022
26d1464
Added temporary val rules for resnet-like networks + small fixes
staeros Nov 24, 2022
7995c80
save path fix
staeros Nov 24, 2022
cee84f8
minor changes
staeros Nov 24, 2022
1d2ebdf
minor changes
staeros Nov 24, 2022
f85bf9a
Keras optimizer changed
staeros Nov 25, 2022
a9a2e0b
Minor changes
staeros Nov 25, 2022
b3fa161
Minor changes
staeros Nov 25, 2022
9d1c341
Added callback for model performance
staeros Nov 25, 2022
718650d
setup update
staeros Nov 25, 2022
f8b249f
callbacks update
staeros Nov 26, 2022
6d65a3d
callbacks update
staeros Nov 26, 2022
346f18a
Hotfixes for val rules
staeros Nov 27, 2022
77e097d
Hotfixes for val rules: added ty except in dimension check rule
staeros Nov 27, 2022
e5afdaa
Builder fixes
staeros Dec 6, 2022
f2d7ad4
Builder fixes
staeros Dec 6, 2022
7fd6b7b
requirements update
staeros Dec 6, 2022
cc5741e
requirements update
staeros Dec 6, 2022
5cec285
Branch Manager fix
staeros Dec 6, 2022
ea71ecd
Minor fixes
staeros Dec 6, 2022
2d42b24
Minor hotfixes
staeros Dec 22, 2022
d810a14
Minor hotfixes
staeros Dec 27, 2022
af11d46
Added unfit method
staeros Dec 27, 2022
0a03bd9
Added performance callback
staeros Dec 27, 2022
aaa2e0b
memory hotfix
staeros Dec 28, 2022
80dc74e
history functional object remove
staeros Dec 29, 2022
34d31a8
golem update
staeros Jan 14, 2023
470b32a
requirements update
staeros Jan 17, 2023
c948a44
golem imports update; requirements refactoring
staeros Jan 17, 2023
078404a
Requirements update
staeros Jan 17, 2023
6163ca2
Requirements update; Added unit tests for base layer requirements
staeros Jan 18, 2023
38b826c
Default requirements hotfix
staeros Jan 18, 2023
6346a82
Added unit tests for requirements
staeros Jan 18, 2023
34a06ae
Redundant code was removed
staeros Jan 18, 2023
23ec730
Minor composer changes; Composer refactoring
staeros Jan 18, 2023
b9ca5a2
Added class BaseNasDatasetBuilder for InputData preparation for model…
staeros Jan 19, 2023
49e28bc
BaseNasDatasetBuilder preprocessor fix
staeros Jan 19, 2023
0cfaf70
BaseNasDatasetBuilder preprocessor fix; cases update
staeros Jan 19, 2023
01194a5
Refactoring
staeros Jan 19, 2023
d517b0b
Refactoring
staeros Jan 19, 2023
205f007
Refactoring; Added unit test for DatasetBuilder
staeros Jan 19, 2023
598dc30
Dataset builder preprocessor fixes; Added unit tests for dataset builder
staeros Jan 20, 2023
caee2f7
NasGraph refactoring; Added option to specify train parameters more f…
staeros Jan 20, 2023
2229ec1
WIP Model builder and LayerInitializer
staeros Jan 23, 2023
7d649db
Code refactoring
staeros Jan 25, 2023
95e3863
Requirements update
staeros Jan 25, 2023
ca19668
Unit tests update
staeros Jan 26, 2023
d075c4b
Unit tests update
staeros Jan 26, 2023
77b3fbd
Code update
staeros Jan 26, 2023
952d33a
nngraph verifier & verifier for all rules (#10)
maypink Sep 29, 2022
669040a
Golem transition
staeros Sep 9, 2022
b2df3bb
Merge remote-tracking branch 'origin/golem-update' into golem-update
staeros Jan 26, 2023
85500a6
Requirements fix
staeros Jan 26, 2023
542839f
Redundant code removed
staeros Jan 26, 2023
986c38a
Code refactoring
staeros Jan 27, 2023
bcb91f7
Added dockstrings; Refactoring
staeros Jan 30, 2023
8a690a7
Requirements update
staeros Jan 30, 2023
a6690e5
Minor changes
staeros Jan 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM tensorflow/tensorflow:1.15.5
RUN pip install keras==2.3.1 scikit_learn==0.22.1 dataclasses networkx==2.2 pandas==0.25.3 xgboost==1.0.1 anytree==2.8.0
RUN pip install h2o==3.28.1.2 tpot==0.11.1 statsmodels==0.11.1 matplotlib==3.0.3 Pillow==7.0.0 imageio==2.8.0
RUN apt-get update ##[edited]
RUN apt-get _update ##[edited]
RUN apt-get install ffmpeg libsm6 libxext6 -y
RUN pip install opencv-python

2 changes: 1 addition & 1 deletion Dockerfile_gpu
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ COPY ./nas /home/nas

RUN pip install keras==2.3.1 scikit_learn==0.22.1 dataclasses networkx==2.2 pandas==0.25.3 xgboost==1.0.1 anytree==2.8.0
RUN pip install h2o==3.28.1.2 tpot==0.11.1 statsmodels==0.11.1 matplotlib Pillow==7.0.0 imageio==2.8.0
RUN apt-get update ##[edited]
RUN apt-get _update ##[edited]
RUN apt-get install ffmpeg libsm6 libxext6 -y
RUN pip install opencv-python

180 changes: 101 additions & 79 deletions cases/butterfly_classification.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,47 @@
import datetime
import os
import pathlib

from golem.core.optimisers.genetic.gp_params import GPAlgorithmParameters

import nas.data.nas_data

os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"

import tensorflow as tf
from fedot.core.composer.advisor import DefaultChangeAdvisor

from golem.core.adapter.adapter import DirectAdapter
from golem.core.optimisers.advisor import DefaultChangeAdvisor
from fedot.core.composer.composer_builder import ComposerBuilder
from fedot.core.dag.verification_rules import has_no_cycle, has_no_self_cycled_nodes
from golem.core.dag.verification_rules import has_no_cycle, has_no_self_cycled_nodes
from fedot.core.data.data_split import train_test_data_setup
from fedot.core.optimisers.adapters import DirectAdapter
from fedot.core.optimisers.gp_comp.gp_optimizer import GPGraphOptimizerParameters, GeneticSchemeTypesEnum
from fedot.core.optimisers.gp_comp.operators.crossover import CrossoverTypesEnum
from fedot.core.optimisers.gp_comp.operators.mutation import MutationTypesEnum
from fedot.core.optimisers.gp_comp.operators.regularization import RegularizationTypesEnum
from fedot.core.optimisers.optimizer import GraphGenerationParams

from golem.core.optimisers.genetic.operators.crossover import CrossoverTypesEnum
from golem.core.optimisers.genetic.operators.inheritance import GeneticSchemeTypesEnum
from golem.core.optimisers.genetic.operators.mutation import MutationTypesEnum
from golem.core.optimisers.genetic.operators.regularization import RegularizationTypesEnum
from golem.core.optimisers.optimizer import GraphGenerationParams
from fedot.core.repository.quality_metrics_repository import ClassificationMetricsEnum, MetricsRepository
from fedot.core.repository.tasks import TaskTypesEnum, Task

import nas.composer.nn_composer_requirements as nas_requirements
import nas.data.load_images as loader
from nas.composer.nn_composer import NNComposer
from nas.data.data_generator import DataGenerator
from nas.data.data_generator import Preprocessor
from nas.data.setup_data import setup_data
from nas.graph.cnn.cnn_builder import CNNBuilder
from nas.graph.cnn.cnn_graph import NNGraph, NNNode
from nas.graph.nn_graph_builder import NNGraphBuilder
from nas.graph.node_factory import NNNodeFactory
from nas.composer.nn_composer import NasComposer
from nas.data import KerasDataset
from nas.data.dataset.builder import BaseNasDatasetBuilder
from nas.data.preprocessor import Preprocessor
from nas.graph.cnn_graph import NasNode
from nas.graph.graph_builder.resnet_builder import ResNetGenerator
from nas.graph.graph_builder import NNGraphBuilder
from nas.graph.node.node_factory import NNNodeFactory
from nas.operations.evaluation.metrics.metrics import calculate_validation_metric, get_predictions
from nas.operations.validation_rules.cnn_val_rules import has_no_flatten_skip, flatten_count, \
graph_has_several_starts, graph_has_wrong_structure, unique_node_types
from nas.operations.validation_rules.cnn_val_rules import *
from nas.optimizer.objective.nas_cnn_optimiser import NNGraphOptimiser
from nas.repository.layer_types_enum import LayersPoolEnum
from nas.utils.utils import set_root, project_root

gpus = tf.config.list_physical_devices('GPU')
print(gpus)

set_root(project_root())


Expand All @@ -39,83 +50,95 @@ def build_butterfly_cls(save_path=None):
task = Task(TaskTypesEnum.classification)
objective_function = MetricsRepository().metric_by_id(ClassificationMetricsEnum.logloss)
dataset_path = pathlib.Path('../datasets/butterfly_cls/train')
data = loader.NNData.data_from_folder(dataset_path, task)
data = nas.data.nas_data.BaseNasImageData.data_from_folder(dataset_path, task)

cv_folds = 3
image_side_size = 20
batch_size = 8
epochs = 1
cv_folds = None
image_side_size = 64
batch_size = 64
epochs = 2
optimization_epochs = 1

train_data, test_data = train_test_data_setup(data, shuffle_flag=True)

data_requirements = nas_requirements.DataRequirements(split_params={'cv_folds': cv_folds})
conv_requirements = nas_requirements.ConvRequirements(input_shape=[image_side_size, image_side_size],
color_mode='RGB',
min_filters=32, max_filters=128,
kernel_size=[3, 3], conv_strides=[1, 1],
pool_size=[2, 2], pool_strides=[2, 2],
pool_types=['max_pool2d', 'average_pool2d'])
fc_requirements = nas_requirements.FullyConnectedRequirements(min_number_of_neurons=32,
max_number_of_neurons=128)
nn_requirements = nas_requirements.NNRequirements(conv_requirements=conv_requirements,
fc_requirements=fc_requirements,
primary=['conv2d'], secondary=['dense'],
epochs=epochs, batch_size=batch_size,
max_nn_depth=3, max_num_of_conv_layers=10,
has_skip_connection=True
)
optimizer_requirements = nas_requirements.OptimizerRequirements(opt_epochs=optimization_epochs)

requirements = nas_requirements.NNComposerRequirements(data_requirements=data_requirements,
optimizer_requirements=optimizer_requirements,
nn_requirements=nn_requirements,
timeout=datetime.timedelta(hours=200),
pop_size=1,
num_of_generations=1)
conv_layers_pool = [LayersPoolEnum.conv2d_1x1, LayersPoolEnum.conv2d_3x3, LayersPoolEnum.conv2d_5x5,
LayersPoolEnum.conv2d_7x7]

mutations = [MutationTypesEnum.single_add, MutationTypesEnum.single_drop, MutationTypesEnum.single_edge,
MutationTypesEnum.single_change, MutationTypesEnum.simple]
MutationTypesEnum.single_change]

validation_rules = [has_no_flatten_skip, flatten_count, graph_has_several_starts, graph_has_wrong_structure,
has_no_cycle, has_no_self_cycled_nodes, unique_node_types]
train_data, test_data = train_test_data_setup(data, shuffle_flag=True)

optimizer_parameters = GPGraphOptimizerParameters(genetic_scheme_type=GeneticSchemeTypesEnum.steady_state,
mutation_types=mutations,
crossover_types=[CrossoverTypesEnum.subtree],
regularization_type=RegularizationTypesEnum.none)
fc_requirements = nas_requirements.BaseLayerRequirements(min_number_of_neurons=32,
max_number_of_neurons=128)
conv_requirements = nas_requirements.ConvRequirements(
min_number_of_neurons=32, max_number_of_neurons=256,
conv_strides=[[1, 1]],
pool_size=[[2, 2]], pool_strides=[[2, 2]])
model_requirements = nas_requirements.ModelRequirements(input_data_shape=[image_side_size, image_side_size],
color_mode='color',
num_of_classes=data.num_classes,
conv_requirements=conv_requirements,
fc_requirements=fc_requirements,
primary=conv_layers_pool,
secondary=[LayersPoolEnum.dense],
epochs=epochs, batch_size=batch_size,
max_nn_depth=1, max_num_of_conv_layers=36)

requirements = nas_requirements.NNComposerRequirements(opt_epochs=optimization_epochs,
model_requirements=model_requirements,
timeout=datetime.timedelta(minutes=5),
num_of_generations=3,
early_stopping_iterations=100,
early_stopping_timeout=float(datetime.timedelta(minutes=30).
total_seconds()),
n_jobs=1,
cv_folds=cv_folds)

validation_rules = [ConvNetChecker.check_cnn, has_no_cycle, has_no_self_cycled_nodes, ]

optimizer_parameters = GPAlgorithmParameters(genetic_scheme_type=GeneticSchemeTypesEnum.steady_state,
mutation_types=mutations,
crossover_types=[CrossoverTypesEnum.subtree],
pop_size=10,
regularization_type=RegularizationTypesEnum.none)

graph_generation_parameters = GraphGenerationParams(
adapter=DirectAdapter(base_graph_class=NNGraph, base_node_class=NNNode),
rules_for_constraint=validation_rules, node_factory=NNNodeFactory(requirements, DefaultChangeAdvisor()))
adapter=DirectAdapter(base_graph_class=NasGraph, base_node_class=NasNode),
rules_for_constraint=validation_rules, node_factory=NNNodeFactory(requirements.model_requirements,
DefaultChangeAdvisor()))

graph_generation_function = NNGraphBuilder()
graph_generation_function.set_builder(CNNBuilder(requirements=requirements))
graph_generation_function.set_builder(ResNetGenerator(model_requirements=requirements.model_requirements))

builder = ComposerBuilder(task).with_composer(NNComposer).with_optimiser(NNGraphOptimiser). \
with_requirements(requirements).with_metrics(objective_function).with_optimiser_params(optimizer_parameters). \
with_initial_pipelines_generation_function(graph_generation_function.create_nas_graph). \
with_graph_generation_param(graph_generation_parameters).with_history('../_results/debug/master')
composer = builder.build()
builder = ComposerBuilder(task).with_composer(NasComposer).with_optimizer(NNGraphOptimiser). \
with_requirements(requirements).with_metrics(objective_function).with_optimizer_params(optimizer_parameters). \
with_initial_pipelines(graph_generation_function.build()). \
with_graph_generation_param(graph_generation_parameters)

transformations = [tf.convert_to_tensor]
data_preprocessor = Preprocessor()
data_preprocessor.set_image_size((image_side_size, image_side_size)).set_features_transformations(transformations)
composer.set_preprocessor(data_preprocessor)
data_preprocessor = Preprocessor((image_side_size, image_side_size))

data_transformer = BaseNasDatasetBuilder(dataset_cls=KerasDataset,
batch_size=requirements.model_requirements.batch_size,
shuffle=True).set_data_preprocessor(data_preprocessor)

composer = builder.build()
composer.set_data_transformer(data_transformer)

optimized_network = composer.compose_pipeline(train_data)

train_data, val_data = train_test_data_setup(train_data, shuffle_flag=True)

train_generator = setup_data(train_data, requirements.nn_requirements.batch_size, data_preprocessor, 'train',
DataGenerator, True)
val_generator = setup_data(val_data, requirements.nn_requirements.batch_size, data_preprocessor, 'train',
DataGenerator, True)
train_generator = data_transformer.build(train_data, mode='train')
val_generator = data_transformer.build(val_data, mode='val')

optimized_network.fit(train_generator, val_generator, requirements=requirements, num_classes=train_data.num_classes,
verbose=1, optimization=False, shuffle=True)
optimized_network.compile_model(model_requirements.input_shape, 'categorical_crossentropy',
metrics=[tf.metrics.Accuracy()], optimizer=tf.keras.optimizers.Adam,
n_classes=model_requirements.num_of_classes)
optimized_network.fit(train_generator, val_generator, model_requirements.epochs, model_requirements.batch_size,
[tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=3, verbose=1,
mode='min'),
tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=.1, patience=3,
verbose=1,
min_delta=1e-4, mode='min')])

predicted_labels, predicted_probabilities = get_predictions(optimized_network, test_data, data_preprocessor)
predicted_labels, predicted_probabilities = get_predictions(optimized_network, test_data, data_transformer)
roc_on_valid_evo_composed, log_loss_on_valid_evo_composed, accuracy_score_on_valid_evo_composed = \
calculate_validation_metric(test_data, predicted_probabilities, predicted_labels)

Expand All @@ -128,6 +151,5 @@ def build_butterfly_cls(save_path=None):


if __name__ == '__main__':
path = f'_results/debug/master/{datetime.datetime.now().date()}'
print(tf.config.list_physical_devices('GPU'))
path = f'_results/debug/master_2/{datetime.datetime.now().date()}'
build_butterfly_cls(path)
84 changes: 84 additions & 0 deletions cases/load_from_fitted_case.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import datetime
import os
import pathlib

import tensorflow as tf
from fedot.core.composer.advisor import DefaultChangeAdvisor
from golem.core.optimisers.adapters import DirectAdapter
from golem.core.optimisers.genetic.individual import Individual
from golem.core.optimisers.genetic.operators.mutation import MutationTypesEnum, Mutation
from golem.core.optimisers.opt_history import OptHistory
from golem.core.optimisers.optimizer import GraphGenerationParams

import nas.composer.nn_composer_requirements as nas_requirements
from nas.graph.cnn_graph import NasGraph
from nas.graph.node.nas_graph_node import NasNode
from nas.graph.node.node_factory import NNNodeFactory
from nas.utils.utils import project_root, set_root

set_root(project_root())


def from_fitted():
# path_to_model = pathlib.Path('../_results/debug/master/2022-09-05/fitted_model.h5')
# # model = tf.keras.models.load_model(path_to_model)
# model = tf.keras.applications.resnet.ResNet152()
graph_path = os.path.join('/home/staeros/_results/resnet_comp/2/2022-10-04/graph.json')
model_path = os.path.join('/home/staeros/_results/resnet_comp/2/2022-10-04/fitted_model.h5')
model = tf.keras.models.load_model(model_path)
graph = NasGraph.load(str(graph_path))
graph.model = model
history = OptHistory.load('/home/staeros/_results/resnet_comp/2/2022-10-04/history.json')
history.show(per_time=False)
# history = OptHistory.load('/home/staeros/_results/debug/master_2/2022-09-07/history.json')
# history.show.fitness_line_interactive(per_time=False)

cv_folds = 3
image_side_size = 20
batch_size = 8
epochs = 1
optimization_epochs = 1

data_requirements = nas_requirements.DataRequirements(split_params={'cv_folds': cv_folds})
conv_requirements = nas_requirements.ConvRequirements(input_shape=[image_side_size, image_side_size],
color_mode='RGB',
min_number_of_neurons=32, max_number_of_neurons=64,
conv_strides=[[1, 1]],
pool_size=[[2, 2]], pool_strides=[[2, 2]],
pool_types=['max_pool2d', 'average_pool2d'])
fc_requirements = nas_requirements.BaseLayerRequirements(min_number_of_neurons=32,
max_number_of_neurons=64)
nn_requirements = nas_requirements.ModelRequirements(conv_requirements=conv_requirements,
fc_requirements=fc_requirements,
primary=['conv2d'], secondary=['dense'],
epochs=epochs, batch_size=batch_size,
max_nn_depth=2, max_num_of_conv_layers=5,
has_skip_connection=True
)
optimizer_requirements = nas_requirements.OptimizerRequirements(opt_epochs=optimization_epochs)

requirements = nas_requirements.NNComposerRequirements(data_requirements=data_requirements,
optimizer_requirements=optimizer_requirements,
model_requirements=nn_requirements,
timeout=datetime.timedelta(hours=200),
pop_size=10,
num_of_generations=10)

graph_generation_parameters = GraphGenerationParams(
adapter=DirectAdapter(base_graph_class=NasGraph, base_node_class=NasNode),
rules_for_constraint=[], node_factory=NNNodeFactory(requirements, DefaultChangeAdvisor()))

path = pathlib.Path('/home/staeros/_results/broken_mutation/graph.json')
graph = Individual(NasGraph.load(path))

mutation = MutationTypesEnum.simple

mutator = Mutation([mutation], requirements, graph_generation_parameters)

mutator(graph)

print('Done!')


if __name__ == '__main__':
from_fitted()
5 changes: 3 additions & 2 deletions nas/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .data import data_generator, load_images
from .graph import nn_graph_builder, node_factory
from .data import preprocessor, loader
from .graph import graph_builder
from .graph.node import node_factory
File renamed without changes.
6 changes: 6 additions & 0 deletions nas/caching/graph_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from fedot.core.caching.base_cache import BaseCache


class GraphCache(BaseCache):
def __init__(self):
pass
Loading