Eigen矩阵和向量上的抽象类

时间:2017-10-10 13:02:36

标签: c++ abstract-class eigen

我想实现一个由层组成的神经网络框架,然后可以将这些层组成一个计算图(例如参见caffe)。我正在使用特征库作为矩阵。特征区分向量和矩阵,因此对于某些操作(向矩阵添加偏差),只能使用向量(而不是与向量具有相同维度的矩阵)。例如:

MatrixXf A = MatrixXf(3, 2); // Variables not initialized for brevity
VectorXf v = VectorXf(2);
MatrixXf R1 = A.array().rowwise() + v.transpose().array();  // Broadcasts v correctly
MatrixXf vMat = MatrixXf(1, 2);
MatrixXf R2 = A.array().rowwise() + vMat.array();           // YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX Error

如果我希望图层看起来像这样:

void AffineForward(std::vector<Tensor> in, std::vector<Tensor> out)
{
   MatrixXf &X = in[0];
   MatrixXf &W = in[1];
   VectorXf &b = in[2];

   out[0] = X * W;
   out[0] += b;
}

我如何设计抽象的Tensor类,以便我可以发送一个std :: vector of Tensors?我想到了这样的事情:

class Tensor
{
public:
    virtual Tensor operator*(const Tensor &t) const = 0;
};

class TensorMatrix : Tensor
{
 public:
    TensorMatrix operator*(const TensorMatrix &t) const;
    TensorMatrix operator*(const TensorVector &t) const;
    MatrixXf _data;
};

class TensorVector : Tensor
{
 public:
    VectorXf _data;
};

但虚拟Tensor运算符*抛出编译时错误(函数返回抽象类Tensor是不允许的),这是有道理的。

做我想做的最简单的方法是什么?创建一个可以放入容器的类,我可以从中获取MatrixXf和VectorXf(取决于用户输入的内容?)。 Caffe使用了一种叫做“Blob”的东西。

1 个答案:

答案 0 :(得分:2)

  

本征区分向量和矩阵,因此对于某些操作(向矩阵添加偏差),只能使用向量(而不是与向量具有相同维度的矩阵)。

这不是真的,矢量 Eigen中的矩阵;它只是某些操作需要在编译时知道维度;在你的例子中

MatrixXf R1 = A.rowwise() + v.transpose();
MatrixXf R2 = A.rowwise() + vMat;  

第二行无法编译,因为广播需要一个编译时间为row-dimensions == 1的矩阵; 解决方案是告诉Eigen你想要一个明确的行向量:

MatrixXf R2 = A.rowwise() + vMat.row(0);

使用存储为MatrixXf的行和列向量的代码(根据您的最终要求是否可行)

if( vMat.rows() == 1  )
  MatrixXf R1 = A.rowwise() + vMat.rows(0); ...
else if( vMat.cols() == 1  )
  MatrixXf R2 = A.rowwise() + vMat.transpose().rows(0); ...
else
  whatever...

所以,你总是可以将矢量作为矩阵存储到Eigen中,你只需要小心告诉Eigen如何处理它们......