我想实现一个由层组成的神经网络框架,然后可以将这些层组成一个计算图(例如参见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”的东西。
答案 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如何处理它们......