在Keras中实现类似Sklearn的转换:一个自定义预处理层的例子

99 阅读4分钟

在这篇文章中,我们将研究如何实现一个类似Sklearn的变换器作为Keras的预处理层。变换器的例子将是MinMax缩放器。

Keras是一个强大的深度学习库,能够创建和训练神经网络模型。然而,在训练任何机器学习模型之前,必须对数据进行预处理。Sklearn提供了各种转化器来预处理数据,包括将特征缩放到特定范围的MinMaxScaler。在这篇博文中,我们将使用MinMaxScalerLayer的例子,演示如何实现一个自定义的Keras预处理层,其行为类似于Sklearn的MinMaxScaler。然后我们将使用相同的数据来比较结果,以突出这两种方法的相似性。

MinMaxScalerLayer

我们的自定义预处理层MinMaxScalerLayer通过根据提供的feature_range ,将特征缩放到指定范围。该层可以很容易地集成到Keras模型中,因为它是tf.python.keras.engine.base_preprocessing_layer.PreprocessingLayer 的一个子类。该层的主要组成部分是:

  • __init__ 方法:用所需的特征范围初始化该层。
  • adapt 方法:计算输入数据中每个特征的最小值和最大值,即包含缩放器的状态。
  • call 方法:为输入数据中的每个特征计算最小值和最大值;即包含缩放器的状态:对输入数据应用缩放变换。
  • get_config 方法:为序列化目的返回图层配置:返回用于序列化的层配置。

下面是在Keras中创建一个等效的自定义MinMax缩放器的实现:

import tensorflow as tfclass MinMaxScalerLayer(tf.python.keras.engine.base_preprocessing_layer.PreprocessingLayer):    def __init__(self, feature_range=(0, 1), **kwargs):        super(MinMaxScalerLayer, self).__init__(**kwargs)        self.feature_range = feature_range        self.data_min = None        self.data_max = None    def adapt(self, data):        data = tf.convert_to_tensor(data)        self.data_min = tf.math.reduce_min(data, axis=0)        self.data_max = tf.math.reduce_max(data, axis=0)    def call(self, inputs):        if self.data_min is None or self.data_max is None:            raise RuntimeError("The layer has not been adapted. Call 'adapt' before using the layer.")                inputs = tf.convert_to_tensor(inputs)        scaled_data = (inputs - self.data_min) / (self.data_max - self.data_min)        return self.feature_range[0] + (scaled_data * (self.feature_range[1] - self.feature_range[0]))    def get_config(self):        config = super(MinMaxScalerLayer, self).get_config()        config.update({            "feature_range": self.feature_range        })        return config

比较MinMaxScalerLayer和Sklearn的MinMaxScaler

为了证明我们的自定义预处理层和Sklearn的MinMaxScaler之间的相似性,我们将对两种方法使用相同的数据,并比较结果。

首先,让我们生成一个数据集:

import numpy as npdata = np.random.randn(100, 10).astype(np.float32)labels = np.random.randn(100, 1)

现在,让我们用Sklearn的MinMaxScaler对数据进行预处理:

from sklearn.preprocessing import MinMaxScalerscaler = MinMaxScaler(feature_range=(0, 1))data_scaled_sklearn = scaler.fit_transform(data)

接下来,我们将使用我们自定义的MinMaxScalerLayer对数据进行预处理:

minmax_scaler_layer = MinMaxScalerLayer(feature_range=(0, 1))minmax_scaler_layer.adapt(data)data_scaled_keras = minmax_scaler_layer(data)

最后,我们可以比较一下结果:

print("Sklearn MinMaxScaler result:")print(data_scaled_sklearn)print("Keras MinMaxScalerLayer result:")print(data_scaled_keras.numpy())print("Difference between Sklearn and Keras results:")print(np.abs(data_scaled_sklearn - data_scaled_keras.numpy()))

准备真实世界的数据

在本节中,我们将用一个真实世界的数据集来演示自定义MinMaxScalerLayer的使用。我们将使用UCI机器学习资源库的 "葡萄酒质量 "数据集,该数据集由葡萄酒的各种物理化学特性及其相应的质量评级组成。

首先,让我们加载数据集并将其分成特征和标签:

import pandas as pdfrom sklearn.model_selection import train_test_spliturl = "https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv"data = pd.read_csv(url, delimiter=";")features = data.drop("quality", axis=1).values.astype(np.float32)labels = data["quality"].values.reshape(-1, 1)# Split the data into training and testing setsX_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=42)

建立和训练一个Keras模型:

我们现在将使用自定义的MinMaxScalerLayer建立一个简单的Keras模型,并在葡萄酒质量数据集上进行训练。该模型的性能将在测试集上进行评估。

import tensorflow as tf# Instantiate and adapt the custom preprocessing layerminmax_scaler_layer = MinMaxScalerLayer(feature_range=(0, 1))minmax_scaler_layer.adapt(X_train)# Create and compile a Keras model using the custom preprocessing layermodel = tf.keras.Sequential([    minmax_scaler_layer,    tf.keras.layers.Dense(64, activation='relu'),    tf.keras.layers.Dense(64, activation='relu'),    tf.keras.layers.Dense(1)])model.compile(optimizer='adam', loss='mse', metrics=['mae'])# Train the modelhistory = model.fit(X_train, y_train, epochs=50, batch_size=32, validation_split=0.2, verbose=2)# Evaluate the model on the test settest_loss, test_mae = model.evaluate(X_test, y_test, verbose=2)print(f"Test MAE: {test_mae:.4f}")

这个例子演示了如何在Keras模型中使用自定义的MinMaxScalerLayer来处理一个真实世界的数据集。该层适应于训练数据,它可以很容易地集成到Keras模型中来处理特征缩放。

总结

在这篇博文中,我们演示了如何在Keras中实现一个模仿Sklearn的MinMaxScaler的自定义预处理层。MinMaxScalerLayer可以很容易地集成到Keras模型中,以处理特征的缩放。通过比较我们的自定义层和Sklearn的MinMaxScaler的结果,我们表明它们产生了相似的结果,突出了Keras在创建自定义转化器方面的灵活性和实用性。这种方法可以扩展到其他预处理任务,使其更容易将类似Sklearn的转化器直接集成到Keras模型中。