• 欢迎访问交通人网站!
  • 分享一款小游戏:信任的进化
  •    发表于7年前 (2018-06-04)  热点资讯 |   抢沙发  801 
    文章评分 0 次,平均分 0.0

    当你在 Keras 中选择好最合适的深度学习模型,就可以用它在新的数据实例上做预测了。但是很多初学者不知道该怎样做好这一点,我经常能看到下面这样的问题:“我应该如何用 Keras 对我的模型作出预测?”

    在本文中,你会学到如何使用 Keras 这个 Python 库完成深度学习模型的分类与回归预测。看完这篇教程,你能掌握以下几点:

    • 如何确定一个模型,为后续的预测做准备;
    • 如何用 Keras 对分类问题进行类及其概率的预测;
    • 如何用 Keras 进行回归预测。

    现在就让我们开始吧!

    模型确定

    在做预测之前,首先得训练出一个最终的模型。你可能选择 k 折交叉验证或者简单划分训练/测试集的方法来训练模型,这样做的目的是为了合理估计模型在样本集之外数据上的表现。

    当评估完成,这些模型存在的目的也达到了,就可以丢弃他们。接下来,你得用所有的可用数据训练出一个最终的模型。关于这方面的内容,你可以在下面这个文章中得到更多的信息:How to Train a Final Machine Learning Model

    分类预测

    对于分类问题,模型学习的是一个输入特征到输出特征之间的映射,这里的输出即为一个标签,比如“垃圾邮件”和“非垃圾邮件”。

    下边是 Keras 中为简单的二分类问题开发的神经网络模型的一个例子。如果说你以前没有接触过用 Keras 开发神经网络模型的话,不妨先看看下边这篇文章:Develop Your First Neural Network in Python With Keras Step-By-Step

    # 训练一个最终分类的模型:
    from keras.models import Sequential
    from keras.layers import Dense
    from sklearn.datasets.samples_generator import make_blobs
    from sklearn.preprocessing import MinMaxScaler
    
    # 生成一个二分类问题的数据集
    X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=1)
    scalar = MinMaxScaler()
    scalar.fit(X)
    X = scalar.transform(X)
    
    # 定义并拟合模型
    model = Sequential()
    model.add(Dense(4, input_dim=2, activation='relu'))
    model.add(Dense(4, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='adam')
    model.fit(X, y, epochs=200, verbose=0)
    

    建立好这个模型后,可能需要将它保存到文件中(比如通过 Keras 的相关 API)。以后你就可以随时加载这个模型,并用它进行预测了。有关这方面的示例,可以参考下边的文章:Save and Load Your Keras Deep Learning Models

    为了本文的结构更简洁,我们的例子中省去了这个步骤。

    继续说回到分类预测的问题。我们希望最终得到的模型能进行两种预测:一是判断出类别,二是给出属于相应类别概率。

    分类预测

    一个类别预测会给定最终的模型以及若干数据实例,我们利用模型来判断这些实例的类别。对于新数据,我们不知道输出的是什么结果,这就是为什么首先需要一个模型。

    在 Keras 中,可以利用 predict_class() 函数来完成我们上述所说的内容——即利用最终的模型预测新数据样本的类别。

    需要注意的是,这个函数仅适用于 Sequential 模型,不适于使用功能式 API 开发的模型。

    比如,我们在名为 Xnew 的数组中有若干个数据实例,它被传入 predict_classes() 函数中,用来对这些数据样本的类别进行预测。

    Xnew = [[...], [...]]
    ynew = model.predict_classes(Xnew)
    

    让我们用一个更具体的例子来说明:

    # 建立一个新的分类模型
    from keras.models import Sequential
    from keras.layers import Dense
    from sklearn.datasets.samples_generator import make_blobs
    from sklearn.preprocessing import MinMaxScaler
    
    # 生成二分类数据集
    X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=1)
    scalar = MinMaxScaler()
    scalar.fit(X)
    X = scalar.transform(X)
    
    # 定义并拟合最终模型
    model = Sequential()
    model.add(Dense(4, input_dim=2, activation='relu'))
    model.add(Dense(4, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='adam')
    model.fit(X, y, epochs=500, verbose=0)
    
    # 新的未知数据实例
    Xnew, _ = make_blobs(n_samples=3, centers=2, n_features=2, random_state=1)
    Xnew = scalar.transform(Xnew)
    
    # 作出预测
    ynew = model.predict_classes(Xnew)
    
    # 显示输入和输出
    for i in range(len(Xnew)):
    print("X=%s, Predicted=%s" % (Xnew[i], ynew[i]))
    

    下面是对三个实例预测的结果,我们将数据和预测结果一并输出:

    X=[0.89337759 0.65864154], Predicted=[0]
    X=[0.29097707 0.12978982], Predicted=[1]
    X=[0.78082614 0.75391697], Predicted=[0]
    

    如果你只有一个新的实例,那就需要将它包装一下,变成一个数组的形式。以便传给 predict_classes() 函数,比如这样:

    from keras.models import Sequential
    from keras.layers import Dense
    from sklearn.datasets.samples_generator import make_blobs
    from sklearn.preprocessing import MinMaxScaler
    from numpy import array
    
    # 生成一个二分类数据集
    X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=1)
    scalar = MinMaxScaler()
    scalar.fit(X)
    X = scalar.transform(X)
    
    # 定义并拟合最终的新模型
    model = Sequential()
    model.add(Dense(4, input_dim=2, activation='relu'))
    model.add(Dense(4, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='adam')
    model.fit(X, y, epochs=500, verbose=0)
    
    # 未知的新实例
    Xnew = array([[0.89337759, 0.65864154]])
    
    # 作出预测
    ynew = model.predict_classes(Xnew)
    
    # 显示输入输出
    print("X=%s, Predicted=%s" % (Xnew[0], ynew[0]))
    

    运行上边这个例子,会得到对这个单独实例的预测结果

    X=[0.89337759 0.65864154], Predicted=[0]
    

    关于类别标签的注意事项

    准备数据时,应该将其中的类别标签转换为整数表示(比如原始数据类别可能是一个字符串),这时候你就可能会用到 sklearn 中的 LabelEncoder。

    当然,在我们使用 LabelEcoder 中的函数 inverse_transform() 时,还可以将那些整数表示的类别标签转换回去。

    因为这个原因,在拟合最终模型时,你可能想要保存用于编码 /(y/) 值的 LabelEncoder 结果。

    概率预测

    另外一种是对数据实例属于某一类的可能性进行预测。它被称为“概率预测”,当给定一个新的实例,模型返回该实例属于每一类的概率值(0-1之间)。

    在 Keras 中,我们可以调用 predict_proba() 函数来实现。举个例子:

    Xnew = [[...], [...]]
    ynew = model.predict_proba(Xnew)
    

    在二分类问题下,Sigmoid 激活函数常被用在输出层,预测概率是数据对象属于类别1的可能性,或者属于类别 0 的可能性(1-概率)。

    在多分类问题下,则是 softmax 激活函数常被用在输出层。数据对象属于每一个类别的概率作为一个向量返回。

    下边的例子对 Xnew 数据数组中的每个样本进行概率预测。

    from keras.models import Sequential
    from keras.layers import Dense
    from sklearn.datasets.samples_generator import make_blobs
    from sklearn.preprocessing import MinMaxScaler
    
    # 生成二分类数据集
    X, y = make_blobs(n_samples=100, centers=2, n_features=2, random_state=1)
    scalar = MinMaxScaler()
    scalar.fit(X)
    X = scalar.transform(X)
    
    # 定义并拟合出最终模型
    model = Sequential()
    model.add(Dense(4, input_dim=2, activation='relu'))
    model.add(Dense(4, activation='relu'))
    model.add(Dense(1, activation='sigmoid'))
    model.compile(loss='binary_crossentropy', optimizer='adam')
    model.fit(X, y, epochs=500, verbose=0)
    
    # 新的未知数据
    Xnew, _ = make_blobs(n_samples=3, centers=2, n_features=2, random_state=1)
    Xnew = scalar.transform(Xnew)
    
    # 做预测
    ynew = model.predict_proba(Xnew)
    
    # 显示输入输出
    for i in range(len(Xnew)):
    print("X=%s, Predicted=%s" % (Xnew[i], ynew[i]))
    

    我们运行这个实例,并将输入数据及这些实例属于类别1的概率打印出来:

    X=[0.89337759 0.65864154], Predicted=[0.0087348]
    X=[0.29097707 0.12978982], Predicted=[0.82020265]
    X=[0.78082614 0.75391697], Predicted=[0.00693122]
    

    回归预测

    回归预测是一个监督学习问题,该模型学习一个给定输入样本到输出数值的映射。比如会输出 0.1 或 0.2 这样的数字。

    下边是一个 Keras 回归的模型。

    # 训练一个回归模型的例子
    from keras.models import Sequential
    from keras.layers import Dense
    from sklearn.datasets import make_regression
    from sklearn.preprocessing import MinMaxScaler
    
    # 生成回归数据集
    X, y = make_regression(n_samples=100, n_features=2, noise=0.1, random_state=1)
    scalarX, scalarY = MinMaxScaler(), MinMaxScaler()
    scalarX.fit(X)
    scalarY.fit(y.reshape(100,1))
    X = scalarX.transform(X)
    y = scalarY.transform(y.reshape(100,1))
    
    # 定义并拟合模型
    model = Sequential()
    model.add(Dense(4, input_dim=2, activation='relu'))
    model.add(Dense(4, activation='relu'))
    model.add(Dense(1, activation='linear'))
    model.compile(loss='mse', optimizer='adam')
    model.fit(X, y, epochs=1000, verbose=0)
    

    我们可以在最终的模型中调用 predict() 函数进行数值的预测。该函数以若干个实例组成的数组作为输入参数。

    下面的例子演示了如何对未知的多个数据实例进行回归预测。

    from keras.models import Sequential
    from keras.layers import Dense
    from sklearn.datasets import make_regression
    from sklearn.preprocessing import MinMaxScaler
    
    # 生成回归数据集
    X, y = make_regression(n_samples=100, n_features=2, noise=0.1, random_state=1)
    scalarX, scalarY = MinMaxScaler(), MinMaxScaler()
    scalarX.fit(X)
    scalarY.fit(y.reshape(100,1))
    X = scalarX.transform(X)
    y = scalarY.transform(y.reshape(100,1))
    
    # 定义并拟合模型
    model = Sequential()
    model.add(Dense(4, input_dim=2, activation='relu'))
    model.add(Dense(4, activation='relu'))
    model.add(Dense(1, activation='linear'))
    model.compile(loss='mse', optimizer='adam')
    model.fit(X, y, epochs=1000, verbose=0)
    
    # 未知的新数据
    Xnew, a = make_regression(n_samples=3, n_features=2, noise=0.1, random_state=1)
    Xnew = scalarX.transform(Xnew)
    
    # 作出预测
    ynew = model.predict(Xnew)
    
    # 显示输入输出
    for i in range(len(Xnew)):
    print("X=%s, Predicted=%s" % (Xnew[i], ynew[i]))
    

    运行上面那个多分类预测实例,然后将输入和预测结果并排打印,进行对比。

    X=[0.29466096 0.30317302], Predicted=[0.17097184]
    X=[0.39445118 0.79390858], Predicted=[0.7475489]
    X=[0.02884127 0.6208843 ], Predicted=[0.43370453]
    

    同样的,这个函数可以用于单独实例的预测,前提是它们包装成适当的格式。

    举例说明:

    from keras.models import Sequential
    from keras.layers import Dense
    from sklearn.datasets import make_regression
    from sklearn.preprocessing import MinMaxScaler
    from numpy import array
    
    # 生成回归数据集
    X, y = make_regression(n_samples=100, n_features=2, noise=0.1, random_state=1)
    scalarX, scalarY = MinMaxScaler(), MinMaxScaler()
    scalarX.fit(X)
    scalarY.fit(y.reshape(100,1))
    X = scalarX.transform(X)
    y = scalarY.transform(y.reshape(100,1))
    
    # 定义并拟合模型
    model = Sequential()
    model.add(Dense(4, input_dim=2, activation='relu'))
    model.add(Dense(4, activation='relu'))
    model.add(Dense(1, activation='linear'))
    model.compile(loss='mse', optimizer='adam')
    model.fit(X, y, epochs=1000, verbose=0)
    
    # 新的数据
    Xnew = array([[0.29466096, 0.30317302]])
    
    # 作出预测
    ynew = model.predict(Xnew)
    
    # 显示输入输出
    print("X=%s, Predicted=%s" % (Xnew[0], ynew[0]))
    

    运行实例并打印出结果:

    X=[0.29466096 0.30317302], Predicted=[0.17333156]
    
    交通人博客是交通人工作室(JTR Studio)建立的交通人系列网站之一,是交通人工作室的主阵地,旨在整合和分享交通行业相关资讯,具体包括但不限于行业新闻、行业动态,以及行业相关规范、书籍、报告和软件等资源。

    发表评论

    表情 格式

    暂无评论

    
    切换注册

    登录

    忘记密码 ?

    切换登录

    注册

    扫一扫二维码分享