Merge repeated labels into single labels. Args: labels: Tensor of shape [batch, max value in seq_length] seq_length: Tensor of shape [batch], sequence length of each batch element. name: A name for this `Op`. Defaults to "collapse_repeated_labels". Returns: A tuple `(collapsed_
(labels, seq_length, name=None)
| 864 | |
| 865 | @tf_export("nn.collapse_repeated") |
| 866 | def collapse_repeated(labels, seq_length, name=None): |
| 867 | """Merge repeated labels into single labels. |
| 868 | |
| 869 | Args: |
| 870 | labels: Tensor of shape [batch, max value in seq_length] |
| 871 | seq_length: Tensor of shape [batch], sequence length of each batch element. |
| 872 | name: A name for this `Op`. Defaults to "collapse_repeated_labels". |
| 873 | |
| 874 | Returns: |
| 875 | A tuple `(collapsed_labels, new_seq_length)` where |
| 876 | |
| 877 | collapsed_labels: Tensor of shape [batch, max_seq_length] with repeated |
| 878 | labels collapsed and padded to max_seq_length, eg: |
| 879 | `[[A, A, B, B, A], [A, B, C, D, E]] => [[A, B, A, 0, 0], [A, B, C, D, E]]` |
| 880 | |
| 881 | new_seq_length: int tensor of shape [batch] with new sequence lengths. |
| 882 | """ |
| 883 | |
| 884 | with ops.name_scope(name, "collapse_repeated_labels", [labels, seq_length]): |
| 885 | labels = ops.convert_to_tensor(labels, name="labels") |
| 886 | seq_length = ops.convert_to_tensor(seq_length, name="seq_length") |
| 887 | |
| 888 | # Mask labels that don't equal previous label. |
| 889 | label_mask = array_ops.concat([ |
| 890 | array_ops.ones_like(labels[:, :1], dtypes.bool), |
| 891 | math_ops.not_equal(labels[:, 1:], labels[:, :-1]) |
| 892 | ], |
| 893 | axis=1) |
| 894 | |
| 895 | # Filter labels that aren't in the original sequence. |
| 896 | maxlen = _get_dim(labels, 1) |
| 897 | seq_mask = array_ops.sequence_mask(seq_length, maxlen=maxlen) |
| 898 | label_mask = math_ops.logical_and(label_mask, seq_mask) |
| 899 | |
| 900 | # Count masks for new sequence lengths. |
| 901 | new_seq_len = math_ops.reduce_sum( |
| 902 | math_ops.cast(label_mask, dtypes.int32), axis=1) |
| 903 | |
| 904 | # Mask indexes based on sequence length mask. |
| 905 | new_maxlen = math_ops.reduce_max(new_seq_len) |
| 906 | idx_mask = array_ops.sequence_mask(new_seq_len, maxlen=new_maxlen) |
| 907 | |
| 908 | # Flatten everything and mask out labels to keep and sparse indices. |
| 909 | flat_labels = array_ops.reshape(labels, [-1]) |
| 910 | flat_label_mask = array_ops.reshape(label_mask, [-1]) |
| 911 | flat_idx_mask = array_ops.reshape(idx_mask, [-1]) |
| 912 | idx = math_ops.range(_get_dim(flat_idx_mask, 0)) |
| 913 | |
| 914 | # Scatter to flat shape. |
| 915 | flat = array_ops.scatter_nd( |
| 916 | indices=array_ops.expand_dims( |
| 917 | array_ops.boolean_mask(idx, flat_idx_mask), axis=1), |
| 918 | updates=array_ops.boolean_mask(flat_labels, flat_label_mask), |
| 919 | shape=array_ops.shape(flat_idx_mask)) |
| 920 | |
| 921 | # Reshape back to square batch. |
| 922 | batch_size = _get_dim(labels, 0) |
| 923 | new_shape = [batch_size, new_maxlen] |
nothing calls this directly
no test coverage detected