| 150 | } |
| 151 | |
| 152 | fn backprop(&self, output: &[f64], target: &[f64], av_zv: &(Vec<Vec<f64>>, Vec<Vec<f64>>)) -> Vec<Vec<f64>> { |
| 153 | |
| 154 | assert!(self.layers.len() >= 2, "At least two layers are required."); |
| 155 | assert!(output.len() == self.output_size(), "Dimension of output vector does not match."); |
| 156 | assert!(target.len() == self.output_size(), "Dimension of output vector does not match."); |
| 157 | assert!(av_zv.0.len() == self.layers(), "Invalid dimension of vectors in av_zv."); |
| 158 | assert!(av_zv.1.len() == self.layers(), "Invalid dimension of vectors in av_zv."); |
| 159 | |
| 160 | //let ref av = av_zv.0; |
| 161 | let ref zv = av_zv.1; |
| 162 | let mut deltas = vec![]; |
| 163 | |
| 164 | let mut pos = (1..self.layers()).collect::<Vec<usize>>(); |
| 165 | |
| 166 | // error of output layer |
| 167 | let p = pos.pop().unwrap(); |
| 168 | deltas.push(output.sub(&target).mul(&zv[p].sigmoid_derivative())); |
| 169 | |
| 170 | // error of hidden layers |
| 171 | while pos.len() > 0 { |
| 172 | let p = pos.pop().unwrap(); |
| 173 | let mut v = self.params[p].transp_mul_vec(&deltas.last().unwrap()); |
| 174 | v.remove(0); |
| 175 | deltas.push(v.mul(&zv[p].sigmoid_derivative())); |
| 176 | } |
| 177 | |
| 178 | // the first entry is the delta vector for the output layer |
| 179 | deltas |
| 180 | } |
| 181 | |
| 182 | fn update(&self, acc: &mut Vec<Matrix<f64>>, deltas: &Vec<Vec<f64>>, a: &Vec<Vec<f64>>) { |
| 183 | |