feat: update workspace paths and enhance gitignore
- Updated stablediffusion crate path from "../stable-diffusion-burn" to "./crates/stable-diffusion-burn" for proper workspace resolution - Enhanced .gitignore to include generated model files (.mpk, .pt, .bin, .safetensors, .ckpt) and user_data directory - Added Cargo.lock to gitignore with appropriate comment - Reorganized IDE files section in gitignore for better clarity - Added newline at end of file for proper formatting
This commit is contained in:
@@ -0,0 +1,962 @@
|
||||
use super::*;
|
||||
use burn_tensor::{Shape, Tolerance, module::conv2d, ops::ConvOptions};
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_basic() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 2,
|
||||
channels_in: 2,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 1,
|
||||
stride_1: 1,
|
||||
stride_2: 1,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 1,
|
||||
height: 4,
|
||||
width: 4,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[
|
||||
[88., 138., 138., 96.],
|
||||
[150., 234., 234., 162.],
|
||||
[150., 234., 234., 162.],
|
||||
[112., 174., 174., 120.],
|
||||
],
|
||||
[
|
||||
[160., 246., 246., 168.],
|
||||
[258., 396., 396., 270.],
|
||||
[258., 396., 396., 270.],
|
||||
[184., 282., 282., 192.],
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
[88., 138., 138., 96.],
|
||||
[150., 234., 234., 162.],
|
||||
[150., 234., 234., 162.],
|
||||
[112., 174., 174., 120.],
|
||||
],
|
||||
[
|
||||
[160., 246., 246., 168.],
|
||||
[258., 396., 396., 270.],
|
||||
[258., 396., 396., 270.],
|
||||
[184., 282., 282., 192.],
|
||||
],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[378., 516., 396.], [552., 752., 576.], [450., 612., 468.]],
|
||||
[[666., 900., 684.], [936., 1264., 960.], [738., 996., 756.]],
|
||||
],
|
||||
[
|
||||
[[378., 516., 396.], [552., 752., 576.], [450., 612., 468.]],
|
||||
[[666., 900., 684.], [936., 1264., 960.], [738., 996., 756.]],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([32., 32.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_different_channels() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 2,
|
||||
channels_in: 2,
|
||||
channels_out: 3,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 1,
|
||||
stride_1: 1,
|
||||
stride_2: 1,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 1,
|
||||
height: 4,
|
||||
width: 4,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[
|
||||
[240., 369., 369., 252.],
|
||||
[387., 594., 594., 405.],
|
||||
[387., 594., 594., 405.],
|
||||
[276., 423., 423., 288.],
|
||||
],
|
||||
[
|
||||
[348., 531., 531., 360.],
|
||||
[549., 837., 837., 567.],
|
||||
[549., 837., 837., 567.],
|
||||
[384., 585., 585., 396.],
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
[240., 369., 369., 252.],
|
||||
[387., 594., 594., 405.],
|
||||
[387., 594., 594., 405.],
|
||||
[276., 423., 423., 288.],
|
||||
],
|
||||
[
|
||||
[348., 531., 531., 360.],
|
||||
[549., 837., 837., 567.],
|
||||
[549., 837., 837., 567.],
|
||||
[384., 585., 585., 396.],
|
||||
],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[378., 516., 396.], [552., 752., 576.], [450., 612., 468.]],
|
||||
[[666., 900., 684.], [936., 1264., 960.], [738., 996., 756.]],
|
||||
],
|
||||
[
|
||||
[[378., 516., 396.], [552., 752., 576.], [450., 612., 468.]],
|
||||
[[666., 900., 684.], [936., 1264., 960.], [738., 996., 756.]],
|
||||
],
|
||||
[
|
||||
[[378., 516., 396.], [552., 752., 576.], [450., 612., 468.]],
|
||||
[[666., 900., 684.], [936., 1264., 960.], [738., 996., 756.]],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([32., 32., 32.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_different_kernel_size() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 2,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 4,
|
||||
padding_1: 1,
|
||||
padding_2: 1,
|
||||
stride_1: 1,
|
||||
stride_2: 1,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 1,
|
||||
height: 4,
|
||||
width: 4,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[116., 180., 192., 132.],
|
||||
[198., 306., 324., 222.],
|
||||
[198., 306., 324., 222.],
|
||||
[148., 228., 240., 164.],
|
||||
],
|
||||
[
|
||||
[212., 324., 336., 228.],
|
||||
[342., 522., 540., 366.],
|
||||
[342., 522., 540., 366.],
|
||||
[244., 372., 384., 260.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[
|
||||
[27., 45., 54., 39.],
|
||||
[52., 84., 96., 68.],
|
||||
[51., 81., 90., 63.],
|
||||
],
|
||||
[
|
||||
[123., 189., 198., 135.],
|
||||
[180., 276., 288., 196.],
|
||||
[147., 225., 234., 159.],
|
||||
],
|
||||
],
|
||||
[
|
||||
[
|
||||
[27., 45., 54., 39.],
|
||||
[52., 84., 96., 68.],
|
||||
[51., 81., 90., 63.],
|
||||
],
|
||||
[
|
||||
[123., 189., 198., 135.],
|
||||
[180., 276., 288., 196.],
|
||||
[147., 225., 234., 159.],
|
||||
],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([12., 12.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_different_padding() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 2,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 2,
|
||||
stride_1: 1,
|
||||
stride_2: 1,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 1,
|
||||
height: 4,
|
||||
width: 4,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[138., 138., 138., 138.],
|
||||
[234., 234., 234., 234.],
|
||||
[234., 234., 234., 234.],
|
||||
[174., 174., 174., 174.],
|
||||
],
|
||||
[
|
||||
[246., 246., 246., 246.],
|
||||
[396., 396., 396., 396.],
|
||||
[396., 396., 396., 396.],
|
||||
[282., 282., 282., 282.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[66., 66., 66.], [120., 120., 120.], [114., 114., 114.]],
|
||||
[[258., 258., 258.], [376., 376., 376.], [306., 306., 306.]],
|
||||
],
|
||||
[
|
||||
[[66., 66., 66.], [120., 120., 120.], [114., 114., 114.]],
|
||||
[[258., 258., 258.], [376., 376., 376.], [306., 306., 306.]],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([24., 24.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_different_width() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 2,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 1,
|
||||
stride_1: 1,
|
||||
stride_2: 1,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 1,
|
||||
height: 4,
|
||||
width: 5,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[88., 138., 138., 138., 96.],
|
||||
[150., 234., 234., 234., 162.],
|
||||
[150., 234., 234., 234., 162.],
|
||||
[112., 174., 174., 174., 120.],
|
||||
],
|
||||
[
|
||||
[160., 246., 246., 246., 168.],
|
||||
[258., 396., 396., 396., 270.],
|
||||
[258., 396., 396., 396., 270.],
|
||||
[184., 282., 282., 282., 192.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[78., 105., 90.], [144., 190., 160.], [138., 180., 150.]],
|
||||
[[318., 405., 330.], [464., 590., 480.], [378., 480., 390.]],
|
||||
],
|
||||
[
|
||||
[[78., 105., 90.], [144., 190., 160.], [138., 180., 150.]],
|
||||
[[318., 405., 330.], [464., 590., 480.], [378., 480., 390.]],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([20., 20.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_stride_2() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 2,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 1,
|
||||
stride_1: 2,
|
||||
stride_2: 2,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 1,
|
||||
height: 6,
|
||||
width: 6,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[26., 52., 26., 52., 26., 28.],
|
||||
[52., 104., 52., 104., 52., 56.],
|
||||
[26., 52., 26., 52., 26., 28.],
|
||||
[52., 104., 52., 104., 52., 56.],
|
||||
[26., 52., 26., 52., 26., 28.],
|
||||
[32., 64., 32., 64., 32., 34.],
|
||||
],
|
||||
[
|
||||
[44., 88., 44., 88., 44., 46.],
|
||||
[88., 176., 88., 176., 88., 92.],
|
||||
[44., 88., 44., 88., 44., 46.],
|
||||
[88., 176., 88., 176., 88., 92.],
|
||||
[44., 88., 44., 88., 44., 46.],
|
||||
[50., 100., 50., 100., 50., 52.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[56., 84., 90.], [84., 126., 135.], [120., 180., 189.]],
|
||||
[[200., 300., 306.], [300., 450., 459.], [336., 504., 513.]],
|
||||
],
|
||||
[
|
||||
[[56., 84., 90.], [84., 126., 135.], [120., 180., 189.]],
|
||||
[[200., 300., 306.], [300., 450., 459.], [336., 504., 513.]],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([9., 9.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_different_stride() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 2,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 1,
|
||||
stride_1: 3,
|
||||
stride_2: 1,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 1,
|
||||
height: 8,
|
||||
width: 8,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[50., 78., 78., 78., 78., 78., 78., 54.],
|
||||
[62., 96., 96., 96., 96., 96., 96., 66.],
|
||||
[38., 60., 60., 60., 60., 60., 60., 42.],
|
||||
[50., 78., 78., 78., 78., 78., 78., 54.],
|
||||
[62., 96., 96., 96., 96., 96., 96., 66.],
|
||||
[38., 60., 60., 60., 60., 60., 60., 42.],
|
||||
[50., 78., 78., 78., 78., 78., 78., 54.],
|
||||
[62., 96., 96., 96., 96., 96., 96., 66.],
|
||||
],
|
||||
[
|
||||
[86., 132., 132., 132., 132., 132., 132., 90.],
|
||||
[98., 150., 150., 150., 150., 150., 150., 102.],
|
||||
[74., 114., 114., 114., 114., 114., 114., 78.],
|
||||
[86., 132., 132., 132., 132., 132., 132., 90.],
|
||||
[98., 150., 150., 150., 150., 150., 150., 102.],
|
||||
[74., 114., 114., 114., 114., 114., 114., 78.],
|
||||
[86., 132., 132., 132., 132., 132., 132., 90.],
|
||||
[98., 150., 150., 150., 150., 150., 150., 102.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[434., 504., 448.], [567., 660., 588.], [735., 852., 756.]],
|
||||
[
|
||||
[1330., 1528., 1344.],
|
||||
[1911., 2196., 1932.],
|
||||
[2079., 2388., 2100.],
|
||||
],
|
||||
],
|
||||
[
|
||||
[[434., 504., 448.], [567., 660., 588.], [735., 852., 756.]],
|
||||
[
|
||||
[1330., 1528., 1344.],
|
||||
[1911., 2196., 1932.],
|
||||
[2079., 2388., 2100.],
|
||||
],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([24., 24.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_dilation_2() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 2,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 1,
|
||||
stride_1: 1,
|
||||
stride_2: 1,
|
||||
dilation_1: 2,
|
||||
dilation_2: 2,
|
||||
groups: 1,
|
||||
height: 6,
|
||||
width: 6,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[18., 38., 38., 42., 42., 22.],
|
||||
[42., 88., 88., 96., 96., 50.],
|
||||
[42., 88., 88., 96., 96., 50.],
|
||||
[54., 112., 112., 120., 120., 62.],
|
||||
[54., 112., 112., 120., 120., 62.],
|
||||
[30., 62., 62., 66., 66., 34.],
|
||||
],
|
||||
[
|
||||
[36., 74., 74., 78., 78., 40.],
|
||||
[78., 160., 160., 168., 168., 86.],
|
||||
[78., 160., 160., 168., 168., 86.],
|
||||
[90., 184., 184., 192., 192., 98.],
|
||||
[90., 184., 184., 192., 192., 98.],
|
||||
[48., 98., 98., 102., 102., 52.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[63., 102., 90.], [192., 280., 228.], [225., 318., 252.]],
|
||||
[[387., 534., 414.], [624., 856., 660.], [549., 750., 576.]],
|
||||
],
|
||||
[
|
||||
[[63., 102., 90.], [192., 280., 228.], [225., 318., 252.]],
|
||||
[[387., 534., 414.], [624., 856., 660.], [549., 750., 576.]],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([16., 16.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_different_dilation() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 2,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 1,
|
||||
stride_1: 1,
|
||||
stride_2: 1,
|
||||
dilation_1: 2,
|
||||
dilation_2: 3,
|
||||
groups: 1,
|
||||
height: 6,
|
||||
width: 6,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[18., 0., 20., 20., 0., 22.],
|
||||
[42., 0., 46., 46., 0., 50.],
|
||||
[42., 0., 46., 46., 0., 50.],
|
||||
[54., 0., 58., 58., 0., 62.],
|
||||
[54., 0., 58., 58., 0., 62.],
|
||||
[30., 0., 32., 32., 0., 34.],
|
||||
],
|
||||
[
|
||||
[36., 0., 38., 38., 0., 40.],
|
||||
[78., 0., 82., 82., 0., 86.],
|
||||
[78., 0., 82., 82., 0., 86.],
|
||||
[90., 0., 94., 94., 0., 98.],
|
||||
[90., 0., 94., 94., 0., 98.],
|
||||
[48., 0., 50., 50., 0., 52.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[18., 51., 33.], [60., 140., 80.], [72., 159., 87.]],
|
||||
[[126., 267., 141.], [204., 428., 224.], [180., 375., 195.]],
|
||||
],
|
||||
[
|
||||
[[18., 51., 33.], [60., 140., 80.], [72., 159., 87.]],
|
||||
[[126., 267., 141.], [204., 428., 224.], [180., 375., 195.]],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([8., 8.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_groups() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 2,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 0,
|
||||
padding_2: 0,
|
||||
stride_1: 1,
|
||||
stride_2: 1,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 2,
|
||||
height: 5,
|
||||
width: 5,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[0., 1., 3., 3., 2.],
|
||||
[3., 8., 15., 12., 7.],
|
||||
[9., 21., 36., 27., 15.],
|
||||
[9., 20., 33., 24., 13.],
|
||||
[6., 13., 21., 15., 8.],
|
||||
],
|
||||
[
|
||||
[9., 19., 30., 21., 11.],
|
||||
[21., 44., 69., 48., 25.],
|
||||
[36., 75., 117., 81., 42.],
|
||||
[27., 56., 87., 60., 31.],
|
||||
[15., 31., 48., 33., 17.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[[[54., 63., 72.], [99., 108., 117.], [144., 153., 162.]]],
|
||||
[[[279., 288., 297.], [324., 333., 342.], [369., 378., 387.]]],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([9., 9.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_groups_stride_2() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 4,
|
||||
channels_out: 4,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 1,
|
||||
stride_1: 2,
|
||||
stride_2: 2,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 4,
|
||||
height: 4,
|
||||
width: 4,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[4., 8., 4., 5.],
|
||||
[8., 16., 8., 10.],
|
||||
[4., 8., 4., 5.],
|
||||
[7., 14., 7., 8.],
|
||||
],
|
||||
[
|
||||
[13., 26., 13., 14.],
|
||||
[26., 52., 26., 28.],
|
||||
[13., 26., 13., 14.],
|
||||
[16., 32., 16., 17.],
|
||||
],
|
||||
[
|
||||
[22., 44., 22., 23.],
|
||||
[44., 88., 44., 46.],
|
||||
[22., 44., 22., 23.],
|
||||
[25., 50., 25., 26.],
|
||||
],
|
||||
[
|
||||
[31., 62., 31., 32.],
|
||||
[62., 124., 62., 64.],
|
||||
[31., 62., 31., 32.],
|
||||
[34., 68., 34., 35.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[[[5., 10., 12.], [10., 20., 24.], [18., 36., 40.]]],
|
||||
[[[21., 42., 44.], [42., 84., 88.], [50., 100., 104.]]],
|
||||
[[[37., 74., 76.], [74., 148., 152.], [82., 164., 168.]]],
|
||||
[[[53., 106., 108.], [106., 212., 216.], [114., 228., 232.]]],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([4., 4., 4., 4.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_groups_different_channels() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 3,
|
||||
channels_out: 6,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 0,
|
||||
padding_2: 0,
|
||||
stride_1: 1,
|
||||
stride_2: 1,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 3,
|
||||
height: 4,
|
||||
width: 4,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[9., 20., 24., 13.],
|
||||
[24., 52., 60., 32.],
|
||||
[36., 76., 84., 44.],
|
||||
[21., 44., 48., 25.],
|
||||
],
|
||||
[
|
||||
[45., 92., 96., 49.],
|
||||
[96., 196., 204., 104.],
|
||||
[108., 220., 228., 116.],
|
||||
[57., 116., 120., 61.],
|
||||
],
|
||||
[
|
||||
[81., 164., 168., 85.],
|
||||
[168., 340., 348., 176.],
|
||||
[180., 364., 372., 188.],
|
||||
[93., 188., 192., 97.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[[[10., 14., 18.], [26., 30., 34.], [42., 46., 50.]]],
|
||||
[[[10., 14., 18.], [26., 30., 34.], [42., 46., 50.]]],
|
||||
[[[74., 78., 82.], [90., 94., 98.], [106., 110., 114.]]],
|
||||
[[[74., 78., 82.], [90., 94., 98.], [106., 110., 114.]]],
|
||||
[[[138., 142., 146.], [154., 158., 162.], [170., 174., 178.]]],
|
||||
[[[138., 142., 146.], [154., 158., 162.], [170., 174., 178.]]],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([4., 4., 4., 4., 4., 4.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_complex() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 2,
|
||||
channels_out: 3,
|
||||
kernel_size_1: 2,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 1,
|
||||
padding_2: 2,
|
||||
stride_1: 1,
|
||||
stride_2: 2,
|
||||
dilation_1: 2,
|
||||
dilation_2: 3,
|
||||
groups: 1,
|
||||
height: 4,
|
||||
width: 5,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[36., 39., 0., 39., 42.],
|
||||
[81., 87., 0., 87., 93.],
|
||||
[81., 87., 0., 87., 93.],
|
||||
[45., 48., 0., 48., 51.],
|
||||
],
|
||||
[
|
||||
[54., 57., 0., 57., 60.],
|
||||
[117., 123., 0., 123., 129.],
|
||||
[117., 123., 0., 123., 129.],
|
||||
[63., 66., 0., 66., 69.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[15., 42., 27.], [30., 72., 42.]],
|
||||
[[75., 162., 87.], [90., 192., 102.]],
|
||||
],
|
||||
[
|
||||
[[15., 42., 27.], [30., 72., 42.]],
|
||||
[[75., 162., 87.], [90., 192., 102.]],
|
||||
],
|
||||
[
|
||||
[[15., 42., 27.], [30., 72., 42.]],
|
||||
[[75., 162., 87.], [90., 192., 102.]],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([8., 8., 8.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_conv2d_groups_stride_2_no_pad() {
|
||||
let test = Conv2dTestCase {
|
||||
batch_size: 1,
|
||||
channels_in: 4,
|
||||
channels_out: 2,
|
||||
kernel_size_1: 3,
|
||||
kernel_size_2: 3,
|
||||
padding_1: 0,
|
||||
padding_2: 0,
|
||||
stride_1: 2,
|
||||
stride_2: 2,
|
||||
dilation_1: 1,
|
||||
dilation_2: 1,
|
||||
groups: 2,
|
||||
height: 4,
|
||||
width: 4,
|
||||
};
|
||||
let device = Default::default();
|
||||
let grads = Grads {
|
||||
x: TestTensor::from_floats(
|
||||
[[
|
||||
[
|
||||
[0., 1., 2., 0.],
|
||||
[3., 4., 5., 0.],
|
||||
[6., 7., 8., 0.],
|
||||
[0., 0., 0., 0.],
|
||||
],
|
||||
[
|
||||
[9., 10., 11., 0.],
|
||||
[12., 13., 14., 0.],
|
||||
[15., 16., 17., 0.],
|
||||
[0., 0., 0., 0.],
|
||||
],
|
||||
[
|
||||
[18., 19., 20., 0.],
|
||||
[21., 22., 23., 0.],
|
||||
[24., 25., 26., 0.],
|
||||
[0., 0., 0., 0.],
|
||||
],
|
||||
[
|
||||
[27., 28., 29., 0.],
|
||||
[30., 31., 32., 0.],
|
||||
[33., 34., 35., 0.],
|
||||
[0., 0., 0., 0.],
|
||||
],
|
||||
]],
|
||||
&device,
|
||||
),
|
||||
weight: TestTensor::from_floats(
|
||||
[
|
||||
[
|
||||
[[0., 1., 2.], [4., 5., 6.], [8., 9., 10.]],
|
||||
[[16., 17., 18.], [20., 21., 22.], [24., 25., 26.]],
|
||||
],
|
||||
[
|
||||
[[32., 33., 34.], [36., 37., 38.], [40., 41., 42.]],
|
||||
[[48., 49., 50.], [52., 53., 54.], [56., 57., 58.]],
|
||||
],
|
||||
],
|
||||
&device,
|
||||
),
|
||||
bias: TestTensor::from_floats([1., 1.], &device),
|
||||
};
|
||||
test.assert_grads(grads);
|
||||
}
|
||||
|
||||
struct Conv2dTestCase {
|
||||
batch_size: usize,
|
||||
channels_in: usize,
|
||||
channels_out: usize,
|
||||
kernel_size_1: usize,
|
||||
kernel_size_2: usize,
|
||||
padding_1: usize,
|
||||
padding_2: usize,
|
||||
stride_1: usize,
|
||||
stride_2: usize,
|
||||
dilation_1: usize,
|
||||
dilation_2: usize,
|
||||
groups: usize,
|
||||
height: usize,
|
||||
width: usize,
|
||||
}
|
||||
|
||||
struct Grads {
|
||||
x: TestTensor<4>,
|
||||
weight: TestTensor<4>,
|
||||
bias: TestTensor<1>,
|
||||
}
|
||||
|
||||
impl Conv2dTestCase {
|
||||
fn assert_grads(self, expected_grads: Grads) {
|
||||
let shape_x = Shape::new([self.batch_size, self.channels_in, self.height, self.width]);
|
||||
let shape_weight = Shape::new([
|
||||
self.channels_out,
|
||||
self.channels_in / self.groups,
|
||||
self.kernel_size_1,
|
||||
self.kernel_size_2,
|
||||
]);
|
||||
let device = Default::default();
|
||||
let weight = TestAutodiffTensor::from_data(
|
||||
TestTensorInt::arange(0..shape_weight.num_elements() as i64, &device)
|
||||
.reshape::<4, _>(shape_weight)
|
||||
.into_data(),
|
||||
&device,
|
||||
)
|
||||
.require_grad();
|
||||
let bias = TestAutodiffTensor::from_data(
|
||||
TestTensorInt::arange(0..self.channels_out as i64, &device).into_data(),
|
||||
&device,
|
||||
)
|
||||
.require_grad();
|
||||
let x = TestAutodiffTensor::from_data(
|
||||
TestTensorInt::arange(0..shape_x.num_elements() as i64, &device)
|
||||
.reshape::<4, _>(shape_x)
|
||||
.into_data(),
|
||||
&device,
|
||||
)
|
||||
.require_grad();
|
||||
let output = conv2d(
|
||||
x.clone(),
|
||||
weight.clone(),
|
||||
Some(bias.clone()),
|
||||
ConvOptions::new(
|
||||
[self.stride_1, self.stride_2],
|
||||
[self.padding_1, self.padding_2],
|
||||
[self.dilation_1, self.dilation_2],
|
||||
self.groups,
|
||||
),
|
||||
);
|
||||
let grads = output.backward();
|
||||
|
||||
// Assert
|
||||
let x_grad_actual = x.grad(&grads).unwrap();
|
||||
let weight_grad_actual = weight.grad(&grads).unwrap();
|
||||
let bias_grad_actual = bias.grad(&grads).unwrap();
|
||||
|
||||
let tolerance = Tolerance::rel_abs(0.01, 0.01);
|
||||
expected_grads
|
||||
.bias
|
||||
.to_data()
|
||||
.assert_approx_eq::<FloatElem>(&bias_grad_actual.to_data(), tolerance);
|
||||
expected_grads
|
||||
.x
|
||||
.to_data()
|
||||
.assert_approx_eq::<FloatElem>(&x_grad_actual.to_data(), tolerance);
|
||||
expected_grads
|
||||
.weight
|
||||
.to_data()
|
||||
.assert_approx_eq::<FloatElem>(&weight_grad_actual.to_data(), tolerance);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user