clean up

parent 5bee43c5
Pipeline #186559 failed with stages
in 20 seconds
This diff is collapsed.
This diff is collapsed.
......@@ -158,6 +158,30 @@ public class GenerationTest extends AbstractSymtabTest {
"CNNTrainer_mnist_mnistClassifier_net.py"));
}
@Test
public void testMnistClassifierForTensorflow() throws IOException, TemplateException {
Log.getFindings().clear();
String[] args = {"-m", "src/test/resources/models/", "-r", "mnist.MnistClassifier", "-b", "TENSORFLOW", "-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/tensorflow"),
Arrays.asList(
"mnist_mnistClassifier.cpp",
"mnist_mnistClassifier.h",
"CNNCreator_mnist_mnistClassifier_net.py",
"CNNPredictor_mnist_mnistClassifier_net.h",
"CNNDataLoader_mnist_mnistClassifier_net.py",
"mnist_mnistClassifier_net.h",
"HelperA.h",
"CNNTranslator.h",
"mnist_mnistClassifier_calculateClass.h",
"CNNTrainer_mnist_mnistClassifier_net.py",
"mnist_mnistClassifier_net.h"));
}
@Test
public void testMnistClassifierForGluon() throws IOException, TemplateException {
Log.getFindings().clear();
......@@ -184,7 +208,7 @@ public class GenerationTest extends AbstractSymtabTest {
"CNNTrainer_mnist_mnistClassifier_net.py",
"mnist_mnistClassifier_net.h"));
}
@Test
public void testInvariantForGluon() throws IOException, TemplateException {
Log.getFindings().clear();
......
/**
*
* ******************************************************************************
* MontiCAR Modeling Family, www.se-rwth.de
* Copyright (c) 2017, Software Engineering Group at RWTH Aachen,
* All rights reserved.
*
* This project is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this project. If not, see <http://www.gnu.org/licenses/>.
* *******************************************************************************
*/
package de.monticore.lang.monticar.emadl;
import de.monticore.lang.monticar.emadl.generator.EMADLGeneratorCli;
import de.se_rwth.commons.logging.Log;
import org.junit.Ignore;
import org.junit.Test;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertFalse;
public class IntegrationTensorflowTest extends IntegrationTest {
private Path multipleStreamsHashFile = Paths.get("./target/generated-sources-emadl/MultipleStreams.training_hash");
public IntegrationTensorflowTest() {
super("TENSORFLOW", "39253EC049D4A4E5FA0536AD34874B9D#1DBAEE1B1BD83FB7CB5F70AE91B29638#C4C23549E737A759721D6694C75D9771#5AF0CE68E408E8C1F000E49D72AC214A");
}
@Test
public void testMultipleStreams() {
Log.getFindings().clear();
deleteHashFile(multipleStreamsHashFile);
String[] args = {"-m", "src/test/resources/models/", "-r", "MultipleStreams", "-b", "TENSORFLOW"};
EMADLGeneratorCli.main(args);
assertTrue(Log.getFindings().isEmpty());
}
private void deleteHashFile(Path hashFile) {
try {
Files.delete(hashFile);
}
catch (NoSuchFileException e) {
}
catch(Exception e) {
assertFalse("Could not delete hash file", true);
}
}
}
......@@ -4,8 +4,8 @@ component MultipleStreams{
implementation CNN {
data[0] ->
Convolution(kernel=(5,5), channels=8, padding="valid") ->
Convolution(kernel=(5,5), channels=8, padding="valid") ->
Convolution(kernel=(5,5), channels=8) ->
Convolution(kernel=(5,5), channels=8) ->
FullyConnected(units=128) ->
Dropout()->
FullyConnected(units=10) ->
......@@ -13,8 +13,8 @@ component MultipleStreams{
softmax[0];
data[1] ->
Convolution(kernel=(5,5), channels=8, padding="valid") ->
Convolution(kernel=(5,5), channels=8, padding="valid") ->
Convolution(kernel=(5,5), channels=8) ->
Convolution(kernel=(5,5), channels=8) ->
FullyConnected(units=128) ->
Dropout()->
FullyConnected(units=10) ->
......
......@@ -6,10 +6,10 @@ component Network{
implementation CNN {
image ->
Convolution(kernel=(5,5), channels=20, padding="valid") ->
Pooling(pool_type="max", kernel=(2,2), stride=(2,2), padding="valid") ->
Convolution(kernel=(5,5), channels=50, padding="valid") ->
Pooling(pool_type="max", kernel=(2,2), stride=(2,2), padding="valid") ->
Convolution(kernel=(5,5), channels=20) ->
Pooling(pool_type="max", kernel=(2,2), stride=(2,2)) ->
Convolution(kernel=(5,5), channels=50) ->
Pooling(pool_type="max", kernel=(2,2), stride=(2,2)) ->
FullyConnected(units=500) ->
Relu() ->
FullyConnected(units=10) ->
......
......@@ -6,8 +6,8 @@ component CifarNetwork<Z(2:oo) classes = 10>{
implementation CNN {
data ->
Convolution(kernel=(5,5), channels=8, padding="valid") ->
Convolution(kernel=(5,5), channels=8, padding="valid") ->
Convolution(kernel=(5,5), channels=8) ->
Convolution(kernel=(5,5), channels=8) ->
FullyConnected(units=128) ->
Dropout()->
FullyConnected(units=classes) ->
......
......@@ -6,10 +6,10 @@ component LeNetNetwork<Z(2:oo) classes = 10>{
implementation CNN {
image ->
Convolution(kernel=(5,5), channels=20, padding="valid") ->
Pooling(pool_type="max", kernel=(2,2), stride=(2,2), padding="valid") ->
Convolution(kernel=(5,5), channels=50, padding="valid") ->
Pooling(pool_type="max", kernel=(2,2), stride=(2,2), padding="valid") ->
Convolution(kernel=(5,5), channels=20) ->
Pooling(pool_type="max", kernel=(2,2), stride=(2,2)) ->
Convolution(kernel=(5,5), channels=50) ->
Pooling(pool_type="max", kernel=(2,2), stride=(2,2)) ->
FullyConnected(units=500) ->
Relu() ->
FullyConnected(units=classes) ->
......
......@@ -6,8 +6,8 @@ component CifarNetwork<Z(2:oo) classes = 10>{
implementation CNN {
data ->
Convolution(kernel=(5,5), channels=8, padding="valid") ->
Convolution(kernel=(5,5), channels=8, padding="valid") ->
Convolution(kernel=(5,5), channels=8) ->
Convolution(kernel=(5,5), channels=8) ->
FullyConnected(units=128) ->
Dropout()->
FullyConnected(units=classes) ->
......
......@@ -74,15 +74,15 @@ class CNNCreator_mnist_mnistClassifier_net:
image_ = data
# image_, output shape: {[1,28,28]}
conv1_ = brew.conv(model, image_, 'conv1_', dim_in=1, dim_out=20, kernel=5, stride=1)
# conv1_, output shape: {[20,24,24]}
pool1_ = brew.max_pool(model, conv1_, 'pool1_', kernel=2, stride=2)
# pool1_, output shape: {[20,12,12]}
conv2_ = brew.conv(model, pool1_, 'conv2_', dim_in=20, dim_out=50, kernel=5, stride=1)
# conv2_, output shape: {[50,8,8]}
pool2_ = brew.max_pool(model, conv2_, 'pool2_', kernel=2, stride=2)
# pool2_, output shape: {[50,4,4]}
fc2_ = brew.fc(model, pool2_, 'fc2_', dim_in=50 * 4 * 4, dim_out=500)
conv1_ = brew.conv(model, image_, 'conv1_', dim_in=1, dim_out=20, kernel=5, stride=1, pad=1)
# conv1_, output shape: {[20,28,28]}
pool1_ = brew.max_pool(model, conv1_, 'pool1_', kernel=2, stride=2, pad=1)
# pool1_, output shape: {[20,14,14]}
conv2_ = brew.conv(model, pool1_, 'conv2_', dim_in=20, dim_out=50, kernel=5, stride=1, pad=1)
# conv2_, output shape: {[50,14,14]}
pool2_ = brew.max_pool(model, conv2_, 'pool2_', kernel=2, stride=2, pad=1)
# pool2_, output shape: {[50,7,7]}
fc2_ = brew.fc(model, pool2_, 'fc2_', dim_in=50 * 7 * 7, dim_out=500)
# fc2_, output shape: {[500,1,1]}
relu2_ = brew.relu(model, fc2_, fc2_)
fc3_ = brew.fc(model, relu2_, 'fc3_', dim_in=500, dim_out=10)
......
......@@ -90,27 +90,29 @@ class Net_0(gluon.HybridBlock):
else:
self.input_normalization_image_ = NoNormalization()
self.conv1_padding = Padding(padding=(0,0,0,0,2,2,2,2))
self.conv1_ = gluon.nn.Conv2D(channels=20,
kernel_size=(5,5),
strides=(1,1),
use_bias=True)
# conv1_, output shape: {[20,24,24]}
# conv1_, output shape: {[20,28,28]}
self.pool1_ = gluon.nn.MaxPool2D(
pool_size=(2,2),
strides=(2,2))
# pool1_, output shape: {[20,12,12]}
# pool1_, output shape: {[20,14,14]}
self.conv2_padding = Padding(padding=(0,0,0,0,2,2,2,2))
self.conv2_ = gluon.nn.Conv2D(channels=50,
kernel_size=(5,5),
strides=(1,1),
use_bias=True)
# conv2_, output shape: {[50,8,8]}
# conv2_, output shape: {[50,14,14]}
self.pool2_ = gluon.nn.MaxPool2D(
pool_size=(2,2),
strides=(2,2))
# pool2_, output shape: {[50,4,4]}
# pool2_, output shape: {[50,7,7]}
self.fc2_ = gluon.nn.Dense(units=500, use_bias=True, flatten=True)
# fc2_, output shape: {[500,1,1]}
......@@ -124,9 +126,11 @@ class Net_0(gluon.HybridBlock):
def hybrid_forward(self, F, image_):
image_ = self.input_normalization_image_(image_)
conv1_ = self.conv1_(image_)
conv1_padding = self.conv1_padding(image_)
conv1_ = self.conv1_(conv1_padding)
pool1_ = self.pool1_(conv1_)
conv2_ = self.conv2_(pool1_)
conv2_padding = self.conv2_padding(pool1_)
conv2_ = self.conv2_(conv2_padding)
pool2_ = self.pool2_(conv2_)
fc2_ = self.fc2_(pool2_)
relu2_ = self.relu2_(fc2_)
......
import logging
import os
import h5py
import sys
import numpy as np
class CNNDataLoader_mnist_mnistClassifier_net:
def __init__(self, data_dir, input_names, output_names, output_shapes):
self._data_dir_ = data_dir
self._input_names_ = input_names
self._output_names_ = output_names
self._output_shapes_ = output_shapes
def load_data_generators(self, batch_size, normalize):
train_h5, test_h5 = self.load_h5_files()
train_generator = self._generator(train_h5, batch_size)
test_generator = self._generator(test_h5, batch_size)
if normalize:
data_mean, data_std = self._get_mean_std(train_h5)
else:
data_mean, data_std = 0,1
data_size = train_h5[self._input_names_[0]].shape[0]
steps_per_epoch = data_size//batch_size
data_size = test_h5[self._input_names_[0]].shape[0]
validation_steps = data_size//batch_size
if validation_steps == 0 and data_size > 0:
validation_steps = data_size
elif data_size == 0:
raise Exception("Test data set is empty. \n")
return train_generator, test_generator, data_mean, data_std, steps_per_epoch, validation_steps
def _generator(self, h5_container, batch_size):
#all tables in the file have to have same number of samples
data_size = h5_container[self._input_names_[0]].shape[0]
for shape in self._output_shapes_:
if len(shape) == 3:
logging.warning("Outputs with 3 dimensions will be interpreted as having a channel diemnsion. Outputs, as inputs are expecte to be passed in channel first format, but internally internally tensorlow needs channel last format, therfore there will be a permutation of the channel of the learned / predicted target to channel first.\n\n")
break
while(True):
for i in range(0, data_size, batch_size):
if i+batch_size < data_size:
offset = batch_size
else:
offset = data_size - i - 1
data_batch = [h5_container[key][i:i+offset].astype(np.float32) for key in self._input_names_]
target_batch = [h5_container[key][i:i+offset].astype(np.float32) for key in self._output_names_]
yield (data_batch, target_batch)
def _get_mean_std(self, h5_container):
input_means = []
input_stds = []
if "statistics" in h5_container.keys():
logging.info("Statistics found.")
data = h5_container["statistics"]
input_means = {key: data[key+"_mean"] for key in self._input_names_}
input_stds = {key: data[key+"_std"] for key in self._input_names_}
else:
logging.info("Statistics NOT found.")
logging.info("Calculating statistics...")
data_size = h5_container[self._input_names_[0]].shape[0]
logging.info("Calculating statistics for " + str(len(self._input_names_)) + " inputs, " + str(len(self._output_names_)) + " outputs, " + str(data_size) + " data points...")
batch_size = 100
#Calculating means...
logging.info("Calculating means... ")
input_means_running = {key: 0. for key in self._input_names_}
for i in range(0, data_size, batch_size):
if i+batch_size < data_size:
offset = batch_size
else:
offset = data_size - i - 1
for key in self._input_names_:
input_means_running[key] += np.mean(h5_container[key][i:i+offset].astype(np.float32))*(offset/float(batch_size))
input_means = {key: (input_means_running[key] / (data_size//batch_size + offset/float(batch_size))) for key in self._input_names_}
logging.info("Done calculating means!")
logging.info("Input means: " + str(input_means) + "\n\n")
#Calculating stds...
logging.info("Calculating stds...")
input_stds_running = {key: 0. for key in self._input_names_}
for i in range(0, data_size, batch_size):
if i+batch_size < data_size:
offset = batch_size
else:
offset = data_size - i - 1
for key in self._input_names_:
input_stds_running[key] += np.mean((h5_container[key][i:i+offset].astype(np.float32) - input_means[key])**2)*(offset/float(batch_size))
std_eps = 1e-08
input_stds = {key: np.sqrt(input_stds_running[key] / (data_size//batch_size + offset/float(batch_size)) + std_eps) for key in self._input_names_}
logging.info("Done calculating stds!")
logging.info("Input stds: " + str(input_stds) + "\n\n")
return input_means, input_stds
def load_h5_files(self):
train_h5 = None
test_h5 = None
train_path = self._data_dir_ + "train.h5"
test_path = self._data_dir_ + "test.h5"
if os.path.isfile(train_path):
train_h5 = h5py.File(train_path, 'r')
if not (self._input_names_[0] in train_h5 and self._output_names_[0] in train_h5):
logging.error("The HDF5 file '" + os.path.abspath(train_path) + "' has to contain the datasets: "
+ "'" + str(self._input_names_) + "', '" + str(self._output_names_) + "'")
sys.exit(1)
if os.path.isfile(test_path):
test_h5 = h5py.File(test_path, 'r')
if not (self._input_names_[0] in test_h5 and self._output_names_[0] in test_h5):
logging.error("The HDF5 file '" + os.path.abspath(test_path) + "' has to contain the datasets: "
+ "'" + str(self._input_names_) + "', '" + str(self._output_names_) + "'")
sys.exit(1)
else:
logging.warning("Couldn't load test set. File '" + os.path.abspath(test_path) + "' does not exist.")
return train_h5, test_h5
else:
logging.error("Data loading failure. File '" + os.path.abspath(train_path) + "' does not exist.")
sys.exit(1)
\ No newline at end of file
#ifndef CNNPREDICTOR_MNIST_MNISTCLASSIFIER_NET
#define CNNPREDICTOR_MNIST_MNISTCLASSIFIER_NET
#include <tensorflow/core/public/session.h>
#include <tensorflow/core/protobuf/meta_graph.pb.h>
#include <cassert>
#include <string>
#include <vector>
class CNNPredictor_mnist_mnistClassifier_net_0{
public:
const std::string graph_file = "model/mnist.LeNetNetwork/model_cpp_pred.meta";
const std::string param_prefix = "model/mnist.LeNetNetwork/model_cpp_pred";
tensorflow::Session* session;
explicit CNNPredictor_mnist_mnistClassifier_net_0(){
init(graph_file, param_prefix);
}
void predict(const std::vector<float> &image_,
std::vector<float> &predictions_){
std::vector<std::string> inputKeys = {"image_"};
std::vector<std::vector<float>> inputShapes = {{1,1,28,28}};
std::vector<tensorflow::TensorShape> inputShapesTensor = {tensorflow::TensorShape({1,1,28,28})};
std::vector<std::vector<float>> inputs = {image_};
std::vector<std::pair<std::string, tensorflow::Tensor>> inputTensors;
for(int i=0; i<inputShapes.size(); i++){
tensorflow::Tensor tempInputTensor = tensorflow::Tensor(tensorflow::DT_FLOAT, inputShapesTensor[i]);
int numElems = inputShapes[i][0];
for(int j=1; j<inputShapes[i].size(); j++){
numElems *= inputShapes[i][j];
}
tensorflow::StringPiece tmpData = tempInputTensor.tensor_data();
memcpy(const_cast<char*>(tmpData.data()), inputs[i].data(), numElems * sizeof(float));
inputTensors.push_back({inputKeys[i], tempInputTensor});
}
std::vector<std::string> outputKeys = {"output_0"};
std::vector<tensorflow::Tensor> outputTensor;
TF_CHECK_OK(session->Run(inputTensors, outputKeys, {}, &outputTensor));
std::vector<std::vector<float>*> outputs = {&predictions_};
for(int i=0; i < outputs.size(); i++){
int flatOutSize = outputTensor[i].dim_size(0);
for(int j=1; j < outputTensor[i].shape().dims(); j++){
flatOutSize *= outputTensor[i].dim_size(j);
}
std::vector<float> currOutput;
for (int j=0; j < flatOutSize; j++){
currOutput.push_back(outputTensor[i].flat<float>()(j));
}
*(outputs[i]) = currOutput;
}
}
void init(const std::string &graph_file,
const std::string &param_prefix){
session = tensorflow::NewSession(tensorflow::SessionOptions());
if (session == nullptr) {
throw std::runtime_error("Could not create Tensorflow session.");
}
tensorflow::Status status;
tensorflow::MetaGraphDef graph;
status = tensorflow::ReadBinaryProto(tensorflow::Env::Default(), graph_file, &graph);
if (!status.ok()) {
throw std::runtime_error("Error reading graph from " + graph_file + ": " + status.ToString());
}
status = session->Create(graph.graph_def());
if (!status.ok()) {
throw std::runtime_error("Error adding graph to session: " + status.ToString());
}
tensorflow::Tensor pramPrefixTensor(tensorflow::DT_STRING, tensorflow::TensorShape());
pramPrefixTensor.scalar<std::string>()() = param_prefix;
status = session->Run({{ graph.saver_def().filename_tensor_name(), pramPrefixTensor },}, {}, {graph.saver_def().restore_op_name()}, nullptr);
if (!status.ok()) {
throw std::runtime_error("Error loading weights from checkpoint:" + param_prefix + ": " + status.ToString());
}
}
};
//For the tensorflow backend we need only one class for all streams, but the generated files require one for every stream, so dummy classes are generated here
#endif // CNNPREDICTOR_MNIST_MNISTCLASSIFIER_NET
import logging
import CNNCreator_mnist_mnistClassifier_net
if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger()
handler = logging.FileHandler("train.log", "w", encoding=None, delay="true")
logger.addHandler(handler)
mnist_mnistClassifier_net = CNNCreator_mnist_mnistClassifier_net.CNNCreator_mnist_mnistClassifier_net()
mnist_mnistClassifier_net.train(
batch_size=64,
num_epoch=11,
context='gpu',
eval_metric='accuracy',
optimizer='adam',
optimizer_params={
'epsilon': 1.0E-8,
'weight_decay': 0.001,
'beta1': 0.9,
'beta2': 0.999,
'learning_rate_policy': 'fixed',
'learning_rate': 0.001}
)
#ifndef CNNTRANSLATOR_H
#define CNNTRANSLATOR_H
#include <armadillo>
#include <cassert>
using namespace std;
using namespace arma;
class CNNTranslator{
public:
template<typename T> static void addColToSTDVector(const Col<T> &source, vector<float> &data){
for(size_t i = 0; i < source.n_elem; i++){
data.push_back((float) source(i));
}
}
template<typename T> static void addRowToSTDVector(const subview_row<T> &source, vector<float> &data){
for(size_t i = 0; i < source.n_elem; i++){
data.push_back((float) source(i));
}
}
template<typename T> static void addRowToSTDVector(const Row<T> &source, vector<float> &data){
for(size_t i = 0; i < source.n_elem; i++){
data.push_back((float) source(i));
}
}
template<typename T> static void addMatToSTDVector(const Mat<T> &source, vector<float> &data){
for(size_t i = 0; i < source.n_rows; i++){
addRowToSTDVector(source.row(i), data);
}
}
template<typename T> static vector<float> translate(const Col<T> &source){
size_t size = source.n_elem;
vector<float> data;
data.reserve(size);
addColToSTDVector(source, data);
return data;
}
template<typename T> static vector<float> translate(const Row<T> &source){