* Scale the gradient values using normalized reward values and compute average. * * The gradient values are scaled by the normalized reward values. Then they * are averaged across all games and all steps. * * @param {{[varName: string]: tf.Tensor[][]}} allGradients A map from variable * name
(allGradients, normalizedRewards)
| 387 | * for the variables. |
| 388 | */ |
| 389 | function scaleAndAverageGradients(allGradients, normalizedRewards) { |
| 390 | return tf.tidy(() => { |
| 391 | const gradients = {}; |
| 392 | for (const varName in allGradients) { |
| 393 | gradients[varName] = tf.tidy(() => { |
| 394 | // Stack gradients together. |
| 395 | const varGradients = allGradients[varName].map( |
| 396 | varGameGradients => tf.stack(varGameGradients)); |
| 397 | // Expand dimensions of reward tensors to prepare for multiplication |
| 398 | // with broadcasting. |
| 399 | const expandedDims = []; |
| 400 | for (let i = 0; i < varGradients[0].rank - 1; ++i) { |
| 401 | expandedDims.push(1); |
| 402 | } |
| 403 | const reshapedNormalizedRewards = normalizedRewards.map( |
| 404 | rs => rs.reshape(rs.shape.concat(expandedDims))); |
| 405 | for (let g = 0; g < varGradients.length; ++g) { |
| 406 | // This mul() call uses broadcasting. |
| 407 | varGradients[g] = varGradients[g].mul(reshapedNormalizedRewards[g]); |
| 408 | } |
| 409 | // Concatenate the scaled gradients together, then average them across |
| 410 | // all the steps of all the games. |
| 411 | return tf.mean(tf.concat(varGradients, 0), 0); |
| 412 | }); |
| 413 | } |
| 414 | return gradients; |
| 415 | }); |
| 416 | } |
| 417 | |
| 418 | setUpUI(); |