Python中组合分类和回归的神经网络模型

开发 后端 深度学习
在本教程中,您将发现如何开发用于组合回归和分类预测的神经网络。

[[406559]]

Python中文社区 (ID:python-china)

 某些预测问题需要为同一输入预测数字值和类别标签。一种简单的方法是在同一数据上开发回归和分类预测模型,然后依次使用这些模型。另一种通常更有效的方法是开发单个神经网络模型,该模型可以根据同一输入预测数字和类别标签值。这被称为多输出模型,使用现代深度学习库(例如Keras和TensorFlow)可以相对容易地开发和评估。

在本教程中,您将发现如何开发用于组合回归和分类预测的神经网络。完成本教程后,您将知道:

  •  一些预测问题需要为每个输入示例预测数字和类别标签值。
  •  如何针对需要多个输出的问题开发单独的回归和分类模型。
  •  如何开发和评估能够同时进行回归和分类预测的神经网络模型。

教程概述

本教程分为三个部分:他们是:

  •  回归和分类的单一模型
  •  单独的回归和分类模型

          鲍鱼数据集

          回归模型

          分类模型

  •  组合回归和分类模型

回归和分类的单一模型

开发用于回归或分类问题的深度学习神经网络模型是很常见的,但是在某些预测建模任务上,我们可能希望开发一个可以进行回归和分类预测的单一模型。回归是指涉及预测给定输入的数值的预测建模问题。分类是指预测建模问题,涉及预测给定输入的类别标签或类别标签的概率。

我们可能要预测数值和分类值时可能会有一些问题。解决此问题的一种方法是为每个所需的预测开发一个单独的模型。这种方法的问题在于,由单独的模型做出的预测可能会有所不同。使用神经网络模型时可以使用的另一种方法是开发单个模型,该模型能够对相同输入的数字和类输出进行单独的预测。这称为多输出神经网络模型。这种类型的模型的好处在于,我们有一个模型可以开发和维护,而不是两个模型,并且同时在两种输出类型上训练和更新模型可以在两种输出类型之间的预测中提供更大的一致性。我们将开发一个能够同时进行回归和分类预测的多输出神经网络模型。

首先,让我们选择一个满足此要求的数据集,并从为回归和分类预测开发单独的模型开始。

单独的回归和分类模型

在本节中,我们将从选择一个实际数据集开始,在该数据集中我们可能需要同时进行回归和分类预测,然后针对每种类型的预测开发单独的模型。

鲍鱼数据集

我们将使用“鲍鱼”数据集。确定鲍鱼的年龄是一项耗时的工作,并且希望仅根据物理细节来确定鲍鱼的年龄。这是一个描述鲍鱼物理细节的数据集,需要预测鲍鱼的环数,这是该生物年龄的代名词。

“年龄”既可以预测为数值(以年为单位),也可以预测为类别标签(按年为普通年)。无需下载数据集,因为我们将作为工作示例的一部分自动下载它。数据集提供了一个数据集示例,我们可能需要输入的数值和分类。

首先,让我们开发一个示例来下载和汇总数据集。   

# load and summarize the abalone dataset  
   from pandas import read_csv  
   from matplotlib import pyplot  
   # load dataset  
   url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'  
   dataframe = read_csv(url, header=None 
   # summarize shape  
   print(dataframe.shape)  
   # summarize first few lines  
   print(dataframe.head()) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

首先运行示例,然后下载并汇总数据集的形状。我们可以看到有4,177个示例(行)可用于训练和评估模型,还有9个要素(列)包括目标变量。我们可以看到,除了第一个字符串值之外,所有输入变量都是数字变量。为了简化数据准备,我们将从模型中删除第一列,并着重于对数字输入值进行建模。 

(4177, 9)  
  012345678  
  0  M  0.4550.3650.0950.51400.22450.10100.15015  
  1  M  0.3500.2650.0900.22550.09950.04850.0707  
  2  F  0.5300.4200.1350.67700.25650.14150.2109  
  3  M  0.4400.3650.1250.51600.21550.11400.15510  
  4  I  0.3300.2550.0800.20500.08950.03950.0557 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

我们可以将数据用作开发单独的回归和分类多层感知器(MLP)神经网络模型的基础。

注意:我们并未尝试为此数据集开发最佳模型;相反,我们正在展示一种特定的技术:开发可以进行回归和分类预测的模型。

回归模型

在本节中,我们将为鲍鱼数据集开发回归MLP模型。首先,我们必须将各列分为输入和输出元素,并删除包含字符串值的第一列。我们还将强制所有加载的列都具有浮点类型(由神经网络模型期望)并记录输入特征的数量,稍后模型需要知道这些特征。 

# split into input (X) and output (y) variables  
X, y = dataset[:, 1:-1], dataset[:, -1]  
X, y = X.astype('float'), y.astype('float')  
n_features = X.shape[1] 
  • 1.
  • 2.
  • 3.
  • 4.

接下来,我们可以将数据集拆分为训练和测试数据集。我们将使用67%的随机样本来训练模型,而剩余的33%则用于评估模型。 

# split data into train and test sets  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1
  • 1.
  • 2.

然后,我们可以定义一个MLP神经网络模型。该模型将具有两个隐藏层,第一个具有20个节点,第二个具有10个节点,都使用ReLU激活和“正常”权重初始化(一种好的做法)。层数和节点数是任意选择的。输出层将具有用于预测数值和线性激活函数的单个节点。 

# define the keras model  
 model = Sequential()  
 model.add(Dense(20, input_dim=n_featuresactivation='relu'kernel_initializer='he_normal'))  
 model.add(Dense(10, activation='relu'kernel_initializer='he_normal'))  
 model.add(Dense(1, activation='linear')) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

使用随机梯度下降的有效Adam版本,将训练模型以最小化均方误差(MSE)损失函数。 

# compile the keras model  
model.compile(loss='mse'optimizer='adam'
  • 1.
  • 2.

我们将训练150个纪元的模型,并以32个样本的小批量为样本,再次任意选择。 

# fit the keras model on the dataset  
model.fit(X_train, y_train, epochs=150batch_size=32verbose=2
  • 1.
  • 2.

最后,在训练完模型后,我们将在保持测试数据集上对其进行评估,并报告平均绝对误差(MAE)。 

# evaluate on test set  
yhat = model.predict(X_test)  
error = mean_absolute_error(y_test, yhat) 
print('MAE: %.3f'% error) 
  • 1.
  • 2.
  • 3.
  • 4.

综上所述,下面列出了以回归问题为框架的鲍鱼数据集的MLP神经网络的完整示例。 

# regression mlp model for the abalone dataset  
from pandas import read_csv  
from tensorflow.keras.models importSequential  
from tensorflow.keras.layers importDense  
from sklearn.metrics import mean_absolute_error  
from sklearn.model_selection import train_test_split  
# load dataset  
url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'  
dataframe = read_csv(url, header=None 
dataset = dataframe.values  
# split into input (X) and output (y) variables  
X, y = dataset[:, 1:-1], dataset[:, -1]  
X, y = X.astype('float'), y.astype('float')  
n_features = X.shape[1]  
# split data into train and test sets  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1 
# define the keras model  
model = Sequential()  
model.add(Dense(20, input_dim=n_featuresactivation='relu'kernel_initializer='he_normal'))  
model.add(Dense(10, activation='relu'kernel_initializer='he_normal'))  
model.add(Dense(1, activation='linear'))  
# compile the keras model 
model.compile(loss='mse'optimizer='adam'
# fit the keras model on the dataset  
model.fit(X_train, y_train, epochs=150batch_size=32verbose=2 
# evaluate on test set  
yhat = model.predict(X_test)  
error = mean_absolute_error(y_test, yhat)  
print('MAE: %.3f'% error) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.

运行示例将准备数据集,拟合模型并报告模型误差的估计值。

注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。

在这种情况下,我们可以看到该模型实现了约1.5 的误差。 

Epoch145/150  
 88/88- 0s- loss: 4.6130  
 Epoch146/150  
 88/88- 0s- loss: 4.6182  
 Epoch147/150  
 88/88- 0s- loss: 4.6277  
 Epoch148/150  
 88/88- 0s- loss: 4.6437  
 Epoch149/150  
 88/88- 0s- loss: 4.6166  
 Epoch150/150 
 88/88- 0s- loss: 4.6132  
 MAE: 1.554 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

到目前为止,一切都很好。接下来,让我们看一下开发类似的分类模型。

分类模型

鲍鱼数据集可以归类为一个分类问题,其中每个“环”整数都被当作一个单独的类标签。该示例和模型与上述回归示例非常相似,但有一些重要的变化。这要求首先为每个“ ring”值分配一个单独的整数,从0开始,以“ class”总数减1结束。这可以使用LabelEncoder实现。我们还可以将类的总数记录为唯一编码的类值的总数,稍后模型会需要。 

# encode strings to integer  
y = LabelEncoder().fit_transform(y)  
n_class = len(unique(y)) 
  • 1.
  • 2.
  • 3.

将数据像以前一样分为训练集和测试集后,我们可以定义模型并将模型的输出数更改为等于类数,并使用对于多类分类通用的softmax激活函数。 

# define the keras model  
model = Sequential()  
model.add(Dense(20, input_dim=n_featuresactivation='relu'kernel_initializer='he_normal'))  
model.add(Dense(10, activation='relu'kernel_initializer='he_normal'))  
model.add(Dense(n_class, activation='softmax')) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

假设我们已将类别标签编码为整数值,则可以通过最小化适用于具有整数编码类别标签的多类别分类任务的稀疏类别交叉熵损失函数来拟合模型 

# compile the keras model  
  model.compile(loss='sparse_categorical_crossentropy'optimizer='adam'
  • 1.
  • 2.

在像以前一样将模型拟合到训练数据集上之后,我们可以通过计算保留测试集上的分类准确性来评估模型的性能。 

# evaluate on test set  
yhat = model.predict(X_test)  
yhat = argmax(yhat, axis=-1).astype('int')  
acc = accuracy_score(y_test, yhat)  
print('Accuracy: %.3f'% acc) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

综上所述,下面列出了针对鲍鱼数据集的MLP神经网络的完整示例,该示例被归类为分类问题。 

# classification mlp model for the abalone dataset  
 from numpy import unique  
 from numpy import argmax  
 from pandas import read_csv  
 from tensorflow.keras.models importSequential 
 from tensorflow.keras.layers importDense  
 from sklearn.metrics import accuracy_score  
 from sklearn.model_selection import train_test_split  
 from sklearn.preprocessing importLabelEncoder  
 # load dataset  
 url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'  
 dataframe = read_csv(url, header=None 
 dataset = dataframe.values  
 # split into input (X) and output (y) variables  
 X, y = dataset[:, 1:-1], dataset[:, -1]  
 X, y = X.astype('float'), y.astype('float')  
 n_features = X.shape[1]  
 # encode strings to integer  
 y = LabelEncoder().fit_transform(y)  
 n_class = len(unique(y))  
 # split data into train and test sets  
 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=1 
 # define the keras model  
 model = Sequential()  
 model.add(Dense(20, input_dim=n_featuresactivation='relu'kernel_initializer='he_normal'))  
 model.add(Dense(10, activation='relu'kernel_initializer='he_normal'))  
 model.add(Dense(n_class, activation='softmax'))  
 # compile the keras model  
 model.compile(loss='sparse_categorical_crossentropy'optimizer='adam' 
 # fit the keras model on the dataset  
 model.fit(X_train, y_train, epochs=150batch_size=32verbose=2 
 # evaluate on test set  
 yhat = model.predict(X_test)  
 yhat = argmax(yhat, axis=-1).astype('int')  
 acc = accuracy_score(y_test, yhat)  
 print('Accuracy: %.3f'% acc) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.

运行示例将准备数据集,拟合模型并报告模型误差的估计值。

注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。

在这种情况下,我们可以看到该模型的准确度约为27%。 

Epoch145/150  
 88/88- 0s- loss: 1.9271  
 Epoch146/150  
 88/88- 0s- loss: 1.9265  
 Epoch147/150  
 88/88- 0s- loss: 1.9265  
 Epoch148/150  
 88/88- 0s- loss: 1.9271 
 Epoch149/150  
 88/88- 0s- loss: 1.9262 
 Epoch150/150  
 88/88- 0s- loss: 1.9260  
 Accuracy: 0.274 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

到目前为止,一切都很好。接下来,让我们看一下开发一种能够同时进行回归和分类预测的组合模型。

组合回归和分类模型

在本节中,我们可以开发一个单一的MLP神经网络模型,该模型可以对单个输入进行回归和分类预测。这称为多输出模型,可以使用功能性Keras API进行开发。

首先,必须准备数据集。尽管我们应该使用单独的名称保存编码后的目标变量以将其与原始目标变量值区分开,但是我们可以像以前一样为分类准备数据集。 

# encode strings to integer  
y_class = LabelEncoder().fit_transform(y)  
n_class = len(unique(y_class)) 
  • 1.
  • 2.
  • 3.

然后,我们可以将输入,原始输出和编码后的输出变量拆分为训练集和测试集。 

# split data into train and test sets  
X_train, X_test, y_train, y_test, y_train_class, y_test_class = train_test_split(X, y, y_class, test_size=0.33, random_state=1
  • 1.
  • 2.

接下来,我们可以使用功能性API定义模型。该模型采用与独立模型相同的输入数量,并使用以相同方式配置的两个隐藏层 

# input  
 visible = Input(shape=(n_features,))  
 hidden1 = Dense(20, activation='relu'kernel_initializer='he_normal')(visible)  
 hidden2 = Dense(10, activation='relu'kernel_initializer='he_normal')(hidden1) 
  • 1.
  • 2.
  • 3.
  • 4.

然后,我们可以定义两个单独的输出层,它们连接到模型的第二个隐藏层。

第一个是具有单个节点和线性激活函数的回归输出层。 

# regression output  
out_reg = Dense(1, activation='linear')(hidden2) 
  • 1.
  • 2.

第二个是分类输出层,对于每个要预测的类都有一个节点,并使用softmax激活函数。 

# classification output  
out_clas = Dense(n_class, activation='softmax')(hidden2) 
  • 1.
  • 2.

然后,我们可以使用一个输入层和两个输出层定义模型。 

# define model  
model = Model(inputs=visibleoutputs=[out_reg, out_clas]) 
  • 1.
  • 2.

给定两个输出层,我们可以使用两个损失函数来编译模型,第一个(回归)输出层的均方误差损失和第二个(分类)输出层的稀疏分类交叉熵。 

# compile the keras model  
model.compile(loss=['mse','sparse_categorical_crossentropy'], optimizer='adam'
  • 1.
  • 2.

我们还可以创建模型图以供参考。这需要安装pydot和pygraphviz。如果存在问题,则可以注释掉该行以及 plot_model()函数的import语句。 

# plot graph of model  
plot_model(model, to_file='model.png'show_shapes=True
  • 1.
  • 2.

每次模型进行预测时,它将预测两个值。同样,训练模型时,每个输出每个样本将需要一个目标变量。这样,我们可以训练模型,并仔细地向模型的每个输出提供回归目标和分类目标数据。 

# plot graph of model  
plot_model(model, to_file='model.png'show_shapes=True
  • 1.
  • 2.

然后,拟合模型可以对保留测试集中的每个示例进行回归和分类预测。 

# make predictions on test set  
yhat1, yhat2 = model.predict(X_test) 
  • 1.
  • 2.

第一个数组可用于通过平均绝对误差评估回归预测。 

# calculate error for regression model  
error = mean_absolute_error(y_test, yhat1) 
 print('MAE: %.3f'% error) 
  • 1.
  • 2.
  • 3.

第二个数组可用于通过分类准确性评估分类预测。 

# evaluate accuracy for classification model  
yhat2 = argmax(yhat2, axis=-1).astype('int')  
acc = accuracy_score(y_test_class, yhat2) 
 print('Accuracy: %.3f'% acc) 
  • 1.
  • 2.
  • 3.
  • 4.

就是这样。结合在一起,下面列出了训练和评估用于鲍鱼数据集上的组合器回归和分类预测的多输出模型的完整示例。 

# mlp for combined regression and classification predictions on the abalone dataset  
  from numpy import unique  
  from numpy import argmax  
  from pandas import read_csv  
  from sklearn.metrics import mean_absolute_error  
  from sklearn.metrics import accuracy_score  
  from sklearn.model_selection import train_test_split  
  from sklearn.preprocessing importLabelEncoder  
  from tensorflow.keras.models importModel  
  from tensorflow.keras.layers importInput  
  from tensorflow.keras.layers importDense  
  from tensorflow.keras.utils import plot_model  
  # load dataset 
   url = 'https://raw.githubusercontent.com/jbrownlee/Datasets/master/abalone.csv'  
  dataframe = read_csv(url, header=None 
  dataset = dataframe.values  
  # split into input (X) and output (y) variables  
  X, y = dataset[:, 1:-1], dataset[:, -1]  
  X, y = X.astype('float'), y.astype('float')  
  n_features = X.shape[1]  
  # encode strings to integer  
  y_class = LabelEncoder().fit_transform(y)  
  n_class = len(unique(y_class))  
  # split data into train and test sets  
  X_train, X_test, y_train, y_test, y_train_class, y_test_class = train_test_split(X, y, y_class, test_size=0.33, random_state=1
   # input  
  visible = Input(shape=(n_features,))  
  hidden1 = Dense(20, activation='relu'kernel_initializer='he_normal')(visible)  
  hidden2 = Dense(10, activation='relu'kernel_initializer='he_normal')(hidden1)  
  # regression output  
  out_reg = Dense(1, activation='linear')(hidden2)  
  # classification output  
  out_clas = Dense(n_class, activation='softmax')(hidden2)  
  # define model  
  model = Model(inputs=visibleoutputs=[out_reg, out_clas])  
  # compile the keras model  
  model.compile(loss=['mse','sparse_categorical_crossentropy'], optimizer='adam' 
  # plot graph of model  
  plot_model(model, to_file='model.png'show_shapes=True 
  # fit the keras model on the dataset  
  model.fit(X_train, [y_train,y_train_class], epochs=150batch_size=32verbose=2 
  # make predictions on test set  
  yhat1, yhat2 = model.predict(X_test)  
  # calculate error for regression model  
  error = mean_absolute_error(y_test, yhat1)  
  print('MAE: %.3f'% error)  
  # evaluate accuracy for classification model  
  yhat2 = argmax(yhat2, axis=-1).astype('int')  
  acc = accuracy_score(y_test_class, yhat2)  
  print('Accuracy: %.3f'% acc) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.

运行示例将准备数据集,拟合模型并报告模型误差的估计值。

注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。考虑运行该示例几次并比较平均结果。

创建了多输出模型图,清楚地显示了连接到模型第二个隐藏层的回归(左)和分类(右)输出层。

在这种情况下,我们可以看到该模型既实现了约1.495 的合理误差,又实现了与之前相似的约25.6%的精度。   

Epoch145/150  
   88/88- 0s- loss: 6.5707- dense_2_loss: 4.5396- dense_3_loss: 2.0311  
   Epoch146/150  
   88/88- 0s- loss: 6.5753- dense_2_loss: 4.5466- dense_3_loss: 2.0287  
   Epoch147/150 
   88/88- 0s- loss: 6.5970- dense_2_loss: 4.5723- dense_3_loss: 2.0247  
   Epoch148/150  
   88/88- 0s- loss: 6.5640- dense_2_loss: 4.5389- dense_3_loss: 2.0251  
   Epoch149/150  
   88/88- 0s- loss: 6.6053- dense_2_loss: 4.5827- dense_3_loss: 2.0226  
   Epoch150/150  
   88/88- 0s- loss: 6.5754- dense_2_loss: 4.5524- dense_3_loss: 2.0230  
   MAE: 1.495  
   Accuracy: 0.256  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
责任编辑:庞桂玉 来源: Python中文社区
相关推荐

2024-01-01 15:37:59

机器学习神经网络

2024-07-10 11:09:35

2017-08-04 14:23:04

机器学习神经网络TensorFlow

2022-06-16 10:29:33

神经网络图像分类算法

2019-01-05 08:40:17

VGG神经网络

2023-06-18 23:00:39

神经网络损失函数随机变量

2017-08-25 14:23:44

TensorFlow神经网络文本分类

2025-02-19 15:12:17

神经网络PyTorch大模型

2019-05-07 19:12:28

机器学习神经网络Python

2018-07-03 16:10:04

神经网络生物神经网络人工神经网络

2023-02-28 08:00:00

深度学习神经网络人工智能

2023-11-14 16:29:14

深度学习

2018-02-02 17:08:48

机器学习算法决策树

2018-02-27 09:32:13

神经网络自然语言初探

2020-04-20 13:45:32

神经网络模型代码

2018-02-05 08:58:36

Python神经网络识别图像

2017-08-28 21:31:37

TensorFlow深度学习神经网络

2025-03-31 08:50:00

模型量化神经网络AI

2025-02-24 08:00:00

机器学习ML架构

2023-09-17 23:09:24

Transforme深度学习
点赞
收藏

51CTO技术栈公众号