System information.
TensorFlow version (you are using): 2.9
Are you willing to contribute it (Yes/No) : Yes
Describe the feature and the current behavior/state:
Currently, I couldn't find any good implementation for converting label to ordinal-regression/classification label. Either people use for loop to do it or they convert labels element-wise rather than batch-wise.
Describe the feature clearly here. Be sure to convey here why the requested feature is needed. Any brief description about the use-case would help.:
This feature is needed for Ordinal Regression / Classification task. In tf.keras.utils
there is to_categorical
to convert labels to one_hot labels for classification. But for ordinal regression / classification we need to transform the labels differently. But currently tf.keras
doesn't have the support of this feature.
Here's an example of the feature with contrast to one_hot encoding,
One Hot
Input:
label = np.array([0, 1, 2, 3, 1])
one_hot = tf.keras.utils.to_categorical(label, num_classes=4)
Output:
[[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 1, 0, 0]]
Ordinal Regression / Classification
Input:
label = np.array([0, 1, 2, 3, 1])
ordinal = to_ordinal(label, num_classes=4)
Output:
[[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[1, 1, 1],
[1, 0, 0]]
Will this change the current api? How?
This feature currently doesn't have any implementation.
Who will benefit from this feature?
All the members of the community. Ordinal regression/classification is quite interesting and getting popular day by day. But it is hardly mentioned in the literature how to transform the label for ordinal regression. I think this feature will be a nice addition to keras for everyone.
Contributing
- Do you want to contribute a PR? (yes/no): Yes
- If yes, please read this page for instructions
- Briefly describe your candidate solution(if contributing):
Solution
Following is the Numpy implementation but the same code can be used for TensorFlow as well,
def to_ordinal(y, num_classes=None):
if not num_classes:
num_classes = np.max(y) + 1
range_values = np.arange(num_classes-1)[None,:]
range_values = np.tile(range_values, [y.shape[0], 1])
ordinal_label = np.where(range_values < y[:, None], 1, 0)
return ordinal_label
type:feature