@@ -5,7 +5,6 @@
5module Test.Grenade.Layers.Convolution where
5module Test.Grenade.Layers.Convolution where
7import Grenade.Core.Shape
7import Grenade.Core.Shape
8โimport Grenade.Core.Vector as Grenade
9import Grenade.Core.Network
8import Grenade.Core.Network
10import Grenade.Layers.Convolution
9import Grenade.Layers.Convolution
11import Grenade.Layers.Internal.Convolution
10import Grenade.Layers.Internal.Convolution
@@ -27,7 +26,7 @@ prop_im2col_no_stride = once $
27 , 5.0, 6.0, 9.0, 10.0
26 , 5.0, 6.0, 9.0, 10.0
28 , 6.0, 7.0, 10.0, 11.0
27 , 6.0, 7.0, 10.0, 11.0
29 , 7.0, 8.0, 11.0, 12.0 ]
28 , 7.0, 8.0, 11.0, 12.0 ]
30โ out = im2colUnsafe 2 2 1 1 input
29+ out = im2col 2 2 1 1 input
31 in expected === out
30 in expected === out
33prop_im2col_stride = once $
32prop_im2col_stride = once $
@@ -40,7 +39,7 @@ prop_im2col_stride = once $
40 , 3.0, 4.0, 7.0, 8.0
39 , 3.0, 4.0, 7.0, 8.0
41 , 5.0, 6.0, 9.0, 10.0
40 , 5.0, 6.0, 9.0, 10.0
42 , 7.0, 8.0, 11.0, 12.0 ]
41 , 7.0, 8.0, 11.0, 12.0 ]
43โ out = im2colUnsafe 2 2 1 2 input
42+ out = im2col 2 2 1 2 input
44 in expected === out
43 in expected === out
46prop_im2col_other = once $
45prop_im2col_other = once $
@@ -51,7 +50,7 @@ prop_im2col_other = once $
51 expected = (2><6)
50 expected = (2><6)
52 [ 1.0, 2.0, 5.0, 6.0 , 9.0, 10.0
51 [ 1.0, 2.0, 5.0, 6.0 , 9.0, 10.0
53 , 3.0, 4.0, 7.0, 8.0 , 11.0 ,12.0 ]
52 , 3.0, 4.0, 7.0, 8.0 , 11.0 ,12.0 ]
54โ out = im2colUnsafe 3 2 1 2 input
53+ out = im2col 3 2 1 2 input
55 in expected === out
54 in expected === out
57-- If there's no overlap (stride is the same size as the kernel)
56-- If there's no overlap (stride is the same size as the kernel)
@@ -61,20 +60,9 @@ prop_im2col_sym_on_same_stride = once $
61 [ 1.0, 2.0, 3.0, 4.0
60 [ 1.0, 2.0, 3.0, 4.0
62 , 5.0, 6.0, 7.0, 8.0
61 , 5.0, 6.0, 7.0, 8.0
63 , 9.0, 10.0, 11.0, 12.0 ]
62 , 9.0, 10.0, 11.0, 12.0 ]
64โ out = col2imUnsafe 3 2 3 2 3 4 . im2colUnsafe 3 2 3 2 $ input
63+ out = col2im 3 2 3 2 3 4 . im2col 3 2 3 2 $ input
65 in input === out
64 in input === out
67โ-- If there's no overlap (stride is the same size as the kernel)
68โ-- then col2im . im2col should be symmetric.
69โprop_im2colunsafe_sym_on_same_stride = once $
71โ [ 1.0, 2.0, 3.0, 4.0
72โ , 5.0, 6.0, 7.0, 8.0
73โ , 9.0, 10.0, 11.0, 12.0 ]
74โ out = col2imUnsafe 3 2 3 2 3 4 . im2colUnsafe 3 2 3 2 $ input
78-- If there is an overlap, then the gradient passed back should be
66-- If there is an overlap, then the gradient passed back should be
79-- the sum of the gradients across the filters.
67-- the sum of the gradients across the filters.
80prop_im2col_col2im_additive = once $
68prop_im2col_col2im_additive = once $
@@ -86,7 +74,7 @@ prop_im2col_col2im_additive = once $
86 [ 1.0, 2.0, 2.0, 1.0
74 [ 1.0, 2.0, 2.0, 1.0
87 , 2.0, 4.0, 4.0, 2.0
75 , 2.0, 4.0, 4.0, 2.0
88 , 1.0, 2.0, 2.0, 1.0 ]
76 , 1.0, 2.0, 2.0, 1.0 ]
89โ out = col2imUnsafe 2 2 1 1 3 4 . im2colUnsafe 2 2 1 1 $ input
77+ out = col2im 2 2 1 1 3 4 . im2col 2 2 1 1 $ input
90 in expected === out
78 in expected === out
92prop_simple_conv_forwards = once $
80prop_simple_conv_forwards = once $
@@ -116,25 +104,18 @@ prop_simple_conv_forwards = once $
116 [ 1.0, 2.0, 5.0
104 [ 1.0, 2.0, 5.0
117 , 3.0, 4.0, 6.0] :: HStatic.L 2 3)
105 , 3.0, 4.0, 6.0] :: HStatic.L 2 3)
119โ expect = [ HStatic.matrix
107+ expect = HStatic.matrix
120โ [ -3.0 , -4.0 ] :: HStatic.L 1 2
108+ [ -3.0 , -4.0
122โ [ -1.0 , 1.0 ] :: HStatic.L 1 2
109+ , -1.0 , 1.0
124โ [ 5.0 , 9.0 ] :: HStatic.L 1 2
110+ , 5.0 , 9.0
126โ [ -7.0 , -10.0 ] :: HStatic.L 1 2] :: [HStatic.L 1 2]
111+ , -7.0 , -10.0 ] :: HStatic.L 4 2
127 out = runForwards convLayer input :: S' ('D3 1 2 4)
112 out = runForwards convLayer input :: S' ('D3 1 2 4)
129โ grad = S3D' ( mkVector
130โ [ HStatic.matrix
114+ grad = S3D' ( HStatic.matrix
131โ [ 1 , 0 ] :: HStatic.L 1 2
115+ [ 1 , 0
132โ , HStatic.matrix
116+ , 0 , 0
133โ [ 0 , 0 ] :: HStatic.L 1 2
117+ , 0 , 0
135โ [ 0 , 0 ] :: HStatic.L 1 2
137โ [ 0 , 1 ] :: HStatic.L 1 2] ) :: S' ('D3 1 2 4)
118+ , 0 , 1 ] :: HStatic.L 4 2 ) :: S' ('D3 1 2 4)
139 expectBack = (HStatic.matrix
120 expectBack = (HStatic.matrix
140 [ 1.0, 0.0, 0.0
121 [ 1.0, 0.0, 0.0
@@ -143,19 +124,19 @@ prop_simple_conv_forwards = once $
144 in case (out, inX, nc) of
125 in case (out, inX, nc) of
145 (S3D' out' , S2D' inX', Convolution' backGrad)
126 (S3D' out' , S2D' inX', Convolution' backGrad)
146โ -> ((HStatic.extract <$> expect) === (HStatic.extract <$> vecToList out'))
127+ -> (HStatic.extract expect === HStatic.extract out')
147 .&&. (HStatic.extract expectBack === HStatic.extract inX')
128 .&&. (HStatic.extract expectBack === HStatic.extract inX')
148 .&&. (HStatic.extract expectedGradient === HStatic.extract backGrad)
129 .&&. (HStatic.extract expectedGradient === HStatic.extract backGrad)
150prop_vid2col_no_stride = once $
131prop_vid2col_no_stride = once $
151โ let input = [(3><4)
132+ let input = (6><4)
152 [ 1.0, 2.0, 3.0, 4.0
133 [ 1.0, 2.0, 3.0, 4.0
153 , 5.0, 6.0, 7.0, 8.0
134 , 5.0, 6.0, 7.0, 8.0
154โ , 9.0, 10.0, 11.0, 12.0 ]
135+ , 9.0, 10.0, 11.0, 12.0
155โ , (3><4)
136+ -- -- --
156โ [ 21.0, 22.0, 23.0, 24.0
137+ , 21.0, 22.0, 23.0, 24.0
157 , 25.0, 26.0, 27.0, 28.0
138 , 25.0, 26.0, 27.0, 28.0
158โ , 29.0, 30.0, 31.0, 32.0 ] ]
139+ , 29.0, 30.0, 31.0, 32.0 ]
159 expected = (6><8)
140 expected = (6><8)
160 [ 1.0, 2.0, 5.0, 6.0 , 21.0, 22.0, 25.0, 26.0
141 [ 1.0, 2.0, 5.0, 6.0 , 21.0, 22.0, 25.0, 26.0
161 , 2.0, 3.0, 6.0, 7.0 , 22.0, 23.0, 26.0, 27.0
142 , 2.0, 3.0, 6.0, 7.0 , 22.0, 23.0, 26.0, 27.0
@@ -163,36 +144,36 @@ prop_vid2col_no_stride = once $
163 , 5.0, 6.0, 9.0, 10.0 , 25.0, 26.0, 29.0, 30.0
144 , 5.0, 6.0, 9.0, 10.0 , 25.0, 26.0, 29.0, 30.0
164 , 6.0, 7.0, 10.0, 11.0 , 26.0, 27.0, 30.0, 31.0
145 , 6.0, 7.0, 10.0, 11.0 , 26.0, 27.0, 30.0, 31.0
165 , 7.0, 8.0, 11.0, 12.0 , 27.0, 28.0, 31.0, 32.0 ]
146 , 7.0, 8.0, 11.0, 12.0 , 27.0, 28.0, 31.0, 32.0 ]
166โ out = vid2colUnsafe 2 2 1 1 3 4 input
147+ out_c = vid2col 2 2 1 1 3 4 input
167โ in expected === out
148+ in expected === out_c
169prop_vid2col_stride = once $
150prop_vid2col_stride = once $
170โ let input = [(3><4)
151+ let input = (6><4)
171 [ 1.0, 2.0, 3.0, 4.0
152 [ 1.0, 2.0, 3.0, 4.0
172 , 5.0, 6.0, 7.0, 8.0
153 , 5.0, 6.0, 7.0, 8.0
173โ , 9.0, 10.0, 11.0, 12.0 ]
154+ , 9.0, 10.0, 11.0, 12.0
174โ , (3><4)
155+ -- -- -- -- --
175โ [ 21.0, 22.0, 23.0, 24.0
156+ , 21.0, 22.0, 23.0, 24.0
176 , 25.0, 26.0, 27.0, 28.0
157 , 25.0, 26.0, 27.0, 28.0
177โ , 29.0, 30.0, 31.0, 32.0 ] ]
158+ , 29.0, 30.0, 31.0, 32.0 ]
178 expected = (4><8)
159 expected = (4><8)
179 [ 1.0, 2.0, 5.0, 6.0 , 21.0, 22.0, 25.0, 26.0
160 [ 1.0, 2.0, 5.0, 6.0 , 21.0, 22.0, 25.0, 26.0
180 , 3.0, 4.0, 7.0, 8.0 , 23.0, 24.0, 27.0, 28.0
161 , 3.0, 4.0, 7.0, 8.0 , 23.0, 24.0, 27.0, 28.0
181 , 5.0, 6.0, 9.0, 10.0 , 25.0, 26.0, 29.0, 30.0
162 , 5.0, 6.0, 9.0, 10.0 , 25.0, 26.0, 29.0, 30.0
182 , 7.0, 8.0, 11.0, 12.0 , 27.0, 28.0, 31.0, 32.0 ]
163 , 7.0, 8.0, 11.0, 12.0 , 27.0, 28.0, 31.0, 32.0 ]
183โ out = vid2colUnsafe 2 2 1 2 3 4 input
164+ out_c = vid2col 2 2 1 2 3 4 input
184โ in expected === out
165+ in expected === out_c
186prop_vid2col_invert = once $
167prop_vid2col_invert = once $
187โ let input = [(3><4)
168+ let input = (6><4)
188 [ 1.0, 2.0, 3.0, 4.0
169 [ 1.0, 2.0, 3.0, 4.0
189 , 5.0, 6.0, 7.0, 8.0
170 , 5.0, 6.0, 7.0, 8.0
190โ , 9.0, 10.0, 11.0, 12.0 ]
171+ , 9.0, 10.0, 11.0, 12.0
191โ , (3><4)
172+ -- -- -- -- --
192โ [ 21.0, 22.0, 23.0, 24.0
173+ , 21.0, 22.0, 23.0, 24.0
193 , 25.0, 26.0, 27.0, 28.0
174 , 25.0, 26.0, 27.0, 28.0
194โ , 29.0, 30.0, 31.0, 32.0 ] ]
175+ , 29.0, 30.0, 31.0, 32.0 ]
195โ out = col2vidUnsafe 3 2 3 2 3 4 . vid2colUnsafe 3 2 3 2 3 4 $ input
176+ out = col2vid 3 2 3 2 3 4 . vid2col 3 2 3 2 3 4 $ input
196 in input === out
177 in input === out
@@ -221,29 +202,22 @@ prop_single_conv_forwards = once $
222 convLayer = Convolution myKernel zeroKernel :: Convolution 1 4 2 2 1 1
203 convLayer = Convolution myKernel zeroKernel :: Convolution 1 4 2 2 1 1
224โ input = S3D' ( mkVector [HStatic.matrix
205+ input = S3D' ( HStatic.matrix
225 [ 1.0, 2.0, 5.0
206 [ 1.0, 2.0, 5.0
226โ , 3.0, 4.0, 6.0] :: HStatic.L 2 3] ) :: S' ('D3 2 3 1)
207+ , 3.0, 4.0, 6.0] :: HStatic.L 2 3 ) :: S' ('D3 2 3 1)
228โ expect = [HStatic.matrix
209+ expect = HStatic.matrix
229โ [ -3.0 , -4.0 ] :: HStatic.L 1 2
210+ [ -3.0 , -4.0
231โ [ -1.0 , 1.0 ] :: HStatic.L 1 2
211+ , -1.0 , 1.0
233โ [ 5.0 , 9.0 ] :: HStatic.L 1 2
212+ , 5.0 , 9.0
235โ [ -7.0 , -10.0 ] :: HStatic.L 1 2] :: [HStatic.L 1 2]
213+ , -7.0 , -10.0 ] :: HStatic.L 4 2
236 out = runForwards convLayer input :: S' ('D3 1 2 4)
214 out = runForwards convLayer input :: S' ('D3 1 2 4)
238โ grad = S3D' ( mkVector
239โ [HStatic.matrix
216+ grad = S3D' (HStatic.matrix
240โ [ 1 , 0 ] :: HStatic.L 1 2
217+ [ 1 , 0
241โ ,HStatic.matrix
218+ , 0 , 0
242โ [ 0 , 0 ] :: HStatic.L 1 2
219+ , 0 , 0
244โ [ 0 , 0 ] :: HStatic.L 1 2
246โ [ 0 , 1 ] :: HStatic.L 1 2] ) :: S' ('D3 1 2 4)
220+ , 0 , 1 ] :: HStatic.L 4 2 ) :: S' ('D3 1 2 4)
248 expectBack = (HStatic.matrix
222 expectBack = (HStatic.matrix
249 [ 1.0, 0.0, 0.0
223 [ 1.0, 0.0, 0.0
@@ -252,8 +226,8 @@ prop_single_conv_forwards = once $
253 in case (out, inX, nc) of
227 in case (out, inX, nc) of
254 (S3D' out' , S3D' inX', Convolution' backGrad)
228 (S3D' out' , S3D' inX', Convolution' backGrad)
255โ -> ((HStatic.extract <$> expect) === (HStatic.extract <$> vecToList out'))
229+ -> (HStatic.extract expect === HStatic.extract out')
256โ .&&. ([HStatic.extract expectBack] === (HStatic.extract <$> vecToList inX'))
230+ .&&. (HStatic.extract expectBack === HStatic.extract inX')
257 .&&. (HStatic.extract expectedGradient === HStatic.extract backGrad)
231 .&&. (HStatic.extract expectedGradient === HStatic.extract backGrad)