<p dir="auto">The segment reduction ops are currently inconsistent, they include different ops for sorted/unsorted/ and sparse/dense tensors.<br>
I guess it would make sense to provide the same reduction ops  for these - I'd be happy to work on this and build on nikste's work.</p>
<p dir="auto">For similar previous issues <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/andydavis1/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/andydavis1">@andydavis1</a>, <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/drpngx/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/drpngx">@drpngx</a> were responsible for reviewing, so I link you here.</p>
<p dir="auto">Things to possibly consider:</p>
<ul dir="auto">
<li>Replace the sorted segment options by the more general unsorted options. I did a quick, non-extensive benchmark for  unsorted_segment_max vs  segment_max, the processing time is about the same (with the unsorted op even being a bit faster sometimes).<br>
The drawback would be, that num_segments needs to be specified or needs to be computed before the reduction.</li>
<li>Include the feature request "Extend tf.unsorted_segment_sum to allow 'rejecting' entries" <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="121665076" data-permission-text="Title is private" data-url="https://github.com/tensorflow/tensorflow/issues/478" data-hovercard-type="issue" data-hovercard-url="/tensorflow/tensorflow/issues/478/hovercard" href="https://github.com/tensorflow/tensorflow/issues/478">#478</a></li>
<li>Address the ToDo in UnsortedSegmentMax: <code class="notranslate">// todo: Remove duplicate code in UnsortedSegmentSumFunctor and UnsortedSegmentMaxFunctor.</code><br>
To sum up, I'd suggest to replace and extend the currently provided functions</li>
</ul>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="tf.segment_sum(data, segment_ids, name=None)
tf.segment_prod(data, segment_ids, name=None)
tf.segment_min(data, segment_ids, name=None)
tf.segment_max(data, segment_ids, name=None)
tf.segment_mean(data, segment_ids, name=None)
tf.unsorted_segment_sum(data, segment_ids, num_segments, name=None)
tf.sparse_segment_sum(data, indices, segment_ids, name=None)
tf.sparse_segment_mean(data, indices, segment_ids, name=None)
tf.sparse_segment_sqrt_n(data, indices, segment_ids, name=None)"><pre class="notranslate"><code class="notranslate">tf.segment_sum(data, segment_ids, name=None)
tf.segment_prod(data, segment_ids, name=None)
tf.segment_min(data, segment_ids, name=None)
tf.segment_max(data, segment_ids, name=None)
tf.segment_mean(data, segment_ids, name=None)
tf.unsorted_segment_sum(data, segment_ids, num_segments, name=None)
tf.sparse_segment_sum(data, indices, segment_ids, name=None)
tf.sparse_segment_mean(data, indices, segment_ids, name=None)
tf.sparse_segment_sqrt_n(data, indices, segment_ids, name=None)
</code></pre></div>
<p dir="auto">with</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="# all dense/sparse ops support unsorted segments
tf.segment_sum(data, segment_ids, num_segements=None, name=None) 
tf.segment_prod(data, segment_ids, num_segements=None, name=None)
tf.segment_min(data, segment_ids, num_segements=None, name=None)
tf.segment_max(data, segment_ids, num_segements=None, name=None) 
tf.segment_mean(data, segment_ids, num_segements=None, name=None)
tf.segment_sqrt_n(data, segment_ids, num_segements=None, name=None)  # new

tf.sparse_segment_sum(data, indices, segment_ids, name=None)
tf.sparse_segment_prod(data, indices, segment_ids, name=None)  # new
tf.sparse_segment_min(data, indices, segment_ids, name=None)  # new
tf.sparse_segment_max(data, indices, segment_ids, name=None)  # new
tf.sparse_segment_mean(data, indices, segment_ids, name=None)
tf.sparse_segment_sqrt_n(data, indices, segment_ids, name=None)"><pre class="notranslate"><code class="notranslate"># all dense/sparse ops support unsorted segments
tf.segment_sum(data, segment_ids, num_segements=None, name=None) 
tf.segment_prod(data, segment_ids, num_segements=None, name=None)
tf.segment_min(data, segment_ids, num_segements=None, name=None)
tf.segment_max(data, segment_ids, num_segements=None, name=None) 
tf.segment_mean(data, segment_ids, num_segements=None, name=None)
tf.segment_sqrt_n(data, segment_ids, num_segements=None, name=None)  # new

tf.sparse_segment_sum(data, indices, segment_ids, name=None)
tf.sparse_segment_prod(data, indices, segment_ids, name=None)  # new
tf.sparse_segment_min(data, indices, segment_ids, name=None)  # new
tf.sparse_segment_max(data, indices, segment_ids, name=None)  # new
tf.sparse_segment_mean(data, indices, segment_ids, name=None)
tf.sparse_segment_sqrt_n(data, indices, segment_ids, name=None)
</code></pre></div>
<p dir="auto">(Or <code class="notranslate">tf.unsorted_segment_reduce_op</code> instead of <code class="notranslate">tf.segement_reduceop</code> to not break backward compability)</p>
<h3 dir="auto">System information</h3>
<ul dir="auto">
<li><strong>Have I written custom code (as opposed to using a stock example script provided in TensorFlow)</strong>: No</li>
<li><strong>OS Platform and Distribution (e.g., Linux Ubuntu 16.04)</strong>: Linux Ubuntu 16.04</li>
<li><strong>Mobile device (e.g. iPhone 8, Pixel 2, Samsung Galaxy) if the issue happens on mobile device</strong>: n/a</li>
<li><strong>TensorFlow installed from (source or binary)</strong>: binary</li>
<li><strong>TensorFlow version (use command below)</strong>: v1.9.0-rc0-35-g17d6639b55 1.9.0-rc1</li>
<li><strong>Python version</strong>: 3.5.2</li>
<li><strong>Bazel version (if compiling from source)</strong>: n/a</li>
<li><strong>GCC/Compiler version (if compiling from source)</strong>: n/a</li>
<li><strong>CUDA/cuDNN version</strong>: n/a</li>
<li><strong>GPU model and memory</strong>: n/a</li>
<li><strong>Exact command to reproduce</strong>: n/a</li>
</ul>
<h3 dir="auto">Describe the problem</h3>
<p dir="auto">I wanted to call attention to an issue and a PR on the keras-team/keras project so that TF could track and integrate with TF-core Keras. I believe these issues are of high importance to the community; for my project at least they are just short of critical. In summary:</p>
<ul dir="auto">
<li>PR: Keras Callbacks should be able to access predictions made during training in <code class="notranslate">on_batch_end()</code> and <code class="notranslate">on_epoch_end()</code> to eliminate expensive duplicate calls to <code class="notranslate">predict()</code> in Callbacks that require prediction results -- <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="335051045" data-permission-text="Title is private" data-url="https://github.com/keras-team/keras/issues/10513" data-hovercard-type="pull_request" data-hovercard-url="/keras-team/keras/pull/10513/hovercard" href="https://github.com/keras-team/keras/pull/10513">keras-team/keras#10513</a></li>
<li>Writing a Keras metric should not require a graph -- <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="191721607" data-permission-text="Title is private" data-url="https://github.com/keras-team/keras/issues/4506" data-hovercard-type="issue" data-hovercard-url="/keras-team/keras/issues/4506/hovercard?comment_id=405452870&amp;comment_type=issue_comment" href="https://github.com/keras-team/keras/issues/4506#issuecomment-405452870">keras-team/keras#4506 (comment)</a></li>
</ul>
<p dir="auto">The reason these are related is because a viable solution to the second issue depends on the first; in particular, if you wanted to write a "fancy" metric function that did calcs in Python, for example, you could leverage already-made predictions from the API described in issue 1 and circumvent having to <code class="notranslate">predict()</code> all over again, which is prohibitively expensive in all but the simplest models.</p>