pytorch
207 строк · 8.0 Кб
1
2
3
4
5import numpy as np
6from numpy.testing import assert_array_equal
7
8from caffe2.python import core, workspace
9from caffe2.python.test_util import TestCase
10from caffe2.proto import caffe2_pb2
11
12
13class TestLengthsToShapeOps(TestCase):
14def test_lengths_to_shape_ops(self):
15workspace.FeedBlob('l', np.array([200, 200, 200], dtype=np.int32))
16workspace.RunOperatorOnce(core.CreateOperator(
17'LengthsToShape', ['l'], ['s']))
18workspace.FeedBlob('res', np.array([3, 200], dtype=np.int32))
19assert_array_equal(workspace.FetchBlob('s'), workspace.FetchBlob('res'))
20
21def test_reshape_ops(self):
22workspace.FeedBlob('res', np.array([[0, 0, 0, 0]], dtype=np.float32))
23workspace.FeedBlob('shape', np.array([1, 4], dtype=np.int32))
24workspace.FeedBlob('input', np.zeros((2, 2), dtype=np.float32))
25workspace.RunOperatorOnce(core.CreateOperator(
26'Reshape', ['input', 'shape'], ['output', 'old_shape']))
27assert_array_equal(workspace.FetchBlob('output'),
28workspace.FetchBlob('res'))
29
30def test_basic_reshape(self):
31_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(2, 4))
32_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(2, 4), arg_shape=False)
33
34def test_missing_dim(self):
35_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(-1, 8))
36_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(-1, 8), arg_shape=False)
37
38def test_in_place(self):
39_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(-1, 8), in_place=True)
40_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(-1, 8),
41in_place=True, arg_shape=False)
42
43def test_zero_dim(self):
44_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(0, 0, 0),
45expected_shape=(4, 2, 1))
46_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(0, 0, 0),
47expected_shape=(4, 2, 1), arg_shape=False)
48_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(0, 2, 1),
49expected_shape=(4, 2, 1))
50_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(0, 2, 1),
51expected_shape=(4, 2, 1), arg_shape=False)
52_test_reshape_output_and_gradient(old_shape=(0, 0), new_shape=(0, 0, 0),
53expected_shape=(0, 0, 0), arg_shape=False)
54
55def test_zero_dim_and_missing_dim(self):
56_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(0, -1, 0),
57expected_shape=(4, 2, 1))
58_test_reshape_output_and_gradient(old_shape=(4, 2, 1), new_shape=(0, -1, 0),
59expected_shape=(4, 2, 1), arg_shape=False)
60_test_reshape_output_and_gradient(old_shape=(4, 3, 2), new_shape=(-1, 0),
61expected_shape=(8, 3))
62_test_reshape_output_and_gradient(old_shape=(4, 3, 2), new_shape=(-1, 0),
63expected_shape=(8, 3), arg_shape=False)
64
65# empty tensor will just have -1 dim = 0
66_test_reshape_output_and_gradient(
67old_shape=(2, 0),
68new_shape=(-1, 0),
69expected_shape=(0, 0),
70arg_shape=False
71)
72
73def test_backprop(self):
74old_shape = (4, 2, 1)
75new_shape = (1, 8)
76X = np.random.rand(*old_shape).astype(np.float32)
77Y = np.random.rand(*new_shape).astype(np.float32)
78
79net = core.Net('net')
80
81net.GivenTensorFill([], 'X', shape=old_shape, values=X.flatten())
82net.GivenTensorFill([], 'Y', shape=new_shape, values=Y.flatten())
83
84net.Reshape(['X'], ['X_out', 'old_shape'], shape=new_shape)
85net.DotProduct(['X_out', 'Y'], 'Z')
86net.AddGradientOperators(['Z'])
87
88workspace.RunNetOnce(net)
89
90Z = workspace.FetchBlob('Z')
91X_grad = workspace.FetchBlob('X_grad')
92
93# Check forward computation
94np.testing.assert_allclose(
95Z.squeeze(), X.reshape(new_shape).dot(Y.T).squeeze(), rtol=1e-5)
96
97# Check the shape of the gradient
98np.testing.assert_array_equal(X_grad.shape, X.shape)
99
100# Check the gradient
101np.testing.assert_allclose(X_grad, Y.reshape(old_shape), rtol=1e-5)
102
103def test_input_shape_changes(self):
104workspace.FeedBlob(
105'input_blob',
106np.array(np.random.rand(10, 20, 10), dtype=np.float32))
107net = core.Net('mynet')
108z, _ = net.Reshape('input_blob',
109['z_reshape', 'dummy_size'],
110shape=(-1, 10))
111workspace.CreateNet(net)
112workspace.RunNet(net)
113workspace.FeedBlob(
114'input_blob',
115np.array(np.random.rand(10, 40, 10), dtype=np.float32))
116workspace.RunNet(net)
117
118def test_nonempty_tensor_gradient(self):
119old_shape = [4, 2]
120new_shape = [1, 2, -1]
121expected_new_shape = [1, 2, 4]
122_test_reshape_output_and_gradient(
123old_shape=old_shape,
124new_shape=new_shape,
125expected_shape=expected_new_shape,
126expected_gradient=np.ones(shape=old_shape)
127)
128
129def test_empty_tensor(self):
130old_shape = [4, 0]
131new_shape = [1, -1]
132expected_new_shape = [1, 0]
133_test_reshape_output_and_gradient(
134old_shape=old_shape,
135new_shape=new_shape,
136expected_shape=expected_new_shape,
137expected_gradient=np.empty(shape=old_shape)
138)
139
140def test_one_dim_empty_tensor_gradient(self):
141old_shape = (0,)
142new_shape = [1, -1]
143expected_new_shape = [1, 0]
144_test_reshape_output_and_gradient(
145old_shape=old_shape,
146new_shape=new_shape,
147expected_shape=expected_new_shape,
148expected_gradient=np.empty(shape=old_shape)
149)
150
151def test_one_dim_and_empty_tensor(self):
152old_shape = (0,)
153new_shape = [0, -1]
154expected_new_shape = [0, 0]
155_test_reshape_output_and_gradient(old_shape=old_shape, new_shape=new_shape, expected_shape=expected_new_shape)
156
157def test_scalar_to_tensor(self):
158old_shape = ()
159new_shape = [1, -1]
160expected_new_shape = [1, 1]
161_test_reshape_output_and_gradient(old_shape=old_shape, new_shape=new_shape, expected_shape=expected_new_shape)
162
163
164def _test_reshape_output_and_gradient(
165old_shape,
166new_shape,
167expected_shape=None,
168arg_shape=True,
169in_place=False,
170expected_gradient=None
171):
172devices = [core.DeviceOption(caffe2_pb2.CPU, 0)]
173if workspace.NumGpuDevices() > 0:
174devices.append(core.DeviceOption(workspace.GpuDeviceType, 0))
175
176for device_opt in devices:
177with core.DeviceScope(device_opt):
178if expected_shape is None:
179expected_shape = new_shape
180net = core.Net('net')
181
182if len(old_shape) == 0:
183# scalar, convert to tensor before feeding to blob
184X = np.atleast_1d(np.random.rand(*old_shape))
185else:
186X = np.random.rand(*old_shape).astype(np.float32)
187blob_in = 'X'
188blob_out = blob_in if in_place else blob_in + '_out'
189
190if arg_shape:
191out, _ = net.Reshape([blob_in], [blob_out, 'old_shape'], shape=new_shape)
192else:
193out, _ = net.Reshape([blob_in, 'new_shape'], [blob_out, 'old_shape'])
194workspace.FeedBlob('new_shape', np.asarray(new_shape))
195
196workspace.FeedBlob(blob_in, X)
197if expected_gradient is not None:
198net.AddGradientOperators([out])
199workspace.CreateNet(net)
200workspace.RunNetOnce(net)
201
202Y = workspace.FetchBlob(blob_out)
203np.testing.assert_allclose(Y, X.reshape(expected_shape))
204if expected_gradient is not None:
205data_grad = workspace.FetchBlob(blob_in + '_grad')
206np.testing.assert_array_equal(data_grad, expected_gradient)
207
208
209if __name__ == "__main__":
210import unittest
211unittest.main()
212