Computes the min and max EMA of input and stores them in min_var and max_var.
| 461 | |
| 462 | // Computes the min and max EMA of input and stores them in min_var and max_var. |
| 463 | Status MakeEMAMinMaxVars(Graph* graph, const string& name_prefix, Node* input, |
| 464 | std::vector<Node*>* added_variables, Node** min_var, |
| 465 | Node** max_var) { |
| 466 | // TODO(suharshs): The decay will be constant, so we could make only one for |
| 467 | // all quantize_and_dequantize ops to share, this would have to live outside |
| 468 | // this function. |
| 469 | Tensor decay_tensor(DT_FLOAT, TensorShape()); |
| 470 | decay_tensor.flat<float>()(0) = kEMADecay; |
| 471 | Node* decay; |
| 472 | TF_RETURN_IF_ERROR( |
| 473 | NodeBuilder(strings::StrCat(name_prefix, "/Decay"), "Const") |
| 474 | .Attr("dtype", DT_FLOAT) |
| 475 | .Attr("value", decay_tensor) |
| 476 | .Finalize(graph, &decay)); |
| 477 | |
| 478 | Node* reduction_axes; |
| 479 | TF_RETURN_IF_ERROR( |
| 480 | MakeReductionAxes(graph, name_prefix, input, &reduction_axes)); |
| 481 | Node* min; |
| 482 | string min_name = strings::StrCat(name_prefix, "/Min"); |
| 483 | TF_RETURN_IF_ERROR(NodeBuilder(min_name, "Min") |
| 484 | .Input(input) |
| 485 | .Input(reduction_axes) |
| 486 | .Finalize(graph, &min)); |
| 487 | Node* max; |
| 488 | string max_name = strings::StrCat(name_prefix, "/Max"); |
| 489 | TF_RETURN_IF_ERROR(NodeBuilder(max_name, "Max") |
| 490 | .Input(input) |
| 491 | .Input(reduction_axes) |
| 492 | .Finalize(graph, &max)); |
| 493 | TF_RETURN_IF_ERROR(MakeInitializedEMAVariable(graph, min_name, decay, min, |
| 494 | added_variables, min_var)); |
| 495 | TF_RETURN_IF_ERROR(MakeInitializedEMAVariable(graph, max_name, decay, max, |
| 496 | added_variables, max_var)); |
| 497 | return Status::OK(); |
| 498 | } |
| 499 | |
| 500 | // Makes an input min and max constant if the range is given. Otherwise, makes |
| 501 | // min and max variables that are updated by an EMA. |
no test coverage detected