1# Copyright 2018 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15"""Numpy-related utilities.""" 16from __future__ import absolute_import 17from __future__ import division 18from __future__ import print_function 19 20import numpy as np 21from tensorflow.python.util.tf_export import keras_export 22 23 24@keras_export('keras.utils.to_categorical') 25def to_categorical(y, num_classes=None, dtype='float32'): 26 """Converts a class vector (integers) to binary class matrix. 27 28 E.g. for use with categorical_crossentropy. 29 30 Args: 31 y: class vector to be converted into a matrix 32 (integers from 0 to num_classes). 33 num_classes: total number of classes. If `None`, this would be inferred 34 as the (largest number in `y`) + 1. 35 dtype: The data type expected by the input. Default: `'float32'`. 36 37 Returns: 38 A binary matrix representation of the input. The classes axis is placed 39 last. 40 41 Example: 42 43 >>> a = tf.keras.utils.to_categorical([0, 1, 2, 3], num_classes=4) 44 >>> a = tf.constant(a, shape=[4, 4]) 45 >>> print(a) 46 tf.Tensor( 47 [[1. 0. 0. 0.] 48 [0. 1. 0. 0.] 49 [0. 0. 1. 0.] 50 [0. 0. 0. 1.]], shape=(4, 4), dtype=float32) 51 52 >>> b = tf.constant([.9, .04, .03, .03, 53 ... .3, .45, .15, .13, 54 ... .04, .01, .94, .05, 55 ... .12, .21, .5, .17], 56 ... shape=[4, 4]) 57 >>> loss = tf.keras.backend.categorical_crossentropy(a, b) 58 >>> print(np.around(loss, 5)) 59 [0.10536 0.82807 0.1011 1.77196] 60 61 >>> loss = tf.keras.backend.categorical_crossentropy(a, a) 62 >>> print(np.around(loss, 5)) 63 [0. 0. 0. 0.] 64 65 Raises: 66 Value Error: If input contains string value 67 68 """ 69 y = np.array(y, dtype='int') 70 input_shape = y.shape 71 if input_shape and input_shape[-1] == 1 and len(input_shape) > 1: 72 input_shape = tuple(input_shape[:-1]) 73 y = y.ravel() 74 if not num_classes: 75 num_classes = np.max(y) + 1 76 n = y.shape[0] 77 categorical = np.zeros((n, num_classes), dtype=dtype) 78 categorical[np.arange(n), y] = 1 79 output_shape = input_shape + (num_classes,) 80 categorical = np.reshape(categorical, output_shape) 81 return categorical 82 83 84@keras_export('keras.utils.normalize') 85def normalize(x, axis=-1, order=2): 86 """Normalizes a Numpy array. 87 88 Args: 89 x: Numpy array to normalize. 90 axis: axis along which to normalize. 91 order: Normalization order (e.g. `order=2` for L2 norm). 92 93 Returns: 94 A normalized copy of the array. 95 """ 96 l2 = np.atleast_1d(np.linalg.norm(x, order, axis)) 97 l2[l2 == 0] = 1 98 return x / np.expand_dims(l2, axis) 99