| /******************************************************************************* |
| * 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 ... |
| ''' |
| |
| } |