This commit is contained in:
AdarshSantoria
2023-02-27 00:58:33 +05:30
parent 95b04c78ae
commit 14c81ecf4b
2 changed files with 0 additions and 5050 deletions
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.