Merge with master works
Signed-off-by: Micaela Verucchi <micaelaverucchi@gmail.com> Davide Sapienza <sapienza.dav@gmail.com>
This commit is contained in:
@@ -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
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user