fix file
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -386,27 +386,6 @@ TEST_CASE("ConstantLayerParametersTest", "[ANNLayerTest]")
|
||||
// REQUIRE(CheckGradient(function) <= 1e-4);
|
||||
// }
|
||||
|
||||
// /**
|
||||
// * Jacobian negative log likelihood module test.
|
||||
// */
|
||||
// TEST_CASE("JacobianNegativeLogLikelihoodLayerTest", "[ANNLayerTest]")
|
||||
// {
|
||||
// for (size_t i = 0; i < 5; ++i)
|
||||
// {
|
||||
// NegativeLogLikelihood module;
|
||||
// const size_t inputElements = RandInt(5, 100);
|
||||
// arma::mat input;
|
||||
// RandomInitialization init(0, 1);
|
||||
// init.Initialize(input, inputElements, 1);
|
||||
|
||||
// arma::mat target(1, 1);
|
||||
// target(0) = RandInt(0, inputElements - 2);
|
||||
|
||||
// double error = JacobianPerformanceTest(module, input, target);
|
||||
// REQUIRE(error <= 1e-5);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Jacobian LeakyReLU module test.
|
||||
*
|
||||
@@ -1848,285 +1827,6 @@ TEST_CASE("SimpleJoinLayerTest", "[ANNLayerTest]")
|
||||
// boost::apply_visitor(DeleteVisitor(), layer);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Simple concat module test.
|
||||
*/
|
||||
TEST_CASE("SimpleConcatLayerTest", "[ANNLayerTest]")
|
||||
{
|
||||
arma::mat output, input, delta, error;
|
||||
|
||||
Linear* moduleA = new Linear(10);
|
||||
moduleA->InputDimensions() = std::vector<size_t>({ 10 });
|
||||
moduleA->ComputeOutputDimensions();
|
||||
arma::mat weightsA(moduleA->WeightSize(), 1);
|
||||
moduleA->SetWeights((double*) weightsA.memptr());
|
||||
moduleA->Parameters().randu();
|
||||
|
||||
Linear* moduleB = new Linear(10);
|
||||
moduleB->InputDimensions() = std::vector<size_t>({ 10 });
|
||||
moduleB->ComputeOutputDimensions();
|
||||
arma::mat weightsB(moduleB->WeightSize(), 1);
|
||||
moduleB->SetWeights((double*) weightsB.memptr());
|
||||
moduleB->Parameters().randu();
|
||||
|
||||
Concat module;
|
||||
module.Add(moduleA);
|
||||
module.Add(moduleB);
|
||||
module.InputDimensions() = std::vector<size_t>({ 10 });
|
||||
module.ComputeOutputDimensions();
|
||||
|
||||
// Test the Forward function.
|
||||
input = arma::zeros(10, 1);
|
||||
output.set_size(module.OutputSize(), 1);
|
||||
module.Forward(input, output);
|
||||
|
||||
const double sumModuleA = arma::accu(
|
||||
moduleA->Parameters().submat(
|
||||
100, 0, moduleA->Parameters().n_elem - 1, 0));
|
||||
const double sumModuleB = arma::accu(
|
||||
moduleB->Parameters().submat(
|
||||
100, 0, moduleB->Parameters().n_elem - 1, 0));
|
||||
REQUIRE(sumModuleA + sumModuleB ==
|
||||
Approx(arma::accu(output.col(0))).epsilon(1e-5));
|
||||
|
||||
// Test the Backward function.
|
||||
error = arma::zeros(20, 1);
|
||||
delta.set_size(input.n_rows, input.n_cols);
|
||||
module.Backward(input, error, delta);
|
||||
REQUIRE(arma::accu(delta) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to check Concat layer along different axes.
|
||||
*/
|
||||
TEST_CASE("ConcatAlongAxisTest", "[ANNLayerTest]")
|
||||
{
|
||||
arma::mat output, input, error, outputA, outputB;
|
||||
size_t inputWidth = 4, inputHeight = 4, inputChannel = 2;
|
||||
size_t outputWidth, outputHeight, outputChannel = 2;
|
||||
size_t kW = 3, kH = 3;
|
||||
size_t batch = 1;
|
||||
|
||||
// Using Convolution<> layer as inout to Concat<> layer.
|
||||
// Compute the output shape of convolution layer.
|
||||
outputWidth = (inputWidth - kW) + 1;
|
||||
outputHeight = (inputHeight - kH) + 1;
|
||||
|
||||
input = arma::ones(inputWidth * inputHeight * inputChannel, batch);
|
||||
|
||||
Convolution* moduleA = new Convolution(outputChannel, kW, kH, 1, 1, 0, 0);
|
||||
Convolution* moduleB = new Convolution(outputChannel, kW, kH, 1, 1, 0, 0);
|
||||
|
||||
moduleA->InputDimensions() = std::vector<size_t>({ inputWidth, inputHeight });
|
||||
moduleA->ComputeOutputDimensions();
|
||||
arma::mat weightsA(moduleA->WeightSize(), 1);
|
||||
moduleA->SetWeights((double*) weightsA.memptr());
|
||||
moduleA->Parameters().randu();
|
||||
|
||||
moduleB->InputDimensions() = std::vector<size_t>({ inputWidth, inputHeight });
|
||||
moduleB->ComputeOutputDimensions();
|
||||
arma::mat weightsB(moduleB->WeightSize(), 1);
|
||||
moduleB->SetWeights((double*) weightsB.memptr());
|
||||
moduleB->Parameters().randu();
|
||||
|
||||
// Compute output of each layer.
|
||||
outputA.set_size(moduleA->OutputSize(), 1);
|
||||
outputB.set_size(moduleB->OutputSize(), 1);
|
||||
moduleA->Forward(input, outputA);
|
||||
moduleB->Forward(input, outputB);
|
||||
|
||||
arma::cube A(outputA.memptr(), outputWidth, outputHeight, outputChannel);
|
||||
arma::cube B(outputB.memptr(), outputWidth, outputHeight, outputChannel);
|
||||
|
||||
error = arma::ones(outputWidth * outputHeight * outputChannel * 2, 1);
|
||||
|
||||
for (size_t axis = 0; axis < 3; ++axis)
|
||||
{
|
||||
size_t x = 1, y = 1, z = 1;
|
||||
arma::cube calculatedOut;
|
||||
if (axis == 0)
|
||||
{
|
||||
calculatedOut.set_size(2 * outputWidth, outputHeight, outputChannel);
|
||||
for (size_t i = 0; i < A.n_slices; ++i)
|
||||
{
|
||||
arma::mat aMat = A.slice(i);
|
||||
arma::mat bMat = B.slice(i);
|
||||
calculatedOut.slice(i) = arma::join_cols(aMat, bMat);
|
||||
}
|
||||
x = 2;
|
||||
}
|
||||
if (axis == 1)
|
||||
{
|
||||
calculatedOut.set_size(outputWidth, 2 * outputHeight, outputChannel);
|
||||
for (size_t i = 0; i < A.n_slices; ++i)
|
||||
{
|
||||
arma::mat aMat = A.slice(i);
|
||||
arma::mat bMat = B.slice(i);
|
||||
calculatedOut.slice(i) = arma::join_rows(aMat, bMat);
|
||||
}
|
||||
y = 2;
|
||||
}
|
||||
if (axis == 2)
|
||||
{
|
||||
calculatedOut = arma::join_slices(A, B);
|
||||
z = 2;
|
||||
}
|
||||
|
||||
// Compute output of Concat<> layer.
|
||||
Concat module(axis);
|
||||
module.Add(moduleA);
|
||||
module.Add(moduleB);
|
||||
module.InputDimensions() = std::vector<size_t>({ inputWidth, inputHeight });
|
||||
module.ComputeOutputDimensions();
|
||||
output.set_size(module.OutputSize(), 1);
|
||||
module.Forward(input, output);
|
||||
arma::cube concatOut(output.memptr(), x * outputWidth,
|
||||
y * outputHeight, z * outputChannel);
|
||||
|
||||
// Verify if the output reshaped to cubes are similar.
|
||||
CheckMatrices(concatOut, calculatedOut, 1e-12);
|
||||
|
||||
// Ensure that the child layers don't get deleted when `module` is
|
||||
// deallocated.
|
||||
module.Network().clear();
|
||||
}
|
||||
|
||||
delete moduleA;
|
||||
delete moduleB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the function that can access the axis parameter of the
|
||||
* Concat layer works.
|
||||
*/
|
||||
TEST_CASE("ConcatLayerParametersTest", "[ANNLayerTest]")
|
||||
{
|
||||
Concat layer(2);
|
||||
|
||||
// Make sure we can get the parameters successfully.
|
||||
REQUIRE(layer.Axis() == 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Concat layer numerical gradient test.
|
||||
*/
|
||||
TEST_CASE("GradientConcatLayerTest", "[ANNLayerTest]")
|
||||
{
|
||||
// Concat function gradient instantiation.
|
||||
struct GradientFunction
|
||||
{
|
||||
GradientFunction() :
|
||||
input(arma::randu(10, 1)),
|
||||
target(arma::mat("0"))
|
||||
{
|
||||
model = new FFN<NegativeLogLikelihood, NguyenWidrowInitialization>();
|
||||
model->ResetData(input, target);
|
||||
model->Add<Linear>(10);
|
||||
|
||||
concat = new Concat();
|
||||
concat->Add<Linear>(5);
|
||||
concat->Add<Linear>(5);
|
||||
model->Add(concat);
|
||||
model->Add<Linear>(2);
|
||||
|
||||
model->Add<LogSoftMax>();
|
||||
}
|
||||
|
||||
~GradientFunction()
|
||||
{
|
||||
delete model;
|
||||
}
|
||||
|
||||
double Gradient(arma::mat& gradient) const
|
||||
{
|
||||
double error = model->Evaluate(model->Parameters(), 0, 1);
|
||||
model->Gradient(model->Parameters(), 0, gradient, 1);
|
||||
return error;
|
||||
}
|
||||
|
||||
arma::mat& Parameters() { return model->Parameters(); }
|
||||
|
||||
FFN<NegativeLogLikelihood, NguyenWidrowInitialization>* model;
|
||||
Concat* concat;
|
||||
arma::mat input, target;
|
||||
} function;
|
||||
|
||||
REQUIRE(CheckGradient(function) <= 1e-4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple concatenate module test.
|
||||
*/
|
||||
TEST_CASE("SimpleConcatenateLayerTest", "[ANNLayerTest]")
|
||||
{
|
||||
arma::mat input = arma::ones(5, 1);
|
||||
arma::mat output, delta;
|
||||
|
||||
Concatenate module;
|
||||
module.Concat() = arma::ones(5, 1) * 0.5;
|
||||
module.InputDimensions() = std::vector<size_t>({ 5 });
|
||||
module.ComputeOutputDimensions();
|
||||
|
||||
// Test the Forward function.
|
||||
output.set_size(module.OutputSize(), 1);
|
||||
module.Forward(input, output);
|
||||
|
||||
REQUIRE(arma::accu(output) == 7.5);
|
||||
|
||||
// Test the Backward function.
|
||||
delta.set_size(5, 1);
|
||||
module.Backward(input, output, delta);
|
||||
REQUIRE(arma::accu(delta) == 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate layer numerical gradient test.
|
||||
*/
|
||||
TEST_CASE("GradientConcatenateLayerTest", "[ANNLayerTest]")
|
||||
{
|
||||
// Concatenate function gradient instantiation.
|
||||
struct GradientFunction
|
||||
{
|
||||
GradientFunction() :
|
||||
input(arma::randu(10, 1)),
|
||||
target(arma::mat("0"))
|
||||
{
|
||||
model = new FFN<NegativeLogLikelihood, NguyenWidrowInitialization>();
|
||||
model->ResetData(input, target);
|
||||
model->Add<Linear>(5);
|
||||
|
||||
arma::mat concat = arma::ones(5, 1);
|
||||
// concatenate = new Concatenate();
|
||||
// concatenate->Concat() = concat;
|
||||
// model->Add(concatenate);
|
||||
model->Add<Concatenate>(concat);
|
||||
|
||||
model->Add<Linear>(5);
|
||||
model->Add<LogSoftMax>();
|
||||
}
|
||||
|
||||
~GradientFunction()
|
||||
{
|
||||
delete model;
|
||||
}
|
||||
|
||||
double Gradient(arma::mat& gradient) const
|
||||
{
|
||||
double error = model->Evaluate(model->Parameters(), 0, 1);
|
||||
model->Gradient(model->Parameters(), 0, gradient, 1);
|
||||
return error;
|
||||
}
|
||||
|
||||
arma::mat& Parameters() { return model->Parameters(); }
|
||||
|
||||
FFN<NegativeLogLikelihood, NguyenWidrowInitialization>* model;
|
||||
Concatenate* concatenate;
|
||||
arma::mat input, target;
|
||||
} function;
|
||||
|
||||
REQUIRE(CheckGradient(function) <= 1e-4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple lookup module test.
|
||||
*
|
||||
@@ -2239,69 +1939,6 @@ TEST_CASE("LookupLayerParametersTest", "[ANNLayerTest]")
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Simple Softmax module test.
|
||||
*/
|
||||
TEST_CASE("SimpleSoftmaxLayerTest", "[ANNLayerTest]")
|
||||
{
|
||||
arma::mat input, output, gy, g;
|
||||
Softmax module;
|
||||
|
||||
// Test the forward function.
|
||||
input = arma::mat("1.7; 3.6");
|
||||
module.Forward(input, output);
|
||||
REQUIRE(arma::accu(arma::abs(arma::mat("0.130108; 0.869892") - output)) ==
|
||||
Approx(0.0).margin(1e-4));
|
||||
|
||||
// Test the backward function.
|
||||
gy = arma::zeros(input.n_rows, input.n_cols);
|
||||
gy(0) = 1;
|
||||
module.Backward(output, gy, g);
|
||||
REQUIRE(arma::accu(arma::abs(arma::mat("0.11318; -0.11318") - g)) ==
|
||||
Approx(0.0).margin(1e-04));
|
||||
}
|
||||
|
||||
/**
|
||||
* Softmax layer numerical gradient test.
|
||||
*/
|
||||
TEST_CASE("GradientSoftmaxTest", "[ANNLayerTest]")
|
||||
{
|
||||
// Softmax function gradient instantiation.
|
||||
struct GradientFunction
|
||||
{
|
||||
GradientFunction() :
|
||||
input(arma::randu(10, 1)),
|
||||
target(arma::mat("1; 0"))
|
||||
{
|
||||
model = new FFN<MeanSquaredError, RandomInitialization>;
|
||||
model->ResetData(input, target);
|
||||
model->Add<Linear>(10);
|
||||
model->Add<ReLU>();
|
||||
model->Add<Linear>(2);
|
||||
model->Add<Softmax>();
|
||||
}
|
||||
|
||||
~GradientFunction()
|
||||
{
|
||||
delete model;
|
||||
}
|
||||
|
||||
double Gradient(arma::mat& gradient) const
|
||||
{
|
||||
double error = model->Evaluate(model->Parameters(), 0, 1);
|
||||
model->Gradient(model->Parameters(), 0, gradient, 1);
|
||||
return error;
|
||||
}
|
||||
|
||||
arma::mat& Parameters() { return model->Parameters(); }
|
||||
|
||||
FFN<MeanSquaredError>* model;
|
||||
arma::mat input, target;
|
||||
} function;
|
||||
|
||||
REQUIRE(CheckGradient(function) <= 1e-4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for the NearestInterpolation layer
|
||||
*
|
||||
@@ -4058,155 +3695,6 @@ TEST_CASE("TransposedConvolutionLayerPaddingTest", "[ANNLayerTest]")
|
||||
// REQUIRE(output.n_elem == 4);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Simple test for AddMerge layer.
|
||||
*/
|
||||
TEST_CASE("AddMergeTestCase", "[ANNLayerTest]")
|
||||
{
|
||||
// For rectangular input to pooling layers.
|
||||
arma::mat input = arma::mat(28, 1);
|
||||
input.zeros();
|
||||
input(0) = input(16) = 1;
|
||||
input(1) = input(17) = 2;
|
||||
input(2) = input(18) = 3;
|
||||
input(3) = input(19) = 4;
|
||||
input(4) = input(20) = 5;
|
||||
input(5) = input(23) = 6;
|
||||
input(6) = input(24) = 7;
|
||||
input(14) = input(25) = 8;
|
||||
input(15) = input(26) = 9;
|
||||
|
||||
AddMerge module1;
|
||||
module1.Add<MeanPooling>(2, 2, 2, 2, false);
|
||||
module1.Add<MeanPooling>(2, 2, 2, 2, false);
|
||||
|
||||
AddMerge module2;
|
||||
module2.Add<MeanPooling>(2, 2, 2, 2, true);
|
||||
module2.Add<MeanPooling>(2, 2, 2, 2, true);
|
||||
|
||||
module1.InputDimensions() = std::vector<size_t>({ 7, 4 });
|
||||
module1.ComputeOutputDimensions();
|
||||
module2.InputDimensions() = std::vector<size_t>({ 7, 4 });
|
||||
module2.ComputeOutputDimensions();
|
||||
|
||||
// Calculated using torch.nn.MeanPool2d().
|
||||
arma::mat result1, result2;
|
||||
result1 << 1.5000 << 8.5000 << arma::endr
|
||||
<< 3.5000 << 8.0000 << arma::endr
|
||||
<< 5.5000 << 12.0000 << arma::endr
|
||||
<< 7.0000 << 5.0000 << arma::endr;
|
||||
|
||||
result2 << 1.5000 << 8.5000 << arma::endr
|
||||
<< 3.5000 << 8.0000 << arma::endr
|
||||
<< 5.5000 << 12.0000 << arma::endr;
|
||||
|
||||
arma::mat output1, output2;
|
||||
output1.set_size(8, 1);
|
||||
output2.set_size(6, 1);
|
||||
module1.Forward(input, output1);
|
||||
REQUIRE(arma::accu(output1) == 51.0);
|
||||
module2.Forward(input, output2);
|
||||
REQUIRE(arma::accu(output2) == 39.0);
|
||||
output1.reshape(4, 2);
|
||||
output2.reshape(3, 2);
|
||||
CheckMatrices(output1, result1, 1e-1);
|
||||
CheckMatrices(output2, result2, 1e-1);
|
||||
|
||||
arma::mat prevDelta1, prevDelta2;
|
||||
prevDelta1 << 3.6000 << -0.9000 << arma::endr
|
||||
<< 3.6000 << -0.9000 << arma::endr
|
||||
<< 3.6000 << -0.9000 << arma::endr
|
||||
<< 3.6000 << -0.9000 << arma::endr;
|
||||
|
||||
prevDelta2 << 3.6000 << -0.9000 << arma::endr
|
||||
<< 3.6000 << -0.9000 << arma::endr
|
||||
<< 3.6000 << -0.9000 << arma::endr;
|
||||
arma::mat delta1, delta2;
|
||||
delta1.set_size(28, 1);
|
||||
delta2.set_size(28, 1);
|
||||
prevDelta1.reshape(8, 1);
|
||||
prevDelta2.reshape(6, 1);
|
||||
module1.Backward(input, prevDelta1, delta1);
|
||||
REQUIRE(arma::accu(delta1) == Approx(21.6).epsilon(1e-3));
|
||||
module2.Backward(input, prevDelta2, delta2);
|
||||
REQUIRE(arma::accu(delta2) == Approx(16.2).epsilon(1e-3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Complex test for AddMerge layer.
|
||||
* This test includes:
|
||||
* 1. AddMerge layer inside the AddMerge layer.
|
||||
* 2. Batch Size > 1.
|
||||
* 3. AddMerge layer with single child layer.
|
||||
*/
|
||||
TEST_CASE("AddMergeAdvanceTestCase", "[ANNLayerTest]")
|
||||
{
|
||||
AddMerge r;
|
||||
AddMerge* r2 = new AddMerge();
|
||||
r2->Add<Linear>(5);
|
||||
r.Add<Linear>(5);
|
||||
r.Add(r2);
|
||||
r.InputDimensions() = std::vector<size_t>({ 5 });
|
||||
r.ComputeOutputDimensions();
|
||||
arma::mat rParams(r.WeightSize(), 1);
|
||||
r.SetWeights((double*) rParams.memptr());
|
||||
r.Network()[0]->Parameters().fill(2.0);
|
||||
((AddMerge*) r.Network()[1])->Network()[0]->Parameters().fill(-1.0);
|
||||
|
||||
Linear l(5);
|
||||
l.InputDimensions() = std::vector<size_t>({ 5 });
|
||||
l.ComputeOutputDimensions();
|
||||
arma::mat lParams(l.WeightSize(), 1);
|
||||
l.SetWeights((double*) lParams.memptr());
|
||||
l.Parameters().fill(1.0);
|
||||
|
||||
arma::mat input(arma::randn(5, 10));
|
||||
arma::mat output1, output2;
|
||||
output1.set_size(5, 10);
|
||||
output2.set_size(5, 10);
|
||||
|
||||
r.Forward(input, output1);
|
||||
l.Forward(input, output2);
|
||||
|
||||
CheckMatrices(output1, output2, 1e-3);
|
||||
|
||||
arma::mat delta1, delta2;
|
||||
delta1.set_size(5, 10);
|
||||
delta2.set_size(5, 10);
|
||||
r.Backward(input, output1, delta1);
|
||||
l.Backward(input, output2, delta2);
|
||||
|
||||
CheckMatrices(output1, output2, 1e-3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test for Identity layer.
|
||||
*/
|
||||
TEST_CASE("IdentityTestCase", "[ANNLayerTest]")
|
||||
{
|
||||
// For rectangular input to pooling layers.
|
||||
arma::mat input = arma::mat(12, 1, arma::fill::randn);
|
||||
arma::mat output;
|
||||
// Output-Size should be 4 x 3.
|
||||
output.set_size(12, 1);
|
||||
|
||||
Identity module1;
|
||||
module1.InputDimensions() = std::vector<size_t>({ 4, 3 });
|
||||
module1.ComputeOutputDimensions();
|
||||
module1.Forward(input, output);
|
||||
CheckMatrices(output, input, 1e-1);
|
||||
REQUIRE(output.n_elem == 12);
|
||||
REQUIRE(output.n_cols == 1);
|
||||
REQUIRE(input.memptr() != output.memptr());
|
||||
|
||||
arma::mat prevDelta = arma::mat(12, 1, arma::fill::randn);
|
||||
arma::mat delta;
|
||||
delta.set_size(12, 1);
|
||||
module1.Backward(input, prevDelta, delta);
|
||||
CheckMatrices(delta, prevDelta, 1e-1);
|
||||
REQUIRE(delta.memptr() != prevDelta.memptr());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the functions that can modify and access the parameters of the
|
||||
* Glimpse layer work.
|
||||
|
||||
Reference in New Issue
Block a user