@ -434,7 +434,7 @@ class Layer_LSTM_Test : public ::testing::Test
{
public :
int numInp , numOut ;
Mat Wh , Wx , b ;
Mat Wh , Wx , b , h , c ;
Ptr < LSTMLayer > layer ;
std : : vector < Mat > inputs , outputs ;
@ -449,12 +449,17 @@ public:
Wh = Mat : : ones ( 4 * numOut , numOut , CV_32F ) ;
Wx = Mat : : ones ( 4 * numOut , numInp , CV_32F ) ;
b = Mat : : ones ( 4 * numOut , 1 , CV_32F ) ;
h = Mat : : ones ( 4 , numOut , CV_32F ) ;
c = Mat : : ones ( 4 , numOut , CV_32F ) ;
LayerParams lp ;
lp . blobs . resize ( 3 ) ;
lp . blobs . resize ( 5 ) ;
lp . blobs [ 0 ] = Wh ;
lp . blobs [ 1 ] = Wx ;
lp . blobs [ 2 ] = b ;
lp . blobs [ 3 ] = h ;
lp . blobs [ 4 ] = c ;
lp . set < bool > ( " produce_cell_output " , produceCellOutput ) ;
lp . set < bool > ( " use_timestamp_dim " , useTimestampDim ) ;
@ -502,10 +507,12 @@ TEST_F(Layer_LSTM_Test, get_set_test)
TEST ( Layer_LSTM_Test_Accuracy_with_ , CaffeRecurrent )
{
LayerParams lp ;
lp . blobs . resize ( 3 ) ;
lp . blobs . resize ( 5 ) ;
lp . blobs [ 0 ] = blobFromNPY ( _tf ( " lstm.prototxt.w_2.npy " ) ) ; // Wh
lp . blobs [ 1 ] = blobFromNPY ( _tf ( " lstm.prototxt.w_0.npy " ) ) ; // Wx
lp . blobs [ 2 ] = blobFromNPY ( _tf ( " lstm.prototxt.w_1.npy " ) ) ; // bias
lp . blobs [ 3 ] = Mat : : zeros ( 2 , 17 , CV_32F ) ; // h_0
lp . blobs [ 4 ] = Mat : : zeros ( 2 , 17 , CV_32F ) ; // c_0
Ptr < LSTMLayer > layer = LSTMLayer : : create ( lp ) ;
Mat inp = blobFromNPY ( _tf ( " recurrent.input.npy " ) ) ;
@ -516,6 +523,68 @@ TEST(Layer_LSTM_Test_Accuracy_with_, CaffeRecurrent)
normAssert ( h_t_reference , outputs [ 0 ] ) ;
}
TEST ( Layer_LSTM_Test_Accuracy_with_ , HiddenParams )
{
Mat Wx = blobFromNPY ( _tf ( " lstm.hidden.W.npy " ) ) ;
Mat Wh = blobFromNPY ( _tf ( " lstm.hidden.R.npy " ) ) ;
Mat b = blobFromNPY ( _tf ( " lstm.hidden.B.npy " ) ) ;
Mat h0 = blobFromNPY ( _tf ( " lstm.hidden.h0.npy " ) ) ;
Mat c0 = blobFromNPY ( _tf ( " lstm.hidden.c0.npy " ) ) ;
const int numHidden = 3 ;
const int numDirs = Wx . size [ 0 ] ;
const int numFeatures = Wx . size [ 2 ] ;
b = b . reshape ( 1 , b . size [ 0 ] ) ;
Mat bx = b . colRange ( 0 , b . cols / 2 ) ;
Mat bh = b . colRange ( b . cols / 2 , b . cols ) ;
b = bx + bh ;
// IFGO->IGFO
for ( int k = 0 ; k < numDirs ; + + k )
{
float * WxData = Wx . ptr < float > ( k ) ;
float * WhData = Wh . ptr < float > ( k ) ;
float * biasData = b . ptr < float > ( k ) ;
for ( int j = 0 ; j < numHidden ; + + j )
{
for ( int i = 0 ; i < numFeatures ; + + i )
{
std : : swap ( WxData [ ( numHidden + j ) * numFeatures + i ] ,
WxData [ ( numHidden * 2 + j ) * numFeatures + i ] ) ;
}
for ( int i = 0 ; i < numHidden ; + + i )
{
std : : swap ( WhData [ ( numHidden + j ) * numHidden + i ] ,
WhData [ ( numHidden * 2 + j ) * numHidden + i ] ) ;
}
std : : swap ( biasData [ numHidden + j ] , biasData [ numHidden * 2 + j ] ) ;
}
}
Wx = Wx . reshape ( 1 , Wx . size [ 0 ] * Wx . size [ 1 ] ) ;
Wh = Wh . reshape ( 1 , Wh . size [ 0 ] * Wh . size [ 1 ] ) ;
h0 = h0 . reshape ( 1 , h0 . size [ 0 ] * h0 . size [ 1 ] ) ;
c0 = c0 . reshape ( 1 , c0 . size [ 0 ] * c0 . size [ 1 ] ) ;
LayerParams lstmParams ;
lstmParams . blobs . resize ( 5 ) ;
lstmParams . blobs [ 0 ] = Wh ;
lstmParams . blobs [ 1 ] = Wx ;
lstmParams . blobs [ 2 ] = b ;
lstmParams . blobs [ 3 ] = h0 ;
lstmParams . blobs [ 4 ] = c0 ;
lstmParams . set ( " bidirectional " , false ) ;
Ptr < LSTMLayer > layer = LSTMLayer : : create ( lstmParams ) ;
Mat inp = blobFromNPY ( _tf ( " lstm.hidden.input.npy " ) ) ;
std : : vector < Mat > inputs ( 1 , inp ) , outputs ;
runLayer ( layer , inputs , outputs ) ;
Mat h_t_reference = blobFromNPY ( _tf ( " lstm.hidden.output.npy " ) ) ;
normAssert ( h_t_reference , outputs [ 0 ] ) ;
}
TEST ( Layer_RNN_Test_Accuracy_with_ , CaffeRecurrent )
{
Ptr < RNNLayer > layer = RNNLayer : : create ( LayerParams ( ) ) ;
@ -560,6 +629,9 @@ TEST(Layer_LSTM_Test_Accuracy_, Reverse)
bias . at < float > ( 2 , 0 ) = 1e10 f ; // Output gate - always output everything
bias . at < float > ( 3 , 0 ) = 0.f ; // Update signal
cv : : Mat hInternal = cv : : Mat : : zeros ( 1 , 1 , CV_32FC1 ) ;
cv : : Mat cInternal = cv : : Mat : : zeros ( 1 , 1 , CV_32FC1 ) ;
LayerParams lp ;
lp . set ( " reverse " , true ) ;
lp . set ( " use_timestamp_dim " , true ) ;
@ -567,6 +639,8 @@ TEST(Layer_LSTM_Test_Accuracy_, Reverse)
lp . blobs . push_back ( Wh ) ;
lp . blobs . push_back ( Wx ) ;
lp . blobs . push_back ( bias ) ;
lp . blobs . push_back ( hInternal ) ;
lp . blobs . push_back ( cInternal ) ;
cv : : Ptr < cv : : dnn : : LSTMLayer > layer = LSTMLayer : : create ( lp ) ;
std : : vector < cv : : Mat > outputs ;