Commit 207a379b authored by Evgeny Kusmenko's avatar Evgeny Kusmenko
Browse files

Merge branch 'ba_kisov' into 'master'

Ba_kisov

See merge request !38
parents 65941028 e939ea35
Pipeline #465937 passed with stages
in 42 seconds
......@@ -11,4 +11,46 @@ In order to visualize attention from an attention network, the data from this la
attention ->
...
`, the data in this layer will be saved until the end of the network iteration.
2. In order to make the network return the saved data, the networks name must be added to the 'AllAttentionModels' class in this project. Furthermore, the layer must either be named `attention`, or the CNNNet.ftl template has to be adjusted to return differently named layers.
\ No newline at end of file
2. In order to make the network return the saved data, the networks name must be added to the 'AllAttentionModels' class in this project. Furthermore, the layer must either be named `attention`, or the CNNNet.ftl template has to be adjusted to return differently named layers.
## Using Custom Layers
* Create a directory with following structure somewhere in your system :
<pre>
+-- custom_files
+-- python
+-- gluon
+-- custom_layers
</pre>
* Add __init__.py file to the custom_layers folder and include a method in it to enable the usage of "from custom_layers import * " statement
* Place your custom layer python file inside the custom_layers folder (for the appropriate backend) and include the three functions in its class as shown in the example below
```
# A method to return a dictionary with
# the names of the parameters of the layer (string) as keys and their data type (data type object) as value
def get_parameters(self):
return {'alpha': int, 'ones': int}
# A method to print a dictionary with
# the names of the parameters of the layer (string) as keys and their data type (string) as value
def print_parameters(self):
print({'alpha': 'int', 'ones': 'int'})
# A method which gets the output dimensions of the previous layer as array of 3-element tuples and computes
# the output dimensions of this layer and print a 5-element tuple with the output dimensions and
# min max value in the form (channel1, height1, width1, min1, max1), (channels2, ...)
# input_dimension_array = [(channels1, height1, width1), (channels2, height2, width2), ...]
def compute_output_types(self, alpha, ones, input_dimension_array):
channels1 = input_dimension_array[0][0]
height1 = input_dimension_array[0][1]
width1 = input_dimension_array[0][2]
min1 = 0
max1 = 'oo'
print([(channels1, height1, width1, min1, max1)])
```
* Use the custom layer inside the model with the same name as the file and the class inside is called
* When you use the script or directly use the EMADL2CPP generator to start generating code and training your model add the "-cfp" command line argument followed by the path to the custom_files folder
......@@ -30,6 +30,12 @@ public class CNNArch2GluonTemplateController extends CNNArchTemplateController {
ftlContext.put(TEMPLATE_CONTROLLER_KEY, this);
ftlContext.put(ELEMENT_DATA_KEY, getCurrentElement());
ftlContext.put(NET_DEFINITION_MODE_KEY, netDefinitionMode.toString());
if (this.getDataElement().getElement() instanceof LayerSymbol){
if(((LayerSymbol) (this.getDataElement().getElement())).getDeclaration() instanceof CustomLayerDeclaration){
templatePath = relativePath + "CustomLayer" + FTL_FILE_ENDING;
}
}
getTemplateConfiguration().processTemplate(ftlContext, templatePath, writer);
}
......
......@@ -7,7 +7,8 @@ package de.monticore.lang.monticar.cnnarch.gluongenerator;
public enum NetDefinitionMode {
ARCHITECTURE_DEFINITION,
PREDICTION_PARAMETER,
FORWARD_FUNCTION;
FORWARD_FUNCTION,
PARAMETER_VALIDATION;
public static NetDefinitionMode fromString(final String netDefinitionMode) {
switch(netDefinitionMode) {
......@@ -17,6 +18,8 @@ public enum NetDefinitionMode {
return FORWARD_FUNCTION;
case "PREDICTION_PARAMETER":
return PREDICTION_PARAMETER;
case "PARAMETER_VALIDATION":
return PARAMETER_VALIDATION;
default:
throw new IllegalArgumentException("Unknown Net Definition Mode");
}
......
......@@ -5,6 +5,12 @@ import os
import shutil
import warnings
import inspect
import sys
<#if tc.architecture.customPyFilesPath??>
sys.path.insert(1, '${tc.architecture.customPyFilesPath}')
from custom_layers import *
</#if>
<#list tc.architecture.networkInstructions as networkInstruction>
from CNNNet_${tc.fullArchitectureName} import Net_${networkInstruction?index}
......@@ -210,3 +216,8 @@ class ${tc.fileNameWithoutEnding}:
</#list>
</#list>
return outputs
def validate_parameters(self):
<#list tc.architecture.networkInstructions as networkInstruction>
${tc.include(networkInstruction.body, "PARAMETER_VALIDATION")}
</#list> pass
\ No newline at end of file
......@@ -5,8 +5,14 @@ import math
import os
import abc
import warnings
import sys
from mxnet import gluon, nd
<#if tc.architecture.customPyFilesPath??>
sys.path.insert(1, '${tc.architecture.customPyFilesPath}')
from custom_layers import *
</#if>
class ZScoreNormalization(gluon.HybridBlock):
def __init__(self, data_mean, data_std, **kwargs):
......@@ -557,6 +563,8 @@ ${tc.include(networkInstruction.body, elements?index, "FORWARD_FUNCTION")}
</#list>
class Net_${networkInstruction?index}(gluon.HybridBlock):
def __init__(self, data_mean=None, data_std=None, mx_context=None, **kwargs):
super(Net_${networkInstruction?index}, self).__init__(**kwargs)
......@@ -579,6 +587,7 @@ ${tc.include(networkInstruction.body, "ARCHITECTURE_DEFINITION")}
</#if>
pass
def hybrid_forward(self, F, ${tc.join(tc.getStreamInputNames(networkInstruction.body, false), ", ")}):
<#if networkInstruction.body.episodicSubNetworks?has_content>
<#list networkInstruction.body.episodicSubNetworks as elements>
......
<#-- (c) https://github.com/MontiCore/monticore -->
import logging
import mxnet as mx
<#list configurations as config>
import CNNCreator_${config.instanceName}
import CNNDataLoader_${config.instanceName}
......@@ -15,6 +16,7 @@ if __name__ == "__main__":
<#list configurations as config>
${config.instanceName}_creator = CNNCreator_${config.instanceName}.CNNCreator_${config.instanceName}()
${config.instanceName}_creator.validate_parameters()
${config.instanceName}_loader = CNNDataLoader_${config.instanceName}.CNNDataLoader_${config.instanceName}()
${config.instanceName}_trainer = CNNSupervisedTrainer_${config.instanceName}.CNNSupervisedTrainer_${config.instanceName}(
${config.instanceName}_loader,
......
<#-- (c) https://github.com/MontiCore/monticore -->
<#assign input = element.inputs[0]>
<#if mode == "ARCHITECTURE_DEFINITION">
self.${element.name} = ${element.element.name}.${element.element.name}(<#rt>
<#list element.element.arguments as argument>
${argument.name}=${argument.rhs.value.get()}<#sep>, </#sep><#t>
</#list>)<#lt>
<#include "OutputShape.ftl">
<#elseif mode == "FORWARD_FUNCTION">
${element.name} = self.${element.name}(${input})
<#elseif mode == "PARAMETER_VALIDATION">
<#if element.element.arguments?has_content>
${element.name}temp = ${element.element.name}.${element.element.name}()
parameters_with_type = ${element.name}temp.get_parameters()
<#list element.element.arguments as argument>
if '${argument.name}' in parameters_with_type:
if isinstance(${argument.rhs.value.get()},parameters_with_type['${argument.name}']) == False:
raise TypeError('Wrong ' + str(type(${argument.rhs.value.get()})) + ' of parameter \'${argument.name}\' given in the model')
else:
raise AttributeError('Parameter of Layer not added to get_parameters function')
</#list>
</#if>
</#if>
\ No newline at end of file
......@@ -4,6 +4,7 @@ import os
import shutil
import warnings
import inspect
import sys
from CNNNet_Alexnet import Net_0
......@@ -186,3 +187,7 @@ class CNNCreator_Alexnet:
output_domains = (float,0.0,1.0,)
outputs["predictions_"] = output_domains + (output_dimensions,)
return outputs
def validate_parameters(self):
pass
......@@ -4,6 +4,7 @@ import os
import shutil
import warnings
import inspect
import sys
from CNNNet_CifarClassifierNetwork import Net_0
......@@ -186,3 +187,7 @@ class CNNCreator_CifarClassifierNetwork:
output_domains = (float,0.0,1.0,)
outputs["softmax_"] = output_domains + (output_dimensions,)
return outputs
def validate_parameters(self):
pass
......@@ -4,6 +4,7 @@ import os
import shutil
import warnings
import inspect
import sys
from CNNNet_EpisodicMemoryNetwork import Net_0
......@@ -187,3 +188,7 @@ class CNNCreator_EpisodicMemoryNetwork:
output_domains = (float,0.0,1.0,)
outputs["softmax_"] = output_domains + (output_dimensions,)
return outputs
def validate_parameters(self):
pass
......@@ -4,6 +4,7 @@ import os
import shutil
import warnings
import inspect
import sys
from CNNNet_LoadNetworkTest import Net_0
......@@ -186,3 +187,7 @@ class CNNCreator_LoadNetworkTest:
output_domains = (float,0.0,1.0,)
outputs["softmax_"] = output_domains + (output_dimensions,)
return outputs
def validate_parameters(self):
pass
......@@ -4,6 +4,7 @@ import os
import shutil
import warnings
import inspect
import sys
from CNNNet_VGG16 import Net_0
......@@ -186,3 +187,7 @@ class CNNCreator_VGG16:
output_domains = (float,0.0,1.0,)
outputs["predictions_"] = output_domains + (output_dimensions,)
return outputs
def validate_parameters(self):
pass
......@@ -4,6 +4,7 @@ import math
import os
import abc
import warnings
import sys
from mxnet import gluon, nd
......
......@@ -4,6 +4,7 @@ import math
import os
import abc
import warnings
import sys
from mxnet import gluon, nd
......
......@@ -4,6 +4,7 @@ import math
import os
import abc
import warnings
import sys
from mxnet import gluon, nd
......
......@@ -4,6 +4,7 @@ import math
import os
import abc
import warnings
import sys
from mxnet import gluon, nd
......
......@@ -4,6 +4,7 @@ import math
import os
import abc
import warnings
import sys
from mxnet import gluon, nd
......
......@@ -11,6 +11,7 @@ if __name__ == "__main__":
logger.addHandler(handler)
emptyConfig_creator = CNNCreator_emptyConfig.CNNCreator_emptyConfig()
emptyConfig_creator.validate_parameters()
emptyConfig_loader = CNNDataLoader_emptyConfig.CNNDataLoader_emptyConfig()
emptyConfig_trainer = CNNSupervisedTrainer_emptyConfig.CNNSupervisedTrainer_emptyConfig(
emptyConfig_loader,
......
......@@ -11,6 +11,7 @@ if __name__ == "__main__":
logger.addHandler(handler)
fullConfig_creator = CNNCreator_fullConfig.CNNCreator_fullConfig()
fullConfig_creator.validate_parameters()
fullConfig_loader = CNNDataLoader_fullConfig.CNNDataLoader_fullConfig()
fullConfig_trainer = CNNSupervisedTrainer_fullConfig.CNNSupervisedTrainer_fullConfig(
fullConfig_loader,
......
......@@ -11,6 +11,7 @@ if __name__ == "__main__":
logger.addHandler(handler)
simpleConfig_creator = CNNCreator_simpleConfig.CNNCreator_simpleConfig()
simpleConfig_creator.validate_parameters()
simpleConfig_loader = CNNDataLoader_simpleConfig.CNNDataLoader_simpleConfig()
simpleConfig_trainer = CNNSupervisedTrainer_simpleConfig.CNNSupervisedTrainer_simpleConfig(
simpleConfig_loader,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment