Commit 45f18417 authored by Evgeny Kusmenko's avatar Evgeny Kusmenko

Merge branch 'release' into 'master'

Pipeline fix and new CNNTrain Integration

See merge request !22
parents 7aeb41ef 7cd16d16
Pipeline #191322 passed with stages
in 5 minutes and 16 seconds
......@@ -9,7 +9,7 @@
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>cnnarch-gluon-generator</artifactId>
<version>0.2.8-SNAPSHOT</version>
<version>0.2.9-SNAPSHOT</version>
<!-- == PROJECT DEPENDENCIES ============================================= -->
......@@ -17,7 +17,7 @@
<!-- .. SE-Libraries .................................................. -->
<CNNArch.version>0.3.3-SNAPSHOT</CNNArch.version>
<CNNTrain.version>0.3.6-SNAPSHOT</CNNTrain.version>
<CNNTrain.version>0.3.7-SNAPSHOT</CNNTrain.version>
<CNNArch2X.version>0.0.4-SNAPSHOT</CNNArch2X.version>
<embedded-montiarc-math-opt-generator>0.1.4</embedded-montiarc-math-opt-generator>
<EMADL2PythonWrapper.version>0.0.2-SNAPSHOT</EMADL2PythonWrapper.version>
......
......@@ -151,7 +151,14 @@ public class CNNTrain2Gluon extends CNNTrainGenerator {
// Generate Reward function if necessary
if (configuration.getRlRewardFunction().isPresent()) {
generateRewardFunction(configuration.getRlRewardFunction().get(), Paths.get(rootProjectModelsDir));
if (configuration.getTrainedArchitecture().isPresent()) {
generateRewardFunction(configuration.getTrainedArchitecture().get(),
configuration.getRlRewardFunction().get(), Paths.get(rootProjectModelsDir));
} else {
Log.error("No architecture model for the trained neural network but is required for " +
"reinforcement learning configuration.");
}
}
ftlContext.put("trainerName", trainerName);
......@@ -167,7 +174,8 @@ public class CNNTrain2Gluon extends CNNTrainGenerator {
return fileContentMap;
}
private void generateRewardFunction(RewardFunctionSymbol rewardFunctionSymbol, Path modelsDirPath) {
private void generateRewardFunction(NNArchitectureSymbol trainedArchitecture,
RewardFunctionSymbol rewardFunctionSymbol, Path modelsDirPath) {
GeneratorPythonWrapperStandaloneApi pythonWrapperApi = new GeneratorPythonWrapperStandaloneApi();
List<String> fullNameOfComponent = rewardFunctionSymbol.getRewardFunctionComponentName();
......@@ -200,7 +208,7 @@ public class CNNTrain2Gluon extends CNNTrainGenerator {
componentPortInformation = pythonWrapperApi.generate(emaSymbol, pythonWrapperOutputPath);
}
RewardFunctionParameterAdapter functionParameter = new RewardFunctionParameterAdapter(componentPortInformation);
new FunctionParameterChecker().check(functionParameter);
new FunctionParameterChecker().check(functionParameter, trainedArchitecture);
rewardFunctionSymbol.setRewardFunctionParameter(functionParameter);
}
......
/* (c) https://github.com/MontiCore/monticore */
package de.monticore.lang.monticar.cnnarch.gluongenerator.reinforcement;
import de.monticore.lang.monticar.cnntrain._symboltable.NNArchitectureSymbol;
import de.se_rwth.commons.logging.Log;
import java.util.List;
/**
*
*/
......@@ -11,21 +14,42 @@ public class FunctionParameterChecker {
private String inputTerminalParameterName;
private String outputParameterName;
private RewardFunctionParameterAdapter rewardFunctionParameter;
private NNArchitectureSymbol trainedArchitecture;
public FunctionParameterChecker() {
}
public void check(final RewardFunctionParameterAdapter rewardFunctionParameter) {
public void check(final RewardFunctionParameterAdapter rewardFunctionParameter,
final NNArchitectureSymbol trainedArchitecture) {
assert rewardFunctionParameter != null;
assert trainedArchitecture != null;
this.rewardFunctionParameter = rewardFunctionParameter;
this.trainedArchitecture = trainedArchitecture;
retrieveParameterNames();
checkHasExactlyTwoInputs();
checkHasExactlyOneOutput();
checkHasStateAndTerminalInput();
checkInputStateDimension();
checkInputTerminalTypeAndDimension();
checkStateDimensionEqualsTrainedArchitectureState();
checkInputStateDimension();
checkOutputDimension();
}
private void checkStateDimensionEqualsTrainedArchitectureState() {
failIfConditionFails(stateInputOfNNArchitectureIsEqualToRewardState(),
"State dimension of trained architecture is not equal to reward state dimensions.");
}
private boolean stateInputOfNNArchitectureIsEqualToRewardState() {
assert trainedArchitecture.getInputs().size() == 1: "Trained architecture is not a policy network.";
final String nnStateInputName = trainedArchitecture.getInputs().get(0);
final List<Integer> dimensions = trainedArchitecture.getDimensions().get(nnStateInputName);
return rewardFunctionParameter.getInputPortDimensionOfPort(inputStateParameterName).isPresent()
&& rewardFunctionParameter.getInputPortDimensionOfPort(inputStateParameterName).get().equals(dimensions);
}
private void checkHasExactlyTwoInputs() {
failIfConditionFails(functionHasTwoInputs(), "Reward function must have exactly two input parameters: "
+ "One input needs to represents the environment's state and another input needs to be a "
......
package de.monticore.lang.monticar.cnnarch.gluongenerator.reinforcement;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import de.monticore.lang.monticar.cnntrain._symboltable.NNArchitectureSymbol;
import de.monticore.lang.monticar.generator.pythonwrapper.symbolservices.data.ComponentPortInformation;
import de.monticore.lang.monticar.generator.pythonwrapper.symbolservices.data.EmadlType;
import de.monticore.lang.monticar.generator.pythonwrapper.symbolservices.data.PortDirection;
import de.monticore.lang.monticar.generator.pythonwrapper.symbolservices.data.PortVariable;
import de.se_rwth.commons.logging.Finding;
import de.se_rwth.commons.logging.Log;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class FunctionParameterCheckerTest {
private static final List<Integer> STATE_DIMENSIONS = Lists.newArrayList(3,2,4);
private static final PortVariable STATE_PORT = PortVariable.multidimensionalVariableFrom("input1", EmadlType.Q,
PortDirection.INPUT, STATE_DIMENSIONS);
private static final PortVariable TERMINAL_PORT = PortVariable.primitiveVariableFrom("input2", EmadlType.B,
PortDirection.INPUT);
private static final PortVariable OUTPUT_PORT = PortVariable.primitiveVariableFrom("output1", EmadlType.Q,
PortDirection.OUTPUT);
private static final String COMPONENT_NAME = "TestRewardComponent";
FunctionParameterChecker uut = new FunctionParameterChecker();
@Before
public void setup() {
Log.getFindings().clear();
Log.enableFailQuick(false);
}
@Test
public void validReward() {
// given
RewardFunctionParameterAdapter adapter = getValidRewardAdapter();
// when
uut.check(adapter, getValidTrainedArchitecture());
List<Finding> findings = Log.getFindings();
assertEquals(0, findings.stream().filter(Finding::isError).count());
}
@Test
public void invalidRewardWithOneInput() {
// given
RewardFunctionParameterAdapter adapter = getComponentWithOneInput();
// when
uut.check(adapter, getValidTrainedArchitecture());
List<Finding> findings = Log.getFindings();
assertTrue(findings.stream().anyMatch(Finding::isError));
}
@Test
public void invalidRewardWithTwoOutputs() {
// given
RewardFunctionParameterAdapter adapter = getComponentWithTwoOutputs();
// when
uut.check(adapter, getValidTrainedArchitecture());
List<Finding> findings = Log.getFindings();
assertTrue(findings.stream().anyMatch(Finding::isError));
}
@Test
public void invalidRewardWithTerminalHasQType() {
// given
RewardFunctionParameterAdapter adapter = getComponentWithTwoQInputs();
// when
uut.check(adapter, getValidTrainedArchitecture());
List<Finding> findings = Log.getFindings();
assertTrue(findings.stream().anyMatch(Finding::isError));
}
@Test
public void invalidRewardWithNonScalarOutput() {
// given
RewardFunctionParameterAdapter adapter = getComponentWithNonScalarOutput();
// when
uut.check(adapter, getValidTrainedArchitecture());
List<Finding> findings = Log.getFindings();
assertTrue(findings.stream().filter(Finding::isError).count() == 1);
}
@Test
public void invalidRewardStateUnequalToTrainedArchitectureState1() {
// given
RewardFunctionParameterAdapter adapter = getValidRewardAdapter();
NNArchitectureSymbol trainedArchitectureWithDifferenDimension = getTrainedArchitectureWithStateDimensions(
Lists.newArrayList(6));
// when
uut.check(adapter, trainedArchitectureWithDifferenDimension);
List<Finding> findings = Log.getFindings();
assertTrue(findings.stream().filter(Finding::isError).count() == 1);
}
@Test
public void invalidRewardStateUnequalToTrainedArchitectureState2() {
// given
RewardFunctionParameterAdapter adapter = getValidRewardAdapter();
NNArchitectureSymbol trainedArchitectureWithDifferenDimension = getTrainedArchitectureWithStateDimensions(
Lists.newArrayList(3, 8));
// when
uut.check(adapter, trainedArchitectureWithDifferenDimension);
List<Finding> findings = Log.getFindings();
assertTrue(findings.stream().filter(Finding::isError).count() == 1);
}
@Test
public void invalidRewardStateUnequalToTrainedArchitectureState3() {
// given
RewardFunctionParameterAdapter adapter = getValidRewardAdapter();
NNArchitectureSymbol trainedArchitectureWithDifferenDimension = getTrainedArchitectureWithStateDimensions(
Lists.newArrayList(2,4,3));
// when
uut.check(adapter, trainedArchitectureWithDifferenDimension);
List<Finding> findings = Log.getFindings();
assertTrue(findings.stream().filter(Finding::isError).count() == 1);
}
private RewardFunctionParameterAdapter getComponentWithNonScalarOutput() {
ComponentPortInformation componentPortInformation = new ComponentPortInformation(COMPONENT_NAME);
componentPortInformation.addAllInputs(getValidInputPortVariables());
List<PortVariable> outputs = Lists.newArrayList(PortVariable.multidimensionalVariableFrom(
"output", EmadlType.Q, PortDirection.OUTPUT, Lists.newArrayList(2,2)));
componentPortInformation.addAllOutputs(outputs);
return new RewardFunctionParameterAdapter(componentPortInformation);
}
private RewardFunctionParameterAdapter getComponentWithTwoQInputs() {
ComponentPortInformation componentPortInformation
= new ComponentPortInformation(COMPONENT_NAME);
List<PortVariable> inputs = Lists.newArrayList(STATE_PORT,
PortVariable.multidimensionalVariableFrom("input2", EmadlType.Q, PortDirection.INPUT,
Lists.newArrayList(2,3,2)));
componentPortInformation.addAllInputs(inputs);
componentPortInformation.addAllOutputs(getValidOutputPorts());
return new RewardFunctionParameterAdapter(componentPortInformation);
}
private RewardFunctionParameterAdapter getComponentWithTwoOutputs() {
ComponentPortInformation componentPortInformation
= new ComponentPortInformation(COMPONENT_NAME);
componentPortInformation.addAllInputs(getValidInputPortVariables());
List<PortVariable> outputs = getValidOutputPorts();
outputs.add(PortVariable.primitiveVariableFrom("output2", EmadlType.B, PortDirection.OUTPUT));
componentPortInformation.addAllOutputs(outputs);
return new RewardFunctionParameterAdapter(componentPortInformation);
}
private RewardFunctionParameterAdapter getComponentWithOneInput() {
ComponentPortInformation componentPortInformation
= new ComponentPortInformation(COMPONENT_NAME);
componentPortInformation.addAllInputs(Lists.newArrayList(STATE_PORT));
componentPortInformation.addAllOutputs(getValidOutputPorts());
return new RewardFunctionParameterAdapter(componentPortInformation);
}
private RewardFunctionParameterAdapter getValidRewardAdapter() {
ComponentPortInformation componentPortInformation
= new ComponentPortInformation(COMPONENT_NAME);
componentPortInformation.addAllInputs(getValidInputPortVariables());
componentPortInformation.addAllOutputs(getValidOutputPorts());
return new RewardFunctionParameterAdapter(componentPortInformation);
}
private List<PortVariable> getValidOutputPorts() {
return Lists.newArrayList(OUTPUT_PORT);
}
private List<PortVariable> getValidInputPortVariables() {
return Lists.newArrayList(STATE_PORT, TERMINAL_PORT);
}
private NNArchitectureSymbol getValidTrainedArchitecture() {
NNArchitectureSymbol nnArchitectureSymbol = mock(NNArchitectureSymbol.class);
final String stateInputName = "stateInput";
when(nnArchitectureSymbol.getInputs()).thenReturn(Lists.newArrayList(stateInputName));
when(nnArchitectureSymbol.getDimensions()).thenReturn(ImmutableMap.<String, List<Integer>>builder()
.put(stateInputName, STATE_DIMENSIONS)
.build());
return nnArchitectureSymbol;
}
private NNArchitectureSymbol getTrainedArchitectureWithStateDimensions(final List<Integer> dimensions) {
NNArchitectureSymbol nnArchitectureSymbol = mock(NNArchitectureSymbol.class);
final String stateInputName = "stateInput";
when(nnArchitectureSymbol.getInputs()).thenReturn(Lists.newArrayList(stateInputName));
when(nnArchitectureSymbol.getDimensions()).thenReturn(ImmutableMap.<String, List<Integer>>builder()
.put(stateInputName, dimensions)
.build());
return nnArchitectureSymbol;
}
}
\ No newline at end of file
/* (c) https://github.com/MontiCore/monticore */
#ifndef CNNBUFFERFILE_H
#define CNNBUFFERFILE_H
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import logging
import os
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import logging
import os
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import logging
import os
......
# (c) https://github.com/MontiCore/monticore
import os
import h5py
import mxnet as mx
......
# (c) https://github.com/MontiCore/monticore
import os
import h5py
import mxnet as mx
......
# (c) https://github.com/MontiCore/monticore
import os
import h5py
import mxnet as mx
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import numpy as np
from mxnet import gluon
......@@ -91,13 +90,14 @@ class Net_0(gluon.HybridBlock):
else:
self.input_normalization_data_ = NoNormalization()
self.conv1_padding = Padding(padding=(0,0,0,0,2,1,2,1))
self.conv1_padding = Padding(padding=(0,0,-1,0,0,0,0,0))
self.conv1_ = gluon.nn.Conv2D(channels=96,
kernel_size=(11,11),
strides=(4,4),
use_bias=True)
# conv1_, output shape: {[96,55,55]}
self.pool1_padding = Padding(padding=(0,0,-1,0,0,0,0,0))
self.pool1_ = gluon.nn.MaxPool2D(
pool_size=(3,3),
strides=(2,2))
......@@ -114,6 +114,7 @@ class Net_0(gluon.HybridBlock):
use_bias=True)
# conv2_1_, output shape: {[128,27,27]}
self.pool2_1_padding = Padding(padding=(0,0,-1,0,0,0,0,0))
self.pool2_1_ = gluon.nn.MaxPool2D(
pool_size=(3,3),
strides=(2,2))
......@@ -127,6 +128,7 @@ class Net_0(gluon.HybridBlock):
use_bias=True)
# conv2_2_, output shape: {[128,27,27]}
self.pool2_2_padding = Padding(padding=(0,0,-1,0,0,0,0,0))
self.pool2_2_ = gluon.nn.MaxPool2D(
pool_size=(3,3),
strides=(2,2))
......@@ -162,6 +164,7 @@ class Net_0(gluon.HybridBlock):
use_bias=True)
# conv5_1_, output shape: {[128,13,13]}
self.pool5_1_padding = Padding(padding=(0,0,-1,0,0,0,0,0))
self.pool5_1_ = gluon.nn.MaxPool2D(
pool_size=(3,3),
strides=(2,2))
......@@ -183,6 +186,7 @@ class Net_0(gluon.HybridBlock):
use_bias=True)
# conv5_2_, output shape: {[128,13,13]}
self.pool5_2_padding = Padding(padding=(0,0,-1,0,0,0,0,0))
self.pool5_2_ = gluon.nn.MaxPool2D(
pool_size=(3,3),
strides=(2,2))
......@@ -217,7 +221,8 @@ class Net_0(gluon.HybridBlock):
beta=0.75,
knorm=2,
nsize=5)
pool1_ = self.pool1_(lrn1_)
pool1_padding = self.pool1_padding(lrn1_)
pool1_ = self.pool1_(pool1_padding)
relu1_ = self.relu1_(pool1_)
split1_ = self.split1_(relu1_)
get2_1_ = split1_[0]
......@@ -228,7 +233,8 @@ class Net_0(gluon.HybridBlock):
beta=0.75,
knorm=2,
nsize=5)
pool2_1_ = self.pool2_1_(lrn2_1_)
pool2_1_padding = self.pool2_1_padding(lrn2_1_)
pool2_1_ = self.pool2_1_(pool2_1_padding)
relu2_1_ = self.relu2_1_(pool2_1_)
get2_2_ = split1_[1]
conv2_2_padding = self.conv2_2_padding(get2_2_)
......@@ -238,7 +244,8 @@ class Net_0(gluon.HybridBlock):
beta=0.75,
knorm=2,
nsize=5)
pool2_2_ = self.pool2_2_(lrn2_2_)
pool2_2_padding = self.pool2_2_padding(lrn2_2_)
pool2_2_ = self.pool2_2_(pool2_2_padding)
relu2_2_ = self.relu2_2_(pool2_2_)
concatenate3_ = self.concatenate3_(relu2_1_, relu2_2_)
conv3_padding = self.conv3_padding(concatenate3_)
......@@ -251,7 +258,8 @@ class Net_0(gluon.HybridBlock):
relu4_1_ = self.relu4_1_(conv4_1_)
conv5_1_padding = self.conv5_1_padding(relu4_1_)
conv5_1_ = self.conv5_1_(conv5_1_padding)
pool5_1_ = self.pool5_1_(conv5_1_)
pool5_1_padding = self.pool5_1_padding(conv5_1_)
pool5_1_ = self.pool5_1_(pool5_1_padding)
relu5_1_ = self.relu5_1_(pool5_1_)
get4_2_ = split3_[1]
conv4_2_padding = self.conv4_2_padding(get4_2_)
......@@ -259,7 +267,8 @@ class Net_0(gluon.HybridBlock):
relu4_2_ = self.relu4_2_(conv4_2_)
conv5_2_padding = self.conv5_2_padding(relu4_2_)
conv5_2_ = self.conv5_2_(conv5_2_padding)
pool5_2_ = self.pool5_2_(conv5_2_)
pool5_2_padding = self.pool5_2_padding(conv5_2_)
pool5_2_ = self.pool5_2_(pool5_2_padding)
relu5_2_ = self.relu5_2_(pool5_2_)
concatenate6_ = self.concatenate6_(relu5_1_, relu5_2_)
fc6_ = self.fc6_(concatenate6_)
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import numpy as np
from mxnet import gluon
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import numpy as np
from mxnet import gluon
......
/* (c) https://github.com/MontiCore/monticore */
#ifndef CNNPREDICTOR_ALEXNET
#define CNNPREDICTOR_ALEXNET
......
/* (c) https://github.com/MontiCore/monticore */
#ifndef CNNPREDICTOR_CIFARCLASSIFIERNETWORK
#define CNNPREDICTOR_CIFARCLASSIFIERNETWORK
......
/* (c) https://github.com/MontiCore/monticore */
#ifndef CNNPREDICTOR_VGG16
#define CNNPREDICTOR_VGG16
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import logging
import numpy as np
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import logging
import numpy as np
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import logging
import numpy as np
......
# (c) https://github.com/MontiCore/monticore
import logging
import mxnet as mx
import CNNCreator_emptyConfig
......
# (c) https://github.com/MontiCore/monticore
import logging
import mxnet as mx
import CNNCreator_fullConfig
......
# (c) https://github.com/MontiCore/monticore
import logging
import mxnet as mx
import CNNCreator_simpleConfig
......
# (c) https://github.com/MontiCore/monticore
from reinforcement_learning.agent import DqnAgent
from reinforcement_learning.util import AgentSignalHandler
from reinforcement_learning.cnnarch_logger import ArchLogger
......
# (c) https://github.com/MontiCore/monticore
import mxnet as mx
import numpy as np
import time
......
# (c) https://github.com/MontiCore/monticore
import logging
import sys
import os
......
# (c) https://github.com/MontiCore/monticore
import abc
import logging
logging.basicConfig(level=logging.INFO)
......