One of the functor of BP_Multi_Thread().
| 303 | |
| 304 | // One of the functor of BP_Multi_Thread(). |
| 305 | void Individual::BP_Multi_Thread_Core(uint32_t start, uint32_t end) { |
| 306 | auto ci = this->clone(); |
| 307 | |
| 308 | float output[outputNum]; |
| 309 | std::map<uint32_t, float> gradient; // Store the gradient of all nodes. |
| 310 | for (uint32_t z = start; z < end; ++z) { |
| 311 | uint32_t data_p = 0; |
| 312 | ci->forward(ci->args->inputArray[z], output); |
| 313 | |
| 314 | gradient.clear(); |
| 315 | if (ci->args->mode == "predict") { // Predict. |
| 316 | for (uint32_t j = 0; j < ci->nodeSlice->size(); ++j) { |
| 317 | auto index = (*ci->nodeSlice)[ci->nodeSlice->size() - 1 - j]; |
| 318 | auto n = (*ci->nodeMap)[index]; |
| 319 | |
| 320 | // The output nodes. |
| 321 | if (index >= inputNum && index < (inputNum + outputNum)) { |
| 322 | gradient[index] = n->value - ci->args->desireArray[z][index - inputNum]; |
| 323 | } |
| 324 | |
| 325 | auto grad = gradient[index] * (n->value > 0 ? 1.0f : 0.2f); |
| 326 | |
| 327 | for (auto &iter : *n->genomeMap) { |
| 328 | auto p = gradient.find(iter.first.in); |
| 329 | if (p != gradient.end()) { |
| 330 | gradient[iter.first.in] += grad * iter.second.weight; |
| 331 | } else { |
| 332 | gradient[iter.first.in] = grad * iter.second.weight; |
| 333 | } |
| 334 | |
| 335 | args->batchData[z][data_p++] = 0 - ci->args->lr * grad * (*ci->nodeMap)[iter.first.in]->value; |
| 336 | } |
| 337 | |
| 338 | args->batchData[z][data_p++] = 0 - ci->args->lr * grad; |
| 339 | } |
| 340 | } else { // Classify. |
| 341 | LycorisUtils::softmax(output, outputNum); |
| 342 | |
| 343 | for (uint32_t j = 0; j < ci->nodeSlice->size(); ++j) { |
| 344 | auto index = (*ci->nodeSlice)[ci->nodeSlice->size() - 1 - j]; |
| 345 | auto n = (*ci->nodeMap)[index]; |
| 346 | |
| 347 | // The output nodes. |
| 348 | if (index >= inputNum && index < (inputNum + outputNum)) { |
| 349 | gradient[index] = output[index - inputNum] - ci->args->desireArray[z][index - inputNum]; |
| 350 | } |
| 351 | |
| 352 | auto grad = gradient[index] * (n->value > 0 ? 1.0f : 0.2f); |
| 353 | |
| 354 | for (auto &iter : *n->genomeMap) { |
| 355 | auto p = gradient.find(iter.first.in); |
| 356 | if (p != gradient.end()) { |
| 357 | gradient[iter.first.in] += grad * iter.second.weight; |
| 358 | } else { |
| 359 | gradient[iter.first.in] = grad * iter.second.weight; |
| 360 | } |
| 361 | |
| 362 | args->batchData[z][data_p++] = 0 - ci->args->lr * grad * (*ci->nodeMap)[iter.first.in]->value; |