All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ai.djl.training.util.MinMaxScaler Maven / Gradle / Ivy

There is a newer version: 0.30.0
Show newest version
/*
 * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
 * with the License. A copy of the License is located at
 *
 * http://aws.amazon.com/apache2.0/
 *
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
 * and limitations under the License.
 */
package ai.djl.training.util;

import ai.djl.ndarray.NDArray;

/**
 * Transform arrays by scaling each value to a given range. The desired range of transformed data
 * can be set using {@code optRange}. the range defaults to 0...1.
 *
 * 

After fitting the scaler the fitted values are attached to the same NDManager as the input * array. * * @author [email protected] */ public class MinMaxScaler implements AutoCloseable { private NDArray fittedMin; private NDArray fittedMax; private NDArray fittedRange; private float minRange; private float maxRange = 1f; private boolean detached; /** * Computes the minimum and maximum to be used for later scaling. * *

After fitting the scaler the fitted values are attached to the same NDManager as the input * array. reusing the minMaxScaler in the context of other NDManager's is possible by {@code * detach()} the scaler from the NDManager. * * @param data used to compute the minimum and maximum used for later scaling * @param axises minimum maximum computation along this axises * @return the fitted MinMaxScaler */ public MinMaxScaler fit(NDArray data, int[] axises) { fittedMin = data.min(axises); fittedMax = data.max(axises); fittedRange = fittedMax.sub(fittedMin); if (detached) { detach(); } return this; } /** * Computes the minimum and maximum to be used for later scaling. * *

After fitting the scaler the fitted values are attached to the same NDManager as the input * array. reusing the minMaxScaler in the context of other NDManager's is possible by {@code * detach()} the scaler from the NDManager. * * @param data used to compute the minimum and maximum used for later scaling * @return the fitted MinMaxScaler */ public MinMaxScaler fit(NDArray data) { fit(data, new int[] {0}); return this; } /** * Transforms the data using the previous calculated minimum and maximum. * *

if {@code fit()} is not executed yet, then the minimum/maximum is computer based on the * input data array and used for later computations. X_std = (X - X.min(axis=0)) / * (X.max(axis=0) - X.min(axis=0)) X_scaled = X_std * (max - min) + min * * @param data to get transformed * @return the transformed data, the input array is not changed */ public NDArray transform(NDArray data) { if (fittedRange == null) { fit(data, new int[] {0}); } NDArray std = data.sub(fittedMin).divi(fittedRange); return scale(std); } /** * Transforms the data in-place using the previous calculated minimum and maximum. * *

if {@code fit()} is not called before then the minimum/maximum is computer based on the * input data array and used for later computations. X_std = (X - X.min(axis=0)) / * (X.max(axis=0) - X.min(axis=0)) X_scaled = X_std * (max - min) + min * * @param data to get transformed * @return the transformed data (reference to the input data) the input array is changed * in-place by this operation */ public NDArray transformi(NDArray data) { if (fittedRange == null) { fit(data, new int[] {0}); } NDArray std = data.subi(fittedMin).divi(fittedRange); return scale(std); } /** * Scales array from std if range is not default range otherwise return the unchanged array. * *

this is an in-place operation. * * @param std input array to scale * @return scaled array */ private NDArray scale(NDArray std) { // we don't have to scale by custom range when range is default 0..1 if (maxRange != 1f || minRange != 0f) { return std.muli(maxRange - minRange).addi(minRange); } return std; } /** * Inverses scale array from std if range is not default range otherwise return the unchanged * array as a duplicate. * * @param std input array to scale * @return re-scaled array */ private NDArray inverseScale(NDArray std) { // we don't have to scale by custom range when range is default 0..1 if (maxRange != 1f || minRange != 0f) { return std.sub(minRange).divi(maxRange - minRange); } return std.duplicate(); } /** * Inverses scale array from std if range is not default range otherwise return the array * itself. * *

this is an in-place operation. * * @param std input array to scale in-place * @return re-scaled array */ private NDArray inverseScalei(NDArray std) { // we don't have to scale by custom range when range is default 0..1 if (maxRange != 1f || minRange != 0f) { return std.subi(minRange).divi(maxRange - minRange); } return std; } /** * Undoes the transformation of X according to feature_range. * * @param data to get transformed * @return the transformed array */ public NDArray inverseTransform(NDArray data) { throwsIllegalStateWhenNotFitted(); NDArray result = inverseScale(data); return result.muli(fittedRange).addi(fittedMin); } /** * Undoes the transformation of X according to feature_range as an in-place operation. * * @param data to get transformed, the data get changed in-place * @return the transformed array */ public NDArray inverseTransformi(NDArray data) { throwsIllegalStateWhenNotFitted(); NDArray result = inverseScalei(data); return result.muli(fittedRange).addi(fittedMin); } /** * Checks if this MinMaxScaler is already fitted and throws exception otherwise. * * @throws IllegalStateException when not Fitted */ private void throwsIllegalStateWhenNotFitted() { if (fittedRange == null) { throw new IllegalStateException("Min Max Scaler is not fitted"); } } /** * Detaches this MinMaxScaler fitted value from current NDManager's lifecycle. * *

this becomes un-managed and it is the user's responsibility to close this. Failure to * close the resource might cause your machine to run out of native memory. * *

After fitting the scaler the fitted values are attached to the same NDManager as the input * array. * *

Re-fitting the scaler after detaching doesn't re-attach the scaler to any NDManager. * * @return the detached MinMaxScaler (itself) - to use as a fluent API */ public MinMaxScaler detach() { detached = true; if (fittedMin != null) { fittedMin.detach(); } if (fittedMax != null) { fittedMax.detach(); } if (fittedRange != null) { fittedRange.detach(); } return this; } /** * Sets desired range of transformed data. * * @param minRange min value for desired range * @param maxRange max value for desired range * @return the configured MinMaxScaler */ public MinMaxScaler optRange(float minRange, float maxRange) { this.minRange = minRange; this.maxRange = maxRange; return this; } /** * Returns the value of fittedMin. * * @return the fittedMin value */ public NDArray getMin() { throwsIllegalStateWhenNotFitted(); return fittedMin; } /** * Returns the value of fittedMax. * * @return the fittedMax value */ public NDArray getMax() { throwsIllegalStateWhenNotFitted(); return fittedMax; } /** {@inheritDoc} */ @Override public void close() { if (fittedMin != null) { fittedMin.close(); } if (fittedMax != null) { fittedMax.close(); } if (fittedRange != null) { fittedRange.close(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy