#ifndef _CUCRBEDCTFEATURES_H_ #define _CUCRBEDCTFEATURES_H_ #include "cuComponent.h" #include "cumath.h" namespace TNet { /** * \brief Input features time context expand * * \ingroup CuNNMisc * Expands the time context of the input features according to FrameOffset * * in N, out k*N, FrameOffset o_1,o_2,...,o_k * FrameOffset example 11frames: -5 -4 -3 -2 -1 0 1 2 3 4 5 */ class CuExpand : public CuComponent { public: CuExpand(size_t nInputs, size_t nOutputs, CuComponent* pPred) : CuComponent(nInputs,nOutputs,pPred) { } ~CuExpand() { } ComponentType GetType() const { return EXPAND; } const char* GetName() const { return ""; } void ReadFromStream(std::istream& rIn) { Vector vec; rIn >> vec; mFrameOffset.CopyFrom(vec); } void WriteToStream(std::ostream& rOut) { Vector vec; mFrameOffset.CopyTo(vec); rOut << vec; } protected: void PropagateFnc(const CuMatrix& X, CuMatrix& Y) { CuMath::Expand(Y,X,mFrameOffset); } void BackpropagateFnc(const CuMatrix& X, CuMatrix& Y) { Error("__func__ Nonsense"); } protected: CuVector mFrameOffset; }; /** * \brief Columns' value shuffling * * \ingroup CuNNMisc * Rearrange the matrix columns according to the indices in CopyFromIndices */ class CuCopy : public CuComponent { public: CuCopy(size_t nInputs, size_t nOutputs, CuComponent* pPred) : CuComponent(nInputs,nOutputs,pPred) { } ~CuCopy() { } ComponentType GetType() const { return COPY; } const char* GetName() const { return ""; } void ReadFromStream(std::istream& rIn) { Vector vec; rIn >> vec; vec.Add(-1); mCopyFromIndices.CopyFrom(vec); } void WriteToStream(std::ostream& rOut) { Vector vec; mCopyFromIndices.CopyTo(vec); vec.Add(1); rOut << vec; } protected: void PropagateFnc(const CuMatrix& X, CuMatrix& Y) { CuMath::Rearrange(Y,X,mCopyFromIndices); } void BackpropagateFnc(const CuMatrix& X, CuMatrix& Y) { Error("__func__ Nonsense"); } protected: CuVector mCopyFromIndices; }; /** * \brief Perform Feature transpose * * \ingroup CuNNMisc */ class CuTranspose : public CuComponent { public: CuTranspose(size_t nInputs, size_t nOutputs, CuComponent* pPred) : CuComponent(nInputs,nOutputs,pPred), mContext(0) { } ~CuTranspose() { } ComponentType GetType() const { return TRANSPOSE; } const char* GetName() const { return ""; } void ReadFromStream(std::istream& rIn) { rIn >> std::ws >> mContext; if(GetNInputs() != GetNOutputs()) { Error("Input dim must be same as output dim"); } if(GetNInputs() % mContext != 0) { Error("Number of inputs must be divisible by context length"); } Vector vec(GetNInputs()); int channels = GetNInputs() / mContext; for(int i=0, ch=0; ch& X, CuMatrix& Y) { CuMath::Rearrange(Y,X,mCopyFromIndices); } void BackpropagateFnc(const CuMatrix& X, CuMatrix& Y) { Error("__func__ Nonsense"); } protected: int mContext; CuVector mCopyFromIndices; }; /** * \brief Used for the blockwise multiplication by * DCT transform loaded from disk * * \ingroup CuNNMisc */ class CuBlockLinearity : public CuComponent { public: CuBlockLinearity(size_t nInputs, size_t nOutputs, CuComponent* pPred) : CuComponent(nInputs,nOutputs,pPred) { } ~CuBlockLinearity() { } ComponentType GetType() const { return CuComponent::BLOCK_LINEARITY; } const char* GetName() const { return ""; } void PropagateFnc(const CuMatrix& X, CuMatrix& Y) { CuMath::BlockLinearity(Y,X,mBlockLinearity); } void BackpropagateFnc(const CuMatrix& X, CuMatrix& Y) { Error("__func__ Not implemented"); } void ReadFromStream(std::istream& rIn) { Matrix mat; rIn >> mat; Matrix trans(mat,TRANS); mBlockLinearity.CopyFrom(trans); if((GetNOutputs() % mBlockLinearity.Cols() != 0) || (GetNInputs() % mBlockLinearity.Rows() != 0) || ((GetNOutputs() / mBlockLinearity.Cols()) != (GetNInputs() / mBlockLinearity.Rows()))) { Error("BlockLinearity matrix dimensions must divide IO dims"); } } void WriteToStream(std::ostream& rOut) { Matrix mat; mBlockLinearity.CopyTo(mat); Matrix trans(mat,TRANS); rOut << trans; } private: CuMatrix mBlockLinearity; }; /** * \brief Bias layer * * \ingroup CuNNMisc * Implements: \f$ \vec{Y}=\vec{X}+\vec{\beta} \f$ */ class CuBias : public CuComponent { public: CuBias(size_t nInputs, size_t nOutputs, CuComponent* pPred) : CuComponent(nInputs,nOutputs,pPred) { } ~CuBias() { } ComponentType GetType() const { return CuComponent::BIAS; } const char* GetName() const { return ""; } void PropagateFnc(const CuMatrix& X, CuMatrix& Y) { Y.CopyFrom(X); Y.AddScaledRow(1.0, mBias, 1.0); } void BackpropagateFnc(const CuMatrix& X, CuMatrix& Y) { Y.CopyFrom(X); } void ReadFromStream(std::istream& rIn) { Vector vec; rIn >> vec; mBias.CopyFrom(vec); } void WriteToStream(std::ostream& rOut) { Vector vec; mBias.CopyTo(vec); rOut << vec; } private: CuVector mBias; }; /** * \brief Column Scaling * * \ingroup CuNNMisc * Scaling the inputs with coefficients in scaling CuVector mWindow */ class CuWindow : public CuComponent { public: CuWindow(size_t nInputs, size_t nOutputs, CuComponent* pPred) : CuComponent(nInputs, nOutputs, pPred) { } ~CuWindow() { } ComponentType GetType() const { return CuComponent::WINDOW; } const char* GetName() const { return ""; } void PropagateFnc(const CuMatrix& X, CuMatrix& Y) { Y.CopyFrom(X); Y.ScaleCols(mWindow); } void BackpropagateFnc(const CuMatrix& X, CuMatrix& Y) { Error("__func__ Not implemented"); } void ReadFromStream(std::istream& rIn) { Vector vec; rIn >> vec; mWindow.CopyFrom(vec); } void WriteToStream(std::ostream& rOut) { Vector vec; mWindow.CopyTo(vec); rOut << vec; } private: CuVector mWindow; ///< Scaling factors }; /** * \brief Perform log transorm * * \ingroup CuNNMisc * Calculate: \f[ \vec{Y}=\ln \vec{X} \f] */ class CuLog : public CuComponent { public: CuLog(size_t nInputs, size_t nOutputs, CuComponent* pPred) : CuComponent(nInputs, nOutputs, pPred) { } ~CuLog() { } ComponentType GetType() const { return CuComponent::LOG; } const char* GetName() const { return ""; } void PropagateFnc(const CuMatrix& X, CuMatrix& Y) { Y.CopyFrom(X); Y.ApplyLog(); } void BackpropagateFnc(const CuMatrix& X, CuMatrix& Y) { Error("__func__ Not implemented"); } void ReadFromStream(std::istream& rIn) { } void WriteToStream(std::ostream& rOut) { } }; } #endif