Add a test for uneven stride.

This commit is contained in:
Ryan Curtin
2022-02-09 21:45:29 -05:00
parent c532632ce9
commit 2065e17df8
2 changed files with 62 additions and 8 deletions
@@ -403,19 +403,41 @@ void ConvolutionType<
mappedError.slice(outMap + fullOutputOffset),
rotatedFilters.slice(outMap),
output,
1,
1,
strideWidth,
strideHeight);
strideHeight,
strideWidth);
if (usingPadding)
// If the stride width or height is greater than 1, then we have to
// insert columns and rows into the convolution output.
if (strideWidth == 1 && strideHeight == 1)
{
gTemp.slice(inMap + fullInputOffset) += output.submat(padWLeft,
padHTop, padWLeft + gTemp.n_rows - 1, padHTop + gTemp.n_cols - 1);
if (usingPadding)
{
gTemp.slice(inMap + fullInputOffset) += output.submat(
padWLeft,
padHTop,
padWLeft + gTemp.n_rows - 1,
padHTop + gTemp.n_cols - 1);
}
else
{
gTemp.slice(inMap + fullInputOffset) += output;
}
}
else
{
gTemp.slice(inMap + fullInputOffset) += output;
// We must iterate over each element of the output and manually
// re-insert the stride.
size_t col = padWLeft;
for (size_t i = 0; i < output.n_cols; ++i)
{
size_t row = padHTop;
for (size_t j = 0; j < output.n_rows; ++j)
{
gTemp(row, col, inMap + fullInputOffset) += output(j, i);
row += strideHeight;
}
col += strideWidth;
}
}
}
}
@@ -461,4 +461,36 @@ TEST_CASE("Issue2986", "[ConvolutionalNetworkTest]")
REQUIRE_NOTHROW(c.Forward(input, output));
REQUIRE_NOTHROW(c.Backward(input, output, delta));
// Now test with a stride of 3.
c = Convolution(1, 3, 3, 3, 3, 0, 0);
// Set up the layer without an enclosing FFN.
c.InputDimensions() = std::vector<size_t>({ 6, 6 });
c.ComputeOutputDimensions();
weights.set_size(c.WeightSize(), 1);
weights.randu();
c.SetWeights(weights.memptr());
output.set_size(c.OutputSize(), 1);
delta.set_size(input.size());
REQUIRE_NOTHROW(c.Forward(input, output));
REQUIRE_NOTHROW(c.Backward(input, output, delta));
// Now test with different strides for height and width.
c = Convolution(1, 3, 3, 2, 3, 0, 0);
// Set up the layer without an enclosing FFN.
c.InputDimensions() = std::vector<size_t>({ 6, 6 });
c.ComputeOutputDimensions();
weights.set_size(c.WeightSize(), 1);
weights.randu();
c.SetWeights(weights.memptr());
output.set_size(c.OutputSize(), 1);
delta.set_size(input.size());
REQUIRE_NOTHROW(c.Forward(input, output));
REQUIRE_NOTHROW(c.Backward(input, output, delta));
}