Merge with master works

Signed-off-by:  Micaela Verucchi <micaelaverucchi@gmail.com>
		Davide Sapienza <sapienza.dav@gmail.com>
This commit is contained in:
Micaela Verucchi
2020-04-08 14:59:42 +02:00
16 changed files with 948 additions and 190 deletions
+143
View File
@@ -0,0 +1,143 @@
#include <iostream>
#include <signal.h>
#include <stdlib.h> /* srand, rand */
#include <unistd.h>
#include <mutex>
#include <Eigen/Dense>
#include "utils.h"
#include "tkdnn.h"
namespace tk { namespace dnn {
/**
*
* @author Francesco Gatti
*/
class ImuOdom {
public:
tk::dnn::Network *net = nullptr;
// Network input dim
tk::dnn::dataDim_t dim0;
tk::dnn::dataDim_t dim1;
tk::dnn::dataDim_t dim2;
// Network output dim
tk::dnn::dataDim_t odim0;
tk::dnn::dataDim_t odim1;
// input pointers
dnnType *i0_d, *i1_d, *i2_d;
// output pointers
dnnType *o0_d, *o1_d;
// output eigen CPU
Eigen::MatrixXf deltaP, deltaQ;
Eigen::MatrixXd odomPOS, odomROT;
Eigen::Isometry3f tf = Eigen::Isometry3f::Identity();
ImuOdom() {}
virtual ~ImuOdom() {}
/**
* Method used for inizialize the class
*
* @return Success of the initialization
*/
bool init(std::string layers_path) {
dim0 = tk::dnn::dataDim_t(1, 4, 1, 100);
dim1 = tk::dnn::dataDim_t(1, 3, 1, 100);
dim2 = tk::dnn::dataDim_t(1, 3, 1, 100);
checkCuda( cudaMalloc(&i0_d, dim0.tot()*sizeof(dnnType)) );
checkCuda( cudaMalloc(&i1_d, dim1.tot()*sizeof(dnnType)) );
checkCuda( cudaMalloc(&i2_d, dim2.tot()*sizeof(dnnType)) );
std::string c0_bin = layers_path + "/conv1d_7.bin";
std::string c1_bin = layers_path + "/conv1d_8.bin";
std::string c2_bin = layers_path + "/conv1d_9.bin";
std::string c3_bin = layers_path + "/conv1d_10.bin";
std::string c4_bin = layers_path + "/conv1d_11.bin";
std::string c5_bin = layers_path + "/conv1d_12.bin";
std::string l0_bin = layers_path + "/bidirectional_3.bin";
std::string l1_bin = layers_path + "/bidirectional_4.bin";
std::string d0_bin = layers_path + "/dense_3.bin";
std::string d1_bin = layers_path + "/dense_4.bin";
net = new tk::dnn::Network(dim0);
tk::dnn::Input *x0 = new tk::dnn::Input (net, dim0, i0_d);
tk::dnn::Conv2d *x0_0 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c0_bin);
tk::dnn::Conv2d *x0_1 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c1_bin);
tk::dnn::Pooling *x0_2 = new tk::dnn::Pooling(net, 1, 3, 1, 3, tk::dnn::tkdnnPoolingMode_t::POOLING_MAX);
tk::dnn::Input *x1 = new tk::dnn::Input (net, dim1, i1_d);
tk::dnn::Conv2d *x1_0 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c2_bin);
tk::dnn::Conv2d *x1_1 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c3_bin);
tk::dnn::Pooling *x1_2 = new tk::dnn::Pooling(net, 1, 3, 1, 3, tk::dnn::tkdnnPoolingMode_t::POOLING_MAX);
tk::dnn::Input *x2 = new tk::dnn::Input (net, dim2, i2_d);
tk::dnn::Conv2d *x2_0 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c4_bin);
tk::dnn::Conv2d *x2_1 = new tk::dnn::Conv2d (net, 128, 1, 11, 1, 1, 0, 0, c5_bin);
tk::dnn::Pooling *x2_2 = new tk::dnn::Pooling(net, 1, 3, 1, 3, tk::dnn::tkdnnPoolingMode_t::POOLING_MAX);
tk::dnn::Layer *concat_l[3] = { x0_2, x1_2, x2_2 };
tk::dnn::Route *concat = new tk::dnn::Route(net, concat_l, 3);
tk::dnn::LSTM *lstm0 = new tk::dnn::LSTM(net, 128, true, l0_bin);
tk::dnn::LSTM *lstm1 = new tk::dnn::LSTM(net, 128, false, l1_bin);
tk::dnn::Dense *d0 = new tk::dnn::Dense(net, 3, d0_bin);
tk::dnn::Layer *lstm1_l[1] = { lstm1 };
tk::dnn::Route *lstm1_link = new tk::dnn::Route(net, lstm1_l, 1);
tk::dnn::Dense *d1 = new tk::dnn::Dense(net, 4, d1_bin);
net->print();
// output data
o0_d = d0->dstData;
o1_d = d1->dstData;
odim0 = d0->output_dim;
odim1 = d1->output_dim;
deltaP.resize(odim0.tot(), 1);
deltaQ.resize(odim1.tot(), 1);
odomPOS = Eigen::MatrixXd::Zero(3, 1);
odomROT = Eigen::MatrixXd::Identity(3, 3);
}
void update(dnnType *x0, dnnType *x1, dnnType *x2) {
checkCuda( cudaMemcpy(i0_d, x0, dim0.tot()*sizeof(dnnType), cudaMemcpyHostToDevice) );
checkCuda( cudaMemcpy(i1_d, x1, dim1.tot()*sizeof(dnnType), cudaMemcpyHostToDevice) );
checkCuda( cudaMemcpy(i2_d, x2, dim2.tot()*sizeof(dnnType), cudaMemcpyHostToDevice) );
// Inference
tk::dnn::dataDim_t dim;
net->infer(dim, nullptr);
checkCuda( cudaMemcpy(deltaP.data(), o0_d, odim0.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) );
checkCuda( cudaMemcpy(deltaQ.data(), o1_d, odim1.tot()*sizeof(dnnType), cudaMemcpyDeviceToHost) );
// compute odom
Eigen::Quaterniond q;
q.w() = deltaQ(0);
q.x() = deltaQ(1);
q.y() = deltaQ(2);
q.z() = deltaQ(3);
odomPOS = odomPOS + odomROT*deltaP.cast<double>();
odomROT = odomROT * q.normalized().toRotationMatrix();
// compose tf
tf.matrix().block(0, 0, 3, 3) = odomROT.cast<float>();
tf.matrix().block(0, 3, 3, 1) = odomPOS.cast<float>();
}
};
}}
+101 -2
View File
@@ -9,10 +9,12 @@
namespace tk { namespace dnn {
enum layerType_t {
LAYER_INPUT,
LAYER_DENSE,
LAYER_CONV2D,
LAYER_DECONV2D,
LAYER_DEFORMCONV2D,
LAYER_LSTM,
LAYER_ACTIVATION,
LAYER_ACTIVATION_CRELU,
LAYER_ACTIVATION_LEAKY,
@@ -55,10 +57,12 @@ public:
std::string getLayerName() {
layerType_t type = getLayerType();
switch(type) {
case LAYER_INPUT: return "Input";
case LAYER_DENSE: return "Dense";
case LAYER_CONV2D: return "Conv2d";
case LAYER_DECONV2D: return "DeConv2d";
case LAYER_DEFORMCONV2D: return "DeformConv2d";
case LAYER_LSTM: return "LSTM";
case LAYER_ACTIVATION: return "Activation";
case LAYER_ACTIVATION_CRELU: return "ActivationCReLU";
case LAYER_ACTIVATION_LEAKY: return "ActivationLeaky";
@@ -123,6 +127,28 @@ public:
};
/**
Input layer (it doesnt need weigths)
*/
class Input : public Layer {
public:
Input(Network *net, dataDim_t &dim, dnnType* srcData) : Layer(net) {
input_dim = dim;
output_dim = dim;
dstData = srcData;
}
virtual ~Input() {}
virtual layerType_t getLayerType() { return LAYER_INPUT; };
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData) {
dim = output_dim;
return dstData;
}
};
/**
Dense (full interconnection) layer
*/
@@ -174,6 +200,14 @@ protected:
/**
Convolutional 2D layer
WEIGHTS shape: OUTCH, INCH, KH, KW ...
BIAS shape: OUTCH
with BATCHNORM:
scales: OUTCH
means: OUTCH
variance: OUTCH
*/
class Conv2d : public LayerWgs {
@@ -203,6 +237,71 @@ protected:
size_t ws_sizeInBytes;
};
/**
Bidirectional LSTM layer
ONLY BIDIRECTIONAL (TODO: more configurable)
currently implemented as 2 inferences: forward and backward (TODO: only 1 cudnn inference)
implementation info:
https://github.com/jiangnanhugo/seq2seq_cuda/blob/e4dbdcfa0517c972bfd4beea9f11a5233954093c/src/rnn.cpp
https://github.com/Jeffery-Song/mxnet-test/blob/aab666faad44011f7a67b527b5f6c960367d0422/src/operator/cudnn_rnn-inl.h
https://stackoverflow.com/a/38737941
https://colah.github.io/posts/2015-08-Understanding-LSTMs/
PARAMS (numlayers*2):
layer0:
( INCH, ? ) ???
( HIDDEN, ? ) ???
( HIDDEN * 8 ) ???
layer2:
( INCH, ? ) ???
( HIDDEN, ? ) ???
( HIDDEN * 8 ) ???
OUTPUT shape:
(N, C, 1, W) ---> LSTM(HIDDEN, returnSeq=True) ---> (N, 2*HIDDEN, 1, W) # W is seqLength
(N, C, 1, W) ---> LSTM(HIDDEN, returnSeq=False) ---> (N, 2*HIDDEN, 1, 1)
*/
class LSTM : public Layer {
public:
LSTM(Network *net, int hiddensize, bool returnSeq, std::string fname_weights);
virtual ~LSTM();
virtual layerType_t getLayerType() { return LAYER_LSTM; };
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
const bool bidirectional = true; /**> is the net bidir */
bool returnSeq = false; /**> if false return only the result of last timestep */
int stateSize = 0; /**> number of hidden states */
int seqLen = 0; /**> number of timesteps */
int numLayers = 1; /**> number of internal layers */
protected:
cudnnRNNDescriptor_t rnnDesc;
cudnnDropoutDescriptor_t dropoutDesc;
dnnType *dropout_states_, *work_space_;
size_t workspace_byte_, dropout_byte_;
int workspace_size_, dropout_size_;
std::vector<cudnnTensorDescriptor_t> x_desc_vec_, y_desc_vec_;
cudnnTensorDescriptor_t hx_desc_, cx_desc_;
cudnnTensorDescriptor_t hy_desc_, cy_desc_;
dnnType *hx_ptr, *cx_ptr, *hy_ptr, *cy_ptr;
int stateDataDim;
cudnnFilterDescriptor_t w_desc_;
dnnType *w_ptr;
dnnType *w_h;
dnnType *wf_ptr, *wb_ptr; // params pointer forward and backward layer
// used during inference
dataDim_t one_output_dim; // output dim of as single inference
dnnType *srcF, *srcB; // input of single inference
dnnType *dstF, *dstB_NR, *dstB; // output of single inference, dstB_NR = dstB not reversed
};
/**
Convolutional 2D layer
@@ -370,8 +469,8 @@ public:
virtual dnnType* infer(dataDim_t &dim, dnnType* srcData);
public:
static const int MAX_INPUT_LAYERS = 16;
Layer *layers[MAX_INPUT_LAYERS]; //ids of layers to be merged
static const int MAX_LAYERS = 32;
Layer *layers[MAX_LAYERS]; //ids of layers to be merged
int layers_n; //number of layers
};
+3 -3
View File
@@ -93,11 +93,11 @@
} \
}
void printCenteredTitle(const char *title, char fill, int dim);
void printCenteredTitle(const char *title, char fill, int dim = 30);
bool fileExist(const char *fname);
void downloadWeightsifDoNotExist(const std::string& input_bin, const std::string& test_folder, const std::string& weights_url);
void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** data_d, int seek = 0, bool skipLoad = false);
int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device = true);
void readBinaryFile(std::string fname, int size, dnnType** data_h, dnnType** data_d, int seek = 0);
int checkResult(int size, dnnType *data_d, dnnType *correct_d, bool device = true, int limit = 10);
void printDeviceVector(int size, dnnType* vec_d, bool device = true);
float getColor(const int c, const int x, const int max);
void resize(int size, dnnType **data);