摘要: 想转行机器学习?块使用keras实现回归与分类两个具体的机器学习方法吧。

深度学习是机器学习领域中越来越热门的研究子集,一般而言,深度学习模型是使用神经网络构建而成。神经网络模型接收输入,然后使用在训练期间调整得到的权重在隐藏层中对输入进行相应的处理,然后在模型末端输出预测值。调整权重以找到相应的规则以便更好地进行预测,在这个过程中,用户不需要人为地指定要获得的模式,而是神经网络模型在数据集上进行自我学习。

Keras是一个使用Python语言编写的神经网络工具箱,该工具箱对用户使用十分友好。在本教程中,将使用Keras实现两个深度学习模型:一个用于回归,一个用于分类。其中,建立的回归模型用来预测员工每小时的工资,建立的分类模型来预测患者是否患有糖尿病。

注意:本教程使用的数据集相对干净,因此不会进行任何的数据预处理操作,就可以直接在建模时使用。如果在未来项目中,使用的数据集可能并不是那么干净整齐,例如,可能缺少某些值,这个时候就需要使用数据预处理技术来更改数据集,以获得更准确的结果。

阅读训练数据

对于回归深度学习模型而言,第一步是读入用作输入的数据。在此示例中,使用“小时工资(hourly wages)”数据集。首先,我们使用Pandas读入数据,在这里,不会介绍pandas包的相关细节,如果你想进一步深入学习数据科学或者机器学习,你应该对其熟悉。

'df'代表数据帧,Pandas将csv文件作为数据帧读入。在head()函数将显示前5行数据帧,以便检查数据是否已被正确读取,从中可以看到初始数据是如何构成的。

Import pandas as pd
#read in data using pandas
train_df = pd.read_csv(‘data/hourly_wages_data.csv’)
#check data has been read in properly
train_df.head()

将数据集拆分为输入和标签(目标值)

接下来,需要将数据集拆分为输入值(train_X)和目标值(train_y)。其中,输入将是除了'wage_per_hour'之外的所有列数据,'wage_per_hour'是将要尝试预测的内容。因此,'wage_per_hour'变成了标签(目标值)。

使用pandas中的'drop'函数就可以从数据帧中删除'wage_per_hour'列,并将其存储在变量'train_X'中。以下是实现代码

#create a dataframe with all training data except the target column
train_X = train_df.drop(columns=['wage_per_hour'])

#check that the target variable has been removed
train_X.head()

同理,将'wage_per_hour'列单独取出来作为目标值:

#create a dataframe with only the target column
train_y = train_df[['wage_per_hour']]

#view dataframe
train_y.head()

建立模型

接下来,需要构建模型。代码如下:

from keras.models import Sequential
from keras.layers import Dense
#create model
model = Sequential()

#get number of columns in training data
n_cols = train_X.shape[1]

#add model layers
model.add(Dense(10, activation='relu', input_shape=(n_cols,)))
model.add(Dense(10, activation='relu'))
model.add(Dense(1))

本教程使用的模型类型是Sequential。Sequential是在Keras中构建模型的最简单方法。它允许我们逐层构建模型,每个层都具有与其后面的层对应的权重。

之后,使用add()函数将模板添加到模型中。上述代码添加了两个隐藏层和一个输出层。

稠密(Dense)层`是一种图层类型,该层是一种适用于大多数情况的标准图层类型。在Dense层中,上一层中的所有节点都连接到当前层中的节点。
       模型中,每个输入层都有10个节点。当然,节点的数量也可以是数百或数千。增加每层的节点数会导致模型体积增大、变复杂,这点将在稍后详细介绍。

激活(Activation)层`是实现激活函数功能,激活函数允许模型考虑非线性关系,这取决于激活函数的类型。

本教程使用的激活函数是深度学习中常用的ReLU或整流线性激活(Rectified Linear Activation),虽然它是由两个线性部分组成,但它已被证明在神经网络模型中表现良好。

ReLU激活函数

第一层需要输入形状,输入形状指定模型输入的行数和列数。输入的列数存储在n_cols中。逗号后面没有跟任何内容,这样表示可以有任意数量的行。

最后一层是输出层,它只有一个节点,用于输出预测值。

编译模型

接下来,需要编译构建的模型。编译模型需要设置两个参数:优化器(optmizer)和损失函数(loss)。

优化器控制学习速率(learning rate),本文使用adam作为选择器。一般情况下,Adam通常是一个很好的优化器,它会在整个训练过程中调整学习率。

学习速率决定了更新模型的权重的速度。较小的学习率可能会导致更准确的权重,但花费的时间也会更长。

对于损失函数而言,本文使用均方误差'mean_squared_error'。它是通过取预测值和实际值之间的平均平方差来计算得到,这也是回归问题中比较常用的损失函数。损失值越接近0,模型表现得越好。

均方误差

#compile model using mse as a measure of model performance
model.compile(optimizer='adam', loss='mean_squared_error')

训练模型

现在训练之前构建的模型,在训练过程中,将在模型上使用fit()函数,该函数具有以下五个参数:训练数据(train_X)、目标数据(train_y)、验证拆分、迭代次数和回调。

验证拆分将数据随机分割以用于训练和测试。在训练期间,我们将能够看到验证损失,它会给出了验证集上模型的均方误差。本文将验证分割率设置为0.2,这意味着在模型中,20%的训练数据将被留出来用于测试模型的性能。

迭代数是模型运行循环数据的次数。运行的次数越多,模型就会越来越趋近于稳定,直到某一点。在那之后,模型将不会有大的改进。此外,迭代次数越多,模型运行的时间就越长。当模型提前达到性能预期后,可以使用“提前停止(early stopping)”。

如果模型停止改进,提前停止将在达到设定的迭代次数之前停止模型训练。本文将提前停止监视器设置为3,这意味着在连续3次运行后,模型的性能没有改进的话,训练将会被停止。

from keras.callbacks import EarlyStopping
#set early stopping monitor so the model stops training when it won't improve anymore
early_stopping_monitor = EarlyStopping(patience=3)
#train model
model.fit(train_X, train_y, validation_split=0.2, epochs=30, callbacks=[early_stopping_monitor])

对新数据进行预测

如果想使用此模型对新数据进行预测,我们可以使用'predict()'函数,传入新数据。输出将是'wage_per_hour'预测。

#example on how to use our newly trained model on how to make predictions on unseen data (we will pretend our new data is saved in a dataframe called 'test_X').
test_y_predictions = model.predict(test_X)

完成以上整个过程,你就已经在Keras建立了一个深度学习模型!虽然它还不是很准确,但可以通过使用更多的训练数据和层数来改善。

模型体积

随着模型中节点和层数的增加,模型的体积也会增加。增加模型体积可以产生更准确的模型,但也会有个上限值。通常,提供的训练数据越多,模型一般也应该越大。本文只使用了少量的数据,所以本文构建的模型非常小。模型越大,它需要的计算能力越多,训练也会花费更长的时间。

下面在与之前模型相同的训练数据上创建一个新模型,该模型与上文中的模型差别在于添加了一个图层并将每个图层中的节点增加到200个,之后训练模型以查看增加模型体积是否会提高验证分数。

#training a new model on the same data to show the effect of increasing model capacity

#create model
model_mc = Sequential()

#add model layers
model_mc.add(Dense(200, activation='relu', input_shape=(n_cols,)))
model_mc.add(Dense(200, activation='relu'))
model_mc.add(Dense(200, activation='relu'))
model_mc.add(Dense(1))

#compile model using mse as a measure of model performance
model_mc.compile(optimizer='adam', loss='mean_squared_error')
#train model
model_mc.fit(train_X, train_y, validation_split=0.2, epochs=30, callbacks=[early_stopping_monitor])

从上面的结果可以看出,通过提高模型体积,我们将验证损失从之前模型中的32.63降低为28.06。

分类模型

现在让我们继续构建一个分类模型。由于分类模型的相关步骤和之前介绍的回归模型类似,这里只讨论一些新的概念。本文构建的分类模型用于预测患者是否患有糖尿病。

#read in training data
train_df_2 = pd.read_csv('documents/data/diabetes_data.csv')

#view data structure
train_df_2.head()

#create a dataframe with all training data except the target column
train_X_2 = df_2.drop(columns=['diabetes'])

#check that the target variable has been removed
train_X_2.head()

在分离目标列时,我们需要调用'to_categorical()'函数,以便该列是'one-hot'编码。目前,没有糖尿病的患者在糖尿病历栏中用0表示,而患有糖尿病的患者用1表示。使用one-hot编码,将每个类别输入转换为二进制变量。在本文案例中,分为两类:无糖尿病和糖尿病。没有糖尿病的患者将由[1 0]表示,患有糖尿病的患者将由[0 1]表示:

from keras.utils import to_categorical
#one-hot encode target column
train_y_2 = to_categorical(df_2.diabetes)

#vcheck that target column has been converted
train_y_2[0:5]

#create model
model_2 = Sequential()

#get number of columns in training data
n_cols_2 = train_X_2.shape[1]

#add layers to model
model_2.add(Dense(250, activation='relu', input_shape=(n_cols_2,)))
model_2.add(Dense(250, activation='relu'))
model_2.add(Dense(250, activation='relu'))
model_2.add(Dense(2, activation='softmax'))

模型的最后一层有2个节点, 对应着两个选项:患者是否患有糖尿病。

在这个模型中,激活函数选用'softmax'。Softmax使得输出总和达到1,因此可以将输出解释为概率。然后,模型将基于哪个选项具有最高概率来进行预测。

#compile model using accuracy to measure model performance
model_2.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

分类模型中,将使用'类别交叉熵(categorical_crossentropy)'来表示损失函数,该函数也是分类模型中最为常见的选择,损失函数的值越低,表示模型的性能越好。

为了使得更容易理解,本文使用“准确度(accuracy’)”指标来查看每次迭代运行结束时验证集的准确度分数。

#train model
model_2.fit(X_2, target, epochs=30, validation_split=0.2, callbacks=[early_stopping_monitor])

以上就是全部的内容,可以在此github处找到本教程的全部源码,感谢阅读!

本文作者:【方向】

阅读原文

本文为云栖社区原创内容,未经允许不得转载。


阿里云云栖号
27.8k 声望35.7k 粉丝

阿里云官网内容平台