blob: 405f0d9e9df57e142d64f926586b8a34727dff9f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020 CEA LIST
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Abhishek Djeachandrane - Initial API and implementation
*******************************************************************************/
package org.eclipse.papyrus.aiml.gen.keras;
import org.eclipse.uml2.uml.Class;
import static extension org.eclipse.uml2.uml.util.UMLUtil.getStereotypeApplication
import org.eclipse.papyrus.aiml.profile.AIML.Module.Model
import org.eclipse.papyrus.aiml.profile.AIML.Tensor.Tensor
import org.eclipse.papyrus.aiml.profile.AIML.Convolution_layers.Convolution_layers
import org.eclipse.papyrus.aiml.profile.AIML.Recurrent_layers.Recurrent_layers
import org.eclipse.papyrus.aiml.profile.AIML.Recurrent_layers.LSTM
import org.eclipse.papyrus.aiml.profile.AIML.Recurrent_layers.GRU
import org.eclipse.papyrus.aiml.profile.AIML.Linear_layers.Linear_layers
import org.eclipse.papyrus.aiml.profile.AIML.Linear_layers.Linear
import org.eclipse.papyrus.aiml.gen.keras.ModelOps;
class GenKeras {
static def genKeras(Class clazz) {
val module = clazz.getStereotypeApplication(Model)
if (module !== null) {
return module.genModule
} else {
return "";
}
}
/**
* Generate a model with different elements necessary for the compilation
*/
static def genModule(Model module) '''
«module.genDefaultTemplate»
«module.genModuleInit»
«module.genModuleCall»
«module.genModuleCompilation»
'''
/**
* Generate the model instance and compilation
*/
static def genModuleCompilation(Model module) '''
«module.base_Class.name.toFirstLower» = «module.base_Class.name»()
««««»«ModelOps.modelAttributesToDisplayForCompilation(module)»
«var study=ModelOps.modelAttributesToCollectProperly(module)»
«study.attributesName.toList»
«study.attributesValue.toList»
«study.attributesType.toList»
«FOR n : study.attributesValue.toList»
«ENDFOR»
«var study2=ModelOps.modelAttributesToDisplayForCompilationProperly(module)»
«study2»
'''
/**
* Generate the basic template with importation in the head of the code
*/
static def genDefaultTemplate(Model module) '''
# generated by Papyrus from module «module.base_Class.class»
import tensorflow as tf
from tensorflow import keras
inputs=[(1,2),(3,4)]
'''
/**
* Generate layer instance through modeling
*/
static def genModuleInit(Model module) '''
class «module.base_Class.name»(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__()
«FOR layer : module.base_Class.ownedAttributes»
«val type = layer.type»
«val layerSt = type.getStereotypeApplication(Model)»
«genLayer(layerSt)»
«ENDFOR»
«FOR connector : module.base_Class.ownedConnectors»
«ENDFOR»
'''
/**
* Generate the code which consist to determine the data flow between layers
* @param l the model ...
*/
static def genModuleCall(Model module) '''
def call(self, inputs):
«var nbr_lay = GenCheck.findNbrOfLayer(module)»
«var unsortedInformationFlowList = ModelOps.genInputOutputLayerArrayWithFlow(nbr_lay,module)»
«IF unsortedInformationFlowList instanceof ModuleInfo»
«var sortedInformationFlowList = ModelOps.genFlowOrder(nbr_lay, unsortedInformationFlowList)»
«FOR layer :sortedInformationFlowList.toList»
«var inputs = sortedInformationFlowList.toList.indexOf(layer)-1»
«IF inputs<0»
x«sortedInformationFlowList.toList.indexOf(layer)» = self.«layer»(input)
«ELSEIF inputs>=0 && inputs<sortedInformationFlowList.length-2»
x«sortedInformationFlowList.toList.indexOf(layer)» = self.«layer»(x«inputs»)
«ELSEIF inputs==sortedInformationFlowList.length-2»
output = self.«layer»(x«inputs»)
«ENDIF»
«ENDFOR»
«ENDIF»
return output
'''
/**
* Generate each layer according to the model
*/
static def genLayer(Model layer) {
if (layer instanceof Convolution_layers) {
genConvolutionLayer(layer as Convolution_layers)
} else if (layer instanceof Recurrent_layers) {
genRecurrentLayer(layer as Recurrent_layers)
} else if (layer instanceof Linear_layers) {
genLinearLayer(layer as Linear_layers)
}
}
/**
* Generate each convolution layer according to the model
*/
static def genConvolutionLayer(Convolution_layers convolutionLayer) '''
'''
/**
* Generate each linear layer according to the model
*/
static def genLinearLayer(Linear_layers linearLayer) {
if (linearLayer instanceof Linear) {
genDense(linearLayer as Linear)
}
}
/**
* Generate each recurrent layer according to the model
*/
static def genRecurrentLayer(Recurrent_layers recurrentLayer) {
if (recurrentLayer instanceof LSTM) {
genLstm(recurrentLayer as LSTM)
} else if (recurrentLayer instanceof GRU) {
genGru(recurrentLayer as GRU)
}
}
/**
* Generate each dense layer according to the model
*/
static def genDense(Linear denseLayer) '''
self.«denseLayer.base_Class.name»=tf.keras.layers.Dense(«denseLayer.in_features»)
'''
/**
* Generate each LSTM layer according to the model
*/
static def genLstm(LSTM lstmLayer) '''
«««»»«IF lstmLayer.return_sequences.equals(true)»
«««self.«lstmLayer.base_Class.name»=tf.keras.layers.«lstmLayer.eClass.name»(«lstmLayer.hidden_size»,input_shape=[«lstmLayer.input_size»],return_sequences=True)
««««»»«ELSEIF lstmLayer.return_sequences.equals(false)»
««««self.«lstmLayer.base_Class.name»=tf.keras.layers.«lstmLayer.eClass.name»(«lstmLayer.hidden_size»,input_shape=[«lstmLayer.input_size»],return_sequences=False)
««««»»«ENDIF»
«var tt = RecurrentLayerOps.lstmAttributesToDisplay(lstmLayer)»
«tt»
'''
/**
* Generate each GRU layer according to the model
*/
static def genGru(GRU gruLayer) '''
«««»»«gruLayer.eClass.name»
«««»«gruLayer.input_size»
«var tt = RecurrentLayerOps.lstmAttributesToDisplay(gruLayer)»
«tt»
'''
/**
* Generate each tensor according to the model
*/
static def genTensor(Tensor tensor) '''
tensor ...
'''
}