Get the real value of `value`. If backprop "uses" a value produced by forward inference, an accumulator is added in the forward loop to accumulate its values. We use the accumulated value. This method must be called in the grad loop context. `value` must be in forward and needed fo
(self, value)
| 433 | return pop |
| 434 | |
| 435 | def GetRealValue(self, value): |
| 436 | """Get the real value of `value`. |
| 437 | |
| 438 | If backprop "uses" a value produced by forward inference, an accumulator |
| 439 | is added in the forward loop to accumulate its values. We use the |
| 440 | accumulated value. This method must be called in the grad loop context. |
| 441 | `value` must be in forward and needed for backprop. |
| 442 | |
| 443 | Args: |
| 444 | value: A tensor to be captured. |
| 445 | |
| 446 | Returns: |
| 447 | The same tensor obtained from the saved history. |
| 448 | """ |
| 449 | assert value.op.type not in ["Variable", "VariableV2"] |
| 450 | real_value = self._history_map.get(value.name) |
| 451 | if real_value is None: |
| 452 | cur_value = value |
| 453 | cur_grad_state = self |
| 454 | while True: |
| 455 | enter_op = util.GetLoopConstantEnter(cur_value) |
| 456 | if enter_op: |
| 457 | # Special case: cur_value comes from a constant Enter node. |
| 458 | cur_value = enter_op.inputs[0] |
| 459 | cur_grad_state = cur_grad_state.outer_grad_state |
| 460 | if cur_grad_state is None: |
| 461 | # We are now outside all nested loops for this gradient(), |
| 462 | # so `value` is a loop invariant and there is no need to |
| 463 | # save the history of value. Just make cur_value to enter |
| 464 | # the right control flow context. |
| 465 | real_value = self._grad_context.AddValue(cur_value) |
| 466 | break |
| 467 | elif constant_op.is_constant(cur_value): |
| 468 | # If the value to be forwarded is a constant, clone the constant in |
| 469 | # the gradient loop rather than using a stack. |
| 470 | # TODO(phawkins): consider hoisting the constant out of the loop |
| 471 | # instead. |
| 472 | real_value = constant_op.constant( |
| 473 | tensor_util.constant_value(cur_value), dtype=cur_value.dtype) |
| 474 | break |
| 475 | else: |
| 476 | # Record the history of this value in forward_ctxt. |
| 477 | self._grad_context.Exit() |
| 478 | history_value = cur_grad_state.AddForwardAccumulator(cur_value) |
| 479 | self._grad_context.Enter() |
| 480 | break |
| 481 | |
| 482 | if real_value is None: |
| 483 | # Add the stack pop op in the grad context. |
| 484 | real_value = cur_grad_state.AddBackpropAccumulatedValue( |
| 485 | history_value, cur_value) |
| 486 | if cur_grad_state != self: |
| 487 | real_value = self._grad_context.AddValue(real_value) |
| 488 | self._history_map[value.name] = real_value |
| 489 | return real_value |
| 490 | |
| 491 | |
| 492 | class _ControlFlowState(object): |
no test coverage detected