| 271 | } |
| 272 | |
| 273 | void Adam::update(UInt64 batch_size, std::vector<Float64> & weights, Float64 & bias, Float64 learning_rate, const std::vector<Float64> & batch_gradient) |
| 274 | { |
| 275 | if (average_gradient.empty()) |
| 276 | { |
| 277 | if (!average_squared_gradient.empty()) |
| 278 | throw Exception("Average_gradient and average_squared_gradient must have same size", ErrorCodes::LOGICAL_ERROR); |
| 279 | |
| 280 | average_gradient.resize(batch_gradient.size(), Float64{0.0}); |
| 281 | average_squared_gradient.resize(batch_gradient.size(), Float64{0.0}); |
| 282 | } |
| 283 | |
| 284 | for (size_t i = 0; i != average_gradient.size(); ++i) |
| 285 | { |
| 286 | Float64 normed_gradient = batch_gradient[i] / batch_size; |
| 287 | average_gradient[i] = beta1 * average_gradient[i] + (1 - beta1) * normed_gradient; |
| 288 | average_squared_gradient[i] = beta2 * average_squared_gradient[i] + |
| 289 | (1 - beta2) * normed_gradient * normed_gradient; |
| 290 | } |
| 291 | |
| 292 | for (size_t i = 0; i < weights.size(); ++i) |
| 293 | { |
| 294 | weights[i] += (learning_rate * average_gradient[i]) / |
| 295 | ((1 - beta1_powered) * (sqrt(average_squared_gradient[i] / (1 - beta2_powered)) + eps)); |
| 296 | } |
| 297 | bias += (learning_rate * average_gradient[weights.size()]) / |
| 298 | ((1 - beta1_powered) * (sqrt(average_squared_gradient[weights.size()] / (1 - beta2_powered)) + eps)); |
| 299 | |
| 300 | beta1_powered *= beta1; |
| 301 | beta2_powered *= beta2; |
| 302 | } |
| 303 | |
| 304 | void Adam::addToBatch( |
| 305 | std::vector<Float64> & batch_gradient, |
no test coverage detected