Commit 876e4b30 authored by Evgeny Kusmenko's avatar Evgeny Kusmenko
Browse files

Merge branch 'develop' into 'master'

Develop

See merge request !37
parents a737d50f 70cab382
Pipeline #350419 passed with stages
in 1 minute and 5 seconds
......@@ -2,6 +2,7 @@
stages:
#- windows
- docker
- linux
- deploy
......@@ -45,7 +46,7 @@ git masterJobLinux:
integrationMXNetJobLinux:
stage: linux
image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/integrationtests/mxnet:v0.0.5
image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/dockerimages/mxnet150:v0.0.5
script:
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B -U clean install --settings settings.xml -Dtest=IntegrationMXNetTest
except:
......@@ -67,7 +68,7 @@ integrationCaffe2JobLinux:
integrationGluonJobLinux:
stage: linux
image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/integrationtests/mxnet:v0.0.5
image: registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/dockerimages/mxnet150:v0.0.5
script:
- mvn -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -B -U clean install --settings settings.xml -Dtest=IntegrationGluonTest
except:
......@@ -118,4 +119,28 @@ UnitTestJobLinux:
- .gitlab-ci.yml
- README.md
buildDockerMXNet150:
stage: docker
tags:
- shell
script:
- cd src/test/resources/docker/mxnet150
# - docker login registry.git.rwth-aachen.de -u someUserName -p yEep-tAt19HbsmNQJMNo
- docker build -t registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/dockerimages/mxnet150:v0.0.5 .
- docker push registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/dockerimages/mxnet150:v0.0.5
only:
changes:
- src/test/resources/docker/mxnet150/**/*
buildDockerMXNet170:
stage: docker
tags:
- shell
script:
- cd src/test/resources/docker/mxnet170
# - docker login registry.git.rwth-aachen.de -u someUserName -p yEep-tAt19HbsmNQJMNo
- docker build -t registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/dockerimages/mxnet170:v0.0.1 .
- docker push registry.git.rwth-aachen.de/monticore/embeddedmontiarc/generators/emadl2cpp/dockerimages/mxnet170:v0.0.1
only:
changes:
- src/test/resources/docker/mxnet170/**/*
......@@ -31,11 +31,11 @@ See example project [EMADL-Demo](https://git.rwth-aachen.de/thomas.timmermanns/E
## Installation
A new bash script for mxnet/gluon can be found [installation scripts](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/tree/master/src/main/resources/installation_scripts)
changing the installation process for mxnet for cpp. This fill now install the full cpp api and not the reduced c api. This script will install all dependencies both for python and cpp as of 26.08.2020.
Additionally a similar docker script used for the git ci pipeline can be found in the gluon subfolder at [Docker images](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/tree/master/src/test/resources/docker).
The other two bash scripts found in the installation_scripts folder are outdated but may be consulted for installation guidlines for other backends.
changing the installation process for mxnet for cpp (version 1.5.1). This fill now install the full cpp api and not the reduced c api. This script will install all dependencies both for python and cpp as of 26.10.2020. Note that some advanced layers need version 1.7.0 which in turn needs python3. For running the generator with python 3 you may need to specifiy the python path when calling it (see howto 3.).
Additionally similar docker scripts,for both versions 1.5.0 and 1.7.0, that are used for the git ci pipelines can be found in the gluon subfolder at [Docker images](https://git.rwth-aachen.de/monticore/EmbeddedMontiArc/generators/EMADL2CPP/-/tree/master/src/test/resources/docker).
The other two bash scripts found in the installation_scripts folder are outdated but may be consulted for installation guidlines for other backends.
Note that the installation may take some time (hours) enough RAM or a big enough swapspace is advisable (>10GB). This scripts were tested with a completly clean Ubuntu 16.04,
without system updates installed. Using another Ubuntu version or installing other stuff, system updates included might/ have caused problems.
without system updates installed. Using another Ubuntu version or installing other stuff, system updates included might/ have caused problems.
If you want to install the backends with CUDA GPU support(only MXNet/Gluon and Tensorflow, the used caffe2 version does not work with GPU support anymore),
you have to install CUDA 10.0(mxnet/ gluon also works with newer version and maybe older), CUDNN and NCCL (Obtainable from the nvidai webpage).
......
......@@ -9,24 +9,25 @@
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>embedded-montiarc-emadl-generator</artifactId>
<version>0.4.1</version>
<version>0.4.2</version>
<!-- == PROJECT DEPENDENCIES ============================================= -->
<properties>
<!-- .. SE-Libraries .................................................. -->
<emadl.version>0.2.12-SNAPSHOT</emadl.version>
<CNNTrain.version>0.3.12-SNAPSHOT</CNNTrain.version>
<cnnarch-generator.version>0.0.7-SNAPSHOT</cnnarch-generator.version>
<cnnarch-mxnet-generator.version>0.2.17-SNAPSHOT</cnnarch-mxnet-generator.version>
<cnnarch-caffe2-generator.version>0.2.14-SNAPSHOT</cnnarch-caffe2-generator.version>
<cnnarch-gluon-generator.version>0.2.12-SNAPSHOT</cnnarch-gluon-generator.version>
<cnnarch-tensorflow-generator.version>0.1.0-SNAPSHOT</cnnarch-tensorflow-generator.version>
<Common-MontiCar.version>0.0.19-SNAPSHOT</Common-MontiCar.version>
<embedded-montiarc-math-opt-generator>0.1.6</embedded-montiarc-math-opt-generator>
<!-- .. Libraries .................................................. -->
<emadl.version>0.2.12-SNAPSHOT</emadl.version>
<CNNTrain.version>0.4.0-SNAPSHOT</CNNTrain.version>
<cnnarch-generator.version>0.4.0-SNAPSHOT</cnnarch-generator.version>
<cnnarch-mxnet-generator.version>0.4.0-SNAPSHOT</cnnarch-mxnet-generator.version>
<cnnarch-caffe2-generator.version>0.4.0-SNAPSHOT</cnnarch-caffe2-generator.version>
<cnnarch-gluon-generator.version>0.4.0-SNAPSHOT</cnnarch-gluon-generator.version>
<cnnarch-tensorflow-generator.version>0.4.0-SNAPSHOT</cnnarch-tensorflow-generator.version>
<Common-MontiCar.version>0.2.12-SNAPSHOT</Common-MontiCar.version>
<embedded-montiarc-math-generator.version>0.4.0-SNAPSHOT</embedded-montiarc-math-generator.version>
<!-- .. Libraries .................................................. -->
<guava.version>25.1-jre</guava.version>
<junit.version>4.13.1</junit.version>
<logback.version>1.1.2</logback.version>
......@@ -67,8 +68,8 @@
<!-- MontiCore Dependencies -->
<dependency>
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>embedded-montiarc-math-opt-generator</artifactId>
<version>${embedded-montiarc-math-opt-generator}</version>
<artifactId>embedded-montiarc-math-generator</artifactId>
<version>${embedded-montiarc-math-generator.version}</version>
</dependency>
<dependency>
......@@ -113,13 +114,13 @@
<version>${CNNTrain.version}</version>
</dependency>
<dependency>
<groupId>de.monticore.lang.monticar</groupId>
<artifactId>cnn-train</artifactId>
<version>${CNNTrain.version}</version>
<classifier>${grammars.classifier}</classifier>
<scope>provided</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>de.monticore.lang.monticar</groupId>-->
<!-- <artifactId>cnn-train</artifactId>-->
<!-- <version>${CNNTrain.version}</version>-->
<!-- <classifier>${grammars.classifier}</classifier>-->
<!-- <scope>provided</scope>-->
<!-- </dependency>-->
<dependency>
<groupId>de.monticore.lang.monticar</groupId>
......
......@@ -4,7 +4,7 @@ package de.monticore.lang.monticar.emadl.generator.reinforcementlearning;
import de.monticore.lang.embeddedmontiarc.embeddedmontiarc._symboltable.instanceStructure.EMAComponentInstanceSymbol;
import de.monticore.lang.monticar.cnnarch.gluongenerator.reinforcement.RewardFunctionSourceGenerator;
import de.monticore.lang.monticar.emadl.generator.EMADLAbstractSymtab;
import de.monticore.lang.monticar.generator.cpp.GeneratorEMAMOpt2CPP;
import de.monticore.lang.monticar.generator.cpp.GeneratorCPP;
import de.monticore.lang.tagging._symboltable.TaggingResolver;
import de.se_rwth.commons.logging.Log;
......@@ -32,13 +32,13 @@ public class RewardFunctionCppGenerator implements RewardFunctionSourceGenerator
@Override
public void generate(EMAComponentInstanceSymbol componentInstanceSymbol, TaggingResolver taggingResolver,
String targetPath) {
GeneratorEMAMOpt2CPP generator = new GeneratorEMAMOpt2CPP();
GeneratorCPP generator = new GeneratorCPP();
generator.useArmadilloBackend();
generator.setGenerationTargetPath(targetPath);
try {
generator.generate(componentInstanceSymbol, taggingResolver);
generator.generateFiles(taggingResolver, componentInstanceSymbol);
} catch (IOException e) {
Log.error("Generation of reward function is not possible: " + e.getMessage());
}
......
This diff is collapsed.
This diff is collapsed.
mxnet @ 75a9e187
Subproject commit 75a9e187d00a8b7ebc71412a02ed0e3ae489d91f
sudo apt-get update -y
sudp apt-get install -y build-essential git openjdk-8-jdk maven ninja-build ccache libopenblas-dev libblas-dev /
liblapack-dev libopencv-dev libarmadillo-dev cmake python2.7 python-dev /
python-numpy python3-pip python3-pip swig unzip libboost-all-dev
python-numpy python-tk python3-pip python3-pip swig unzip libboost-all-dev
sudo update-alternatives --config java
......@@ -22,12 +22,12 @@ pip install --user h5py matplotlib numpy==1.16.5 mxnet==1.5.1.post0 #The newest
git clone --recursive https://github.com/apache/incubator-mxnet.git mxnet
cd mxnet && git checkout tags/1.5.0 && git submodule update --recursive --init
cd mxnet && mkdir build && cd build && cmake -DUSE_CPP_PACKAGE=1 -DUSE_CUDA=0 -GNinja .. && ninja -v
cd mxnet && cp -r include/mxnet /usr/include/mxnet && cp -r cpp-package/include/mxnet-cpp /usr/include/ && cp -r 3rdparty/tvm/nnvm/include/nnvm /usr/include/ && cp -r 3rdparty/dmlc-core/include/dmlc /usr/include/
mkdir build && cd build && cmake -DUSE_CPP_PACKAGE=1 -DUSE_CUDA=0 -GNinja .. && ninja -v
sudo cp -r include/mxnet /usr/include/mxnet && sudo cp -r cpp-package/include/mxnet-cpp /usr/include/ && sudo cp -r 3rdparty/tvm/nnvm/include/nnvm /usr/include/ && sudo cp -r 3rdparty/dmlc-core/include/dmlc /usr/include/
#you have to have armadillo-9.600.6.zip in your current folder
unzip armadillo.zip -d .
cd armadillo-9.600.6 && cmake . && make && make install
unzip armadillo-9.600.6.zip -d .
cd armadillo-9.600.6 && cmake . && make && sudo make install
mkdir -p /root/.config/matplotlib
echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc
\ No newline at end of file
sudo mkdir -p /root/.config/matplotlib
echo "backend : Agg" > sudo /root/.config/matplotlib/matplotlibrc
......@@ -177,7 +177,6 @@ public class GenerationTest extends AbstractSymtabTest {
String[] args = {"-m", "src/test/resources/models/", "-r", "mnist.MnistClassifier", "-b", "GLUON", "-f", "n", "-c", "n"};
EMADLGeneratorCli.main(args);
assertTrue(Log.getFindings().isEmpty());
checkFilesAreEqual(
Paths.get("./target/generated-sources-emadl"),
Paths.get("./src/test/resources/target_code/gluon"),
......@@ -256,8 +255,8 @@ public class GenerationTest extends AbstractSymtabTest {
Log.getFindings().clear();
String[] args = {"-m", "src/test/resources/models/reinforcementModel", "-r", "mountaincar.Master", "-b", "GLUON", "-f", "n", "-c", "n"};
EMADLGeneratorCli.main(args);
assertEquals(0, Log.getFindings().stream().filter(Finding::isError).count());
assertEquals(0, Log.getFindings().stream().filter(Finding::isError).count());
checkFilesAreEqual(
Paths.get("./target/generated-sources-emadl"),
Paths.get("./src/test/resources/target_code/gluon/reinforcementModel/mountaincar"),
......
......@@ -76,7 +76,7 @@ public class IntegrationGluonTest extends IntegrationTest {
deleteHashFile(Paths.get("./target/generated-sources-emadl/episodicMemorySimple/episodicMemorySimple.training_hash"));
String[] args = {"-m", "src/test/resources/models", "-r", "episodicMemorySimple.Network", "-b", "GLUON"};
String[] args = {"-m", "src/test/resources/models", "-r", "episodicMemorySimple.Network", "-b", "GLUON", "-f", "y"};
EMADLGeneratorCli.main(args);
}
......
......@@ -21,7 +21,6 @@ public class IntegrationPythonWrapperTest extends AbstractSymtabTest {
String[] args = {"-m", "src/test/resources/models/reinforcementModel", "-r", "torcs.agent.TorcsAgent", "-b", "GLUON", "-f", "n", "-c", "n"};
EMADLGeneratorCli.main(args);
assertTrue(Log.getFindings().stream().filter(Finding::isError).collect(Collectors.toList()).isEmpty());
checkFilesAreEqual(
Paths.get("./target/generated-sources-emadl"),
Paths.get("./src/test/resources/target_code/gluon/reinforcementModel/torcs"),
......@@ -76,7 +75,6 @@ public class IntegrationPythonWrapperTest extends AbstractSymtabTest {
String[] args = {"-m", "src/test/resources/models/reinforcementModel/torcs_td3", "-r", "torcs.agent.TorcsAgent", "-b", "GLUON", "-f", "n", "-c", "n"};
EMADLGeneratorCli.main(args);
assertTrue(Log.getFindings().stream().filter(Finding::isError).collect(Collectors.toList()).isEmpty());
checkFilesAreEqual(
Paths.get("./target/generated-sources-emadl"),
Paths.get("./src/test/resources/target_code/gluon/reinforcementModel/torcs_td3"),
......
FROM maven:3-jdk-8
RUN apt-get update
RUN apt-get install -y build-essential git ninja-build ccache libopenblas-dev libblas-dev liblapack-dev libopencv-dev libarmadillo-dev cmake python2.7 python-dev python-numpy python3-pip python3-pip swig unzip libboost-all-dev
RUN apt-get install -y build-essential git ninja-build ccache
RUN apt-get install -y libopenblas-dev libblas-dev
RUN apt-get install -y liblapack-dev libopencv-dev
RUN apt-get install -y libarmadillo-dev cmake
RUN apt-get install -y python2.7 python-dev python-tk
RUN apt-get install -y python-numpy
RUN apt-get install -y python3-pip
RUN apt-get install -y swig unzip
RUN apt-get install -y libboost-all-dev
RUN pip3 install --user --upgrade "cmake>=3.13.2"
RUN wget https://bootstrap.pypa.io/get-pip.py
RUN python get-pip.py
RUN pip install --user h5py matplotlib numpy==1.16.5 mxnet==1.5.1.post0
ADD armadillo-9.600.6.zip /root/armadillo.zip
RUN unzip /root/armadillo.zip -d /root/armadillo
RUN cd /root/armadillo/armadillo-9.600.6 && cmake . && make && make install
RUN git clone --recursive https://github.com/apache/incubator-mxnet.git mxnet
RUN cd mxnet && git checkout tags/1.5.0 && git submodule update --recursive --init
RUN cd mxnet && mkdir build && cd build && cmake -DUSE_CPP_PACKAGE=1 -DUSE_CUDA=0 -GNinja .. && ninja -v
RUN cd mxnet && mkdir build && cd build && cmake -DUSE_CPP_PACKAGE=1 -DUSE_CUDA=0 -GNinja .. && ninja
RUN cd mxnet && cp -r include/mxnet /usr/include/mxnet && cp -r cpp-package/include/mxnet-cpp /usr/include/ && cp -r 3rdparty/tvm/nnvm/include/nnvm /usr/include/ && cp -r 3rdparty/dmlc-core/include/dmlc /usr/include/
ADD armadillo-9.600.6.zip /root/armadillo.zip
RUN unzip /root/armadillo.zip -d /root/armadillo
RUN cd /root/armadillo/armadillo-9.600.6 && cmake . && make && make install
RUN pip3 install --user --upgrade "cmake>=3.13.2"
RUN wget https://bootstrap.pypa.io/get-pip.py
RUN python get-pip.py
RUN pip install --user h5py matplotlib numpy==1.16.5 mxnet==1.5.1.post0
RUN mkdir -p /root/.config/matplotlib
RUN echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc
FROM maven:3-jdk-8
RUN apt-get update
RUN apt-get install -y build-essential git ninja-build ccache
RUN apt-get install -y libopenblas-dev libblas-dev
RUN apt-get install -y liblapack-dev libopencv-dev
RUN apt-get install -y libarmadillo-dev cmake
RUN apt-get install -y python2.7 python-dev python-tk
RUN apt-get install -y python-numpy
RUN apt-get install -y python3-pip
RUN apt-get install -y swig unzip
RUN apt-get install -y libboost-all-dev
ADD armadillo-9.600.6.zip /root/armadillo.zip
RUN unzip /root/armadillo.zip -d /root/armadillo
RUN cd /root/armadillo/armadillo-9.600.6 && cmake . && make && make install
RUN git clone --recursive https://github.com/apache/incubator-mxnet.git mxnet
RUN cd mxnet && git checkout tags/1.7.0 && git submodule update --recursive --init
RUN cd mxnet && mkdir build && cd build && cmake -DUSE_CPP_PACKAGE=1 -DUSE_CUDA=0 -GNinja .. && ninja
RUN cd mxnet && cp -r include/mxnet /usr/include/mxnet && cp -r cpp-package/include/mxnet-cpp /usr/include/ && cp -r 3rdparty/tvm/nnvm/include/nnvm /usr/include/ && cp -r 3rdparty/dmlc-core/include/dmlc /usr/include/
RUN pip3 install --user --upgrade "cmake>=3.13.2"
RUN pip3 install --user h5py matplotlib
ADD mxnet-1.7.0b20200417-py2.py3-none-manylinux1_x86_64.whl /root/mxnet-1.7.0b20200417-py2.py3-none-manylinux1_x86_64.whl
RUN pip3 install /root/mxnet-1.7.0b20200417-py2.py3-none-manylinux1_x86_64.whl
RUN mkdir -p /root/.config/matplotlib
RUN echo "backend : Agg" > /root/.config/matplotlib/matplotlibrc
\ No newline at end of file
......@@ -7,7 +7,7 @@ component Network{
implementation CNN {
data ->
EpisodicMemory(replayInterval=10, replayBatchSize=100, replaySteps=1, replayGradientSteps=1, replayMemoryStoreProb=0.5, localAdaptionGradientSteps=30, maxStoredSamples=-1, localAdaptionK=32, queryNetDir="tag:simple", queryNetPrefix="simple_embedding-", queryNetNumInputs=1) ->
EpisodicMemory(replayInterval=10, replayBatchSize=100, replaySteps=1, replayGradientSteps=1, memoryStoreProb=1, maxStoredSamples=-1, memoryReplacementStrategy="no_replacement", useLocalAdaptation=false, localAdaptationK=4, localAdaptationGradientSteps=2, queryNetDir="tag:simple", queryNetPrefix="simple_embedding-", queryNetNumInputs=1) ->
LoadNetwork(networkDir="tag:simple", networkPrefix="simple_embedding-", numInputs=1, outputShape=(1,768)) ->
FullyConnected(units=33) ->
Softmax() ->
......
......@@ -146,11 +146,21 @@ class DotProductSelfAttention(gluon.HybridBlock):
score = F.batch_dot(head_queries, head_keys, transpose_b=True)
score = score * self.scale_factor
if self.use_mask:
mask = F.tile(mask, self.num_heads)
mask = F.repeat(mask, self.dim_model)
mask = F.reshape(mask, shape=(-1, self.dim_model))
weights = F.softmax(score, mask, use_length=self.use_mask)
seqs = F.contrib.arange_like(score, axis=1)
zeros = F.zeros_like(seqs)
zeros = F.reshape(zeros, shape=(1, -1))
mask = args[0]
mask = F.reshape(mask, shape=(-1, 1))
mask = F.broadcast_add(mask, zeros)
mask = F.expand_dims(mask, axis=1)
mask = F.broadcast_axis(mask, axis=1, size=self.num_heads)
mask = mask.reshape(shape=(-1, 0), reverse=True)
mask = F.cast(mask, dtype='int32')
weights = F.softmax(score, mask, use_length=self.use_mask)
else:
weights = F.softmax(score)
head_values = F.reshape(head_values, shape=(0, 0, self.num_heads, -1))
head_values = F.transpose(head_values, axes=(0,2,1,3))
......@@ -169,7 +179,7 @@ class DotProductSelfAttention(gluon.HybridBlock):
class EpisodicReplayMemoryInterface(gluon.HybridBlock):
__metaclass__ = abc.ABCMeta
def __init__(self, use_replay, replay_interval, replay_batch_size, replay_steps, replay_gradient_steps, num_heads, **kwargs):
def __init__(self, use_replay, replay_interval, replay_batch_size, replay_steps, replay_gradient_steps, use_local_adaptation, local_adaptation_gradient_steps, k, **kwargs):
super(EpisodicReplayMemoryInterface, self).__init__(**kwargs)
self.use_replay = use_replay
......@@ -177,7 +187,10 @@ class EpisodicReplayMemoryInterface(gluon.HybridBlock):
self.replay_batch_size = replay_batch_size
self.replay_steps = replay_steps
self.replay_gradient_steps = replay_gradient_steps
self.num_heads = num_heads
self.use_local_adaptation = use_local_adaptation
self.local_adaptation_gradient_steps = local_adaptation_gradient_steps
self.k = k
@abc.abstractmethod
def store_samples(self, data, y, query_network, store_prob, mx_context):
......@@ -187,6 +200,10 @@ class EpisodicReplayMemoryInterface(gluon.HybridBlock):
def sample_memory(self, batch_size, mx_context):
pass
@abc.abstractmethod
def sample_neighbours(self, data, query_network):
pass
@abc.abstractmethod
def get_query_network(self, mx_context):
pass
......@@ -205,7 +222,6 @@ class LargeMemory(gluon.HybridBlock):
sub_key_size,
query_size,
query_act,
dist_measure,
k,
num_heads,
values_dim,
......@@ -213,7 +229,6 @@ class LargeMemory(gluon.HybridBlock):
super(LargeMemory, self).__init__(**kwargs)
with self.name_scope():
#Memory parameters
self.dist_measure = dist_measure
self.k = k
self.num_heads = num_heads
self.query_act = query_act
......@@ -250,46 +265,25 @@ class LargeMemory(gluon.HybridBlock):
q_split = F.split(q, num_outputs=2, axis=-1)
if self.dist_measure == "l2":
q_split_resh = F.reshape(q_split[0], shape=(0,0,1,-1))
sub_keys1_resh = F.reshape(sub_keys1, shape=(1,0,0,-1), reverse=True)
q1_diff = F.broadcast_sub(q_split_resh, sub_keys1_resh)
q1_dist = F.norm(q1_diff, axis=-1)
q_split_resh = F.reshape(q_split[1], shape=(0,0,1,-1))
sub_keys2_resh = F.reshape(sub_keys2, shape=(1,0,0,-1), reverse=True)
q2_diff = F.broadcast_sub(q_split_resh, sub_keys2_resh)
q2_dist = F.norm(q2_diff, axis=-1)
else:
q1 = F.split(q_split[0], num_outputs=self.num_heads, axis=1)
q2 = F.split(q_split[1], num_outputs=self.num_heads, axis=1)
sub_keys1_resh = F.split(sub_keys1, num_outputs=self.num_heads, axis=0, squeeze_axis=True)
sub_keys2_resh = F.split(sub_keys2, num_outputs=self.num_heads, axis=0, squeeze_axis=True)
if self.num_heads == 1:
q1 = [q1]
q2 = [q2]
sub_keys1_resh = [sub_keys1_resh ]
sub_keys2_resh = [sub_keys2_resh ]
q1_dist = F.dot(q1[0], sub_keys1_resh[0], transpose_b=True)
q2_dist = F.dot(q2[0], sub_keys2_resh[0], transpose_b=True)
for h in range(1, self.num_heads):
q1_dist = F.concat(q1_dist, F.dot(q1[0], sub_keys1_resh[h], transpose_b=True), dim=1)
q2_dist = F.concat(q2_dist, F.dot(q2[0], sub_keys1_resh[h], transpose_b=True), dim=1)
q1 = F.split(q_split[0], num_outputs=self.num_heads, axis=1)
q2 = F.split(q_split[1], num_outputs=self.num_heads, axis=1)
sub_keys1_resh = F.split(sub_keys1, num_outputs=self.num_heads, axis=0, squeeze_axis=True)
sub_keys2_resh = F.split(sub_keys2, num_outputs=self.num_heads, axis=0, squeeze_axis=True)
if self.num_heads == 1:
q1 = [q1]
q2 = [q2]
sub_keys1_resh = [sub_keys1_resh ]
sub_keys2_resh = [sub_keys2_resh ]
q1_dist = F.dot(q1[0], sub_keys1_resh[0], transpose_b=True)
q2_dist = F.dot(q2[0], sub_keys2_resh[0], transpose_b=True)
for h in range(1, self.num_heads):
q1_dist = F.concat(q1_dist, F.dot(q1[0], sub_keys1_resh[h], transpose_b=True), dim=1)
q2_dist = F.concat(q2_dist, F.dot(q2[0], sub_keys1_resh[h], transpose_b=True), dim=1)
i1 = F.topk(q1_dist, k=self.k, ret_typ="indices")
i2 = F.topk(q2_dist, k=self.k, ret_typ="indices")
# Calculate cross product for keys at indices I1 and I2
# def head_take(data, state):
# return [F.take(data[0], data[2]), F.take(data[1], data[3])], state,
#
# i1 = F.transpose(i1, axes=(1,0,2))
# i2 = F.transpose(i2, axes=(1, 0, 2))
# st = F.zeros(1)
# (k1, k2), _ = F.contrib.foreach(head_take, [sub_keys1, sub_keys2,i1,i2], st)
# k1 = F.reshape(k1, shape=(-1, 0, 0), reverse=True)
# k2 = F.reshape(k2, shape=(-1, 0, 0), reverse=True)
i1 = F.split(i1, num_outputs=self.num_heads, axis=1)
i2 = F.split(i2, num_outputs=self.num_heads, axis=1)
sub_keys1 = F.split(sub_keys1, num_outputs=self.num_heads, axis=0, squeeze_axis=True)
......@@ -313,12 +307,9 @@ class LargeMemory(gluon.HybridBlock):
q = F.reshape(q, shape=(-1,0), reverse=True)
q = F.reshape(q, shape=(0, 1, -1))
c_cart = F.reshape(c_cart, shape=(-1, 0, 0), reverse=True)
if self.dist_measure == "l2":
k_diff = F.broadcast_sub(q, c_cart)
k_dist = F.norm(k_diff, axis=-1)
else:
k_dist = F.batch_dot(q, c_cart, transpose_b=True) #F.contrib.foreach(loop_batch_dot, [q, c_cart], init_states=state_batch_dist)
k_dist = F.reshape(k_dist, shape=(0, -1))
k_dist = F.batch_dot(q, c_cart, transpose_b=True) #F.contrib.foreach(loop_batch_dot, [q, c_cart], init_states=state_batch_dist)
k_dist = F.reshape(k_dist, shape=(0, -1))
i = F.topk(k_dist, k=self.k, ret_typ="both")
......@@ -359,11 +350,14 @@ class EpisodicMemory(EpisodicReplayMemoryInterface):
max_stored_samples,
memory_replacement_strategy,
use_replay,
use_local_adaptation,
local_adaptation_gradient_steps,
k,
query_net_dir,
query_net_prefix,
query_net_num_inputs,
**kwargs):
super(EpisodicMemory, self).__init__(use_replay, replay_interval, replay_batch_size, replay_steps, replay_gradient_steps, 1, **kwargs)
super(EpisodicMemory, self).__init__(use_replay, replay_interval, replay_batch_size, replay_steps, replay_gradient_steps, use_local_adaptation, local_adaptation_gradient_steps, k, **kwargs)
with self.name_scope():
#Replay parameters
self.store_prob = store_prob
......@@ -458,6 +452,29 @@ class EpisodicMemory(EpisodicReplayMemoryInterface):
return sample_batches
def sample_neighbours(self, data, query_network):
num_stored_samples = self.key_memory.shape[0]
batch_size = data[0].shape[0]
query = query_network(*data).as_in_context(mx.cpu())
vec1 = nd.repeat(query, repeats=num_stored_samples, axis=0)
vec2 = nd.tile(self.key_memory, reps=(batch_size, 1))
diff = nd.subtract(vec1, vec2)
sq = nd.square(diff)
batch_sum = nd.sum(sq, exclude=1, axis=0)
sqrt = nd.sqrt(batch_sum)
dist = nd.reshape(sqrt, shape=(batch_size, num_stored_samples))
sample_ind = nd.topk(dist, k=self.k, axis=1, ret_typ="indices")
num_outputs = len(self.label_memory)
sample_labels = [self.label_memory[i][sample_ind] for i in range(num_outputs)]
sample_batches = [[self.value_memory[j][sample_ind] for j in range(len(self.value_memory))], sample_labels]
return sample_batches
def get_query_network(self, context):
lastEpoch = 0
for file in os.listdir(self.query_net_dir):
......
......@@ -110,6 +110,37 @@ class SoftmaxCrossEntropyLossIgnoreLabel(gluon.loss.Loss):
loss = gluon.loss._apply_weighting(F, loss, self._weight, sample_weight)
return F.sum(loss) / F.sum(valid_label_map)
class LocalAdaptationLoss(gluon.loss.Loss):
def __init__(self, lamb, axis=-1, sparse_label=True, weight=None, batch_axis=0, **kwargs):
super(LocalAdaptationLoss, self).__init__(weight, batch_axis, **kwargs)
self.lamb = lamb
self._axis = axis
self._sparse_label = sparse_label
def hybrid_forward(self, F, pred, label, curr_weights, base_weights, sample_weight=None):
pred = F.log(pred)
if self._sparse_label:
cross_entr_loss = -F.pick(pred, label, axis=self._axis, keepdims=True)
else:
label = gluon.loss._reshape_like(F, label, pred)
cross_entr_loss = -F.sum(pred * label, axis=