1
1
#![ allow( unused_imports) ]
2
+ #![ allow( non_snake_case) ]
2
3
3
4
use crate :: ann:: activation:: Activation ;
4
5
use crate :: ann:: minibatch:: Minibatch ;
@@ -21,8 +22,24 @@ impl QuadraticCost {
21
22
// SS: a are the output layer activations
22
23
let diff = y - a;
23
24
let diff2 = ops:: hadamard ( & diff, & diff) ;
24
- diff2. iter ( ) . sum ( )
25
+ diff2. iter ( ) . sum ( ) as f64 / 2.0
25
26
}
27
+
28
+ fn numerical_derivative ( a : & Vector , index : usize , y : & Vector ) -> f64 {
29
+ // SS: numerically calculate dC/da_{index}^{L}
30
+ let delta = 0.000_001 ;
31
+
32
+ let mut a_mut = a. clone ( ) ;
33
+ a_mut[ index] = a[ index] - delta;
34
+ let c1 = QuadraticCost :: single_cost ( & a_mut, y) ;
35
+
36
+ a_mut[ index] = a[ index] + delta;
37
+ let c2 = QuadraticCost :: single_cost ( & a_mut, y) ;
38
+
39
+ let dc = ( c2 - c1) / delta / 2_f64 ;
40
+ dc
41
+ }
42
+
26
43
}
27
44
28
45
impl CostFunction for QuadraticCost {
@@ -107,7 +124,7 @@ impl CostFunction for CrossEntropyCost {
107
124
let t3 = t1 + t2;
108
125
dCda[ i] = t3;
109
126
}
110
- dCda /
127
+ dCda
111
128
}
112
129
}
113
130
@@ -185,6 +202,20 @@ mod tests {
185
202
assert_eq ! ( 8.0 , c)
186
203
}
187
204
205
+ #[ test]
206
+ fn test_quadratic_cost_derivative ( ) {
207
+ // Arrange
208
+ let a = vec ! [ 1.0 , 2.0 ] . into ( ) ;
209
+ let y = vec ! [ 3.0 , 4.0 ] . into ( ) ;
210
+
211
+ // Act
212
+ let dc_numeric = QuadraticCost :: numerical_derivative ( & a, 0 , & y) ;
213
+ let dc_analytical = QuadraticCost { } . output_error ( & a, & y) ;
214
+
215
+ // Assert
216
+ assert_approx_eq ! ( dc_analytical[ 0 ] , dc_numeric, 1E-4 ) ;
217
+ }
218
+
188
219
#[ test]
189
220
fn test_quadratic_cost_output_layer ( ) {
190
221
// Arrange
0 commit comments