Link:
http://blog.csdn.net/u013677156/article/details/79202271
kaldi中的Vector和Matrix
Vector和Matrix是kaldi中最常用的数据类型之一。语音数据,提取的特征,计算的结果,都保存在Vector或者Matrix之中。按照字面意思,Vector是“向量”,它只有一行数据,是一维的。Matrix是“矩阵”,它有行与列两个维度。kaldi中的Vector和Matrix,可以做许多数学上的操作。比如点加或点乘(每个元素都加上一个数,或者乘以一个数),比如矩阵之间的乘法和矩阵的奇异分解等。kaldi中Vector和Matrix还可以做一些特殊操作,比如对每个元素取对数,对所有元素做softmax等。
一、首先介绍下Vector。 在matrix/kaldi-vector.h中,定义了三个类:VectorBase、Vector和SubVector。其中,VectorBase是基类(父类),Vector和SubVector是派生类(子类)。VectorBase中的成员函数已经可以完成一个向量类的所有操作了,Vector类只是做了封装,定义了多种形式的构造函数,增加了resize操作等。 VectorBase类中的数据成员十分简单,就两个成员。一个指针data_指向存放数据的内存,一个整数dim_指示元素的个数。VectorBase中的函数成员比较多,但基本可以分为两类。一类是基本的、简单的操作。例如SetZero函数,用以设置全部数据为0;例如max函数,返回向量中的最大值。另一类是偏应用的函数或操作。比如,ApplySoftMax函数,提供softmax操作;比如Norm函数,计算范数。
下面的代码,有利于理解VectorBase的各种性质。注意,为了方面阅读和理解,对源代码做了修改。
- template<typename Real>
- class VectorBase {
-
- Real* data_;
- MatrixIndexT dim_;
- explicit VectorBase(): data_(NULL), dim_(0) { }
-
-
-
- void SetZero();
- void Set(Real f);
- void SetRandn();
- void SetRandUniform();
-
-
- inline MatrixIndexT Dim() const { return dim_; }
- inline Real* Data() { return data_; }
- inline MatrixIndexT SizeInBytes() const { return (dim_*sizeof(Real)); }
- inline Real operator() (MatrixIndexT i) const { return *(data_ + i); }
- inline Real & operator() (MatrixIndexT i) { return *(data_ + i); }
- Real Max() const;
- Real Min() const;
- Real Sum() const;
- Real SumLog() const;
-
-
- void CopyFromVec(const VectorBase<Real> &v);
- void CopyFromPacked(const PackedMatrix<Real> &M);
- void CopyRowsFromMat(const MatrixBase<Real> &M);
- void CopyColsFromMat(const MatrixBase<Real> &M);
- void CopyRowFromMat(const MatrixBase<Real> &M, MatrixIndexT row);
- void CopyDiagFromMat(const MatrixBase<Real> &M);
-
-
- void Add(Real c);
- void Scale(Real c);
- void ApplyLog();
- void ApplyExp();
- void ApplyAbs();
- void InvertElements();
- void ApplyPow(Real power);
- Real Norm(Real p) const;
- void MulElements(const VectorBase<Real> &v);
- void DivElements(const VectorBase<Real> &v);
-
-
- void AddVec(const Real alpha, const VectorBase<Real> &v);
- void AddVec2(const Real alpha, const VectorBase<Real> &v);
- void AddMatVec(...);
- void AddSpVec(...)
- void AddTpVec(...)
- void AddVecVec(...);
- void AddVecDivVec(...);
- void MulTp(...);
-
-
- Real ApplySoftMax(){
- Real max = this->Max(), sum = 0.0;
- for (MatrixIndexT i = 0; i < dim_; i++)
- sum += (data_[i] = Exp(data_[i] - max));
- this->Scale(1.0 / sum);
- return max + Log(sum);
- }
- void Tanh(const VectorBase<Real> &src);
- void Sigmoid(const VectorBase<Real> &src);
- };
-
-
- template<typename Real>
- class Vector: public VectorBase<Real> {
- public:
-
- Vector(): VectorBase<Real>() {}
- explicit Vector(const MatrixIndexT s, MatrixResizeType resize_type)
- : VectorBase<Real>() { Resize(s, resize_type); }
- Vector(const Vector<Real> &v) : VectorBase<Real>() {
- Resize(v.Dim(), kUndefined);
- this->CopyFromVec(v); }
- explicit Vector(const VectorBase<Real> &v) : VectorBase<Real>() {
- Resize(v.Dim(), kUndefined);
- this->CopyFromVec(v); }
- Vector<Real> &operator = (const Vector<Real> &other) {
- Resize(other.Dim(), kUndefined);
- this->CopyFromVec(other);
- return *this; }
-
-
- void Swap(Vector<Real> *other);
- void Resize(MatrixIndexT length, MatrixResizeType resize_type = kSetZero);
- void RemoveElement(MatrixIndexT i);
-
- private:
- void Init(const MatrixIndexT dim);
- void Destroy();
- };
-
- template<typename Real>
- class SubVector : public VectorBase<Real> {
- public:
-
-
- SubVector(const VectorBase<Real> &t, const MatrixIndexT origin,
- const MatrixIndexT length) : VectorBase<Real>() {
- VectorBase<Real>::data_ = const_cast<Real*> (t.Data()+origin);
- VectorBase<Real>::dim_ = length;
- }
- SubVector(const PackedMatrix<Real> &M) {
- VectorBase<Real>::data_ = const_cast<Real*> (M.Data());
- VectorBase<Real>::dim_ = (M.NumRows()*(M.NumRows()+1))/2;
- }
- SubVector(const SubVector &other) : VectorBase<Real> () {
- VectorBase<Real>::data_ = other.data_;
- VectorBase<Real>::dim_ = other.dim_;
- }
- SubVector(Real *data, MatrixIndexT length) : VectorBase<Real> () {
- VectorBase<Real>::data_ = data;
- VectorBase<Real>::dim_ = length;
- }
- SubVector(const MatrixBase<Real> &matrix, MatrixIndexT row) {
- VectorBase<Real>::data_ = const_cast<Real*>(matrix.RowData(row));
- VectorBase<Real>::dim_ = matrix.NumCols();
- }
- ~SubVector() {}
-
- private:
-
- SubVector & operator = (const SubVector &other) {}
- };
通过上面的代码,我们可以看出,Vector对VectorBase并未做太多的扩展,它们的功能基本一样。SubVector可以看作一种“引用”,它自身并不分配内存保存数据,而是指向了其他的对象中的数据。
二、简单介绍下Matrix。
跟Vector类似,在在matrix/kaldi-matrix.h中,定义了三个类:MatrixBase、Matrix和SubMatrix。MatrixBase是基类,另外两个是派生类。MatrixBase已经实现了非常多的方法。Matrix只是在基类的基础上,加了少数几个函数,比如Swap和RemoveRow等,这点跟Vector与VectorBase的关系一样。
MatrixBase中,数据成员并不多,大部分也容易理解。比如,整数num_rows_和num_cols_表示矩阵的行数和列数,指针data_指向保存数据的内存地址。这里有另外一个整型变量stride_需要注意。stride_保存的是正真的一行的个数。这里的意思是,一个矩阵,一行可能可以存放许多数据(stride_个),但可以不放满,只放num_cols_个。这时,一部分空间是浪费的。当然,一般部分情况下,num_cols_和stride_是一致的。
在矩阵上面的操作要比向量上的操作多,所以Matrix中的成员函数比Vector中的多很多。
- template<typename Real>
- class MatrixBase {
-
- Real* data_;
- MatrixIndexT num_cols_;
- MatrixIndexT num_rows_;
- MatrixIndexT stride_;
-
-
- inline MatrixIndexT NumRows() const { return num_rows_; }
- inline MatrixIndexT NumCols() const { return num_cols_; }
- inline MatrixIndexT Stride() const { return stride_; }
- inline Real* Data() const { return data_; }
- inline Real* RowData(MatrixIndexT i) { return data_ + i * stride_; }
- inline Real& operator() ( r, c) {return *(data_ + r * stride_ + c); }
- size_t SizeInBytes() const {return num_rows_ * stride_ * sizeof(Real);}
- Real &Index (MatrixIndexT r, MatrixIndexT c) { return (*this)(r, c); }
-
-
- void SetZero();
- void Set(Real);
- Real Sum() const;
- Real Max() const;
- Real Min() const;
- bool IsZero(Real cutoff = 1.0e-05) const;
-
-
- void CopyFromMat(const CompressedMatrix &M);
- void CopyRowsFromVec(const VectorBase<Real> &v);
- void CopyDiagFromVec(const VectorBase<Real> &v);
- inline SubVector<Real> Row(MatrixIndexT i);
- inline SubMatrix<Real> Range(...);
-
-
- void MulElements(const MatrixBase<Real> &A);
- void DivElements(const MatrixBase<Real> &A);
- void Scale(Real alpha);
- void Max(const MatrixBase<Real> &A);
- void Min(const MatrixBase<Real> &A);
- void MulColsVec(const VectorBase<Real> &scale);
- void MulRowsVec(const VectorBase<Real> &scale);
- void Add(const Real alpha);
- void ApplyFloor(Real floor_val);
- void ApplyCeiling(Real ceiling_val);
- void ApplyLog();
- void ApplyExp();
- Real ApplySoftMax();
- void Sigmoid(const MatrixBase<Real> &src);
-
-
- Real LogDet(Real *det_sign = NULL) const;
- void Invert(Real *log_det = NULL, Real *det_sign = NULL,
- bool inverse_needed = true);
- void Transpose();
- void Eig(MatrixBase<Real> *P,
- VectorBase<Real> *eigs_real,
- VectorBase<Real> *eigs_imag) const;
- void Svd(VectorBase<Real> *s, MatrixBase<Real> *U,
- MatrixBase<Real> *Vt) const;
- void AddVecVec(...)
- void AddMat(...)
- void AddMatMatMat(...)
- void AddTpTp(...)
- };
'via Blog this'
No comments:
Post a Comment