草庐IT

如何利用Keras 深度学习库的进行回归

来西瓜 2023-03-28 原文
1 问题描述 

2 开发基线神经网络模型 

3 标准化数据集建模 

4 调整神经网络拓扑 

  4.1 评估更深层次的网络拓扑 

  4.2 评估更广泛的网络拓扑 

5 总结 

  Keras 是一个包含高效数值库 Theano 和 TensorFlow 的深度学习库。在这篇文章中,您将了解如何使用 Keras 开发和评估神经网络模型来解决回归问题。在本文中您将了解:

  • 如何加载 CSV 数据集并使其可用于 Keras。
  • 如何使用 Keras 为回归问题创建神经网络模型。
  • 如何使用 scikit-learn 和 Keras 来评估使用交叉验证的模型。
  • 如何执行数据准备以提高 Keras 模型的技能。
  • 如何使用 Keras 调整模型的网络拓扑。
1 问题描述

  我们将在本教程中研究的问题是波士顿房价数据集。您可以下载此数据集并将其保存到您当前的工作中,直接使用文件名 Housing.csv。数据集描述了波士顿郊区房屋的数值属性,并关注以数千美元为单位对这些郊区的房(分开)屋价格进行建模。 因此,这是一个回归预测建模问题。 输入属性包括犯罪率、非零售商业面积的比例、化学品浓度等。

   这是机器学习中一个经过充分研究的问题。 使用起来很方便,因为所有输入和输出属性都是数字的,并且有 506 个实例可供使用。使用均方误差 (MSE) 评估的模型的合理性能约为 20 美元的平方数(如果您愿意,则为 4,500 美元) 取平方根)。 这是我们的神经网络模型的一个目标。

2 开发基线神经网络模型

  在本节中,我们将为回归问题创建一个基线神经网络模型。让我们从包含本文所需的所有函数和对象开始。

import pandas
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
...
  我们现在可以从本地目录中的文件加载我们的数据集。数据集实际上不是 UCI 机器学习存储库中的 CSV 格式,而是用空格分隔属性。 我们可以使用 pandas 库轻松加载它。 然后,我们可以拆分输入 (X) 和输出 (Y) 属性,以便更容易使用 Keras 和 scikit-learn 进行建模。

...
dataframe = pandas.read_csv("housing.csv", delim_whitespace=True, header=None)
dataset = dataframe.values
X = dataset[:,0:13]
Y = dataset[:,13]
  我们可以使用 Keras 库对象创建 Keras 模型并使用 scikit-learn 对其进行评估。 这是可取的,因为 scikit-learn 擅长评估模型,并且允许我们使用强大的数据准备和模型评估方案,只需要很少的代码行。

  Keras 包装器需要一个函数作为参数。 我们必须定义的这个函数负责创建要评估的神经网络模型。

  下面我们定义函数来创建要评估的基线模型。 这是一个简单的模型,它有一个完全连接的隐藏层,其神经元数量与输入属性 (13) 相同。 该网络网络中使用的参数为最佳实践,例如隐藏层的整流器激活函数。 输出层没有使用激活函数,因为它是一个回归问题,我们有兴趣直接预测数值而不进行变换。

  使用高效的 ADAM 优化算法并优化均方误差损失函数。 这将与我们用于评估模型性能的指标相同。 这是一个理想的度量标准,因为通过取平方根,我们可以得到一个误差值,我们可以在问题的上下文中直接理解(数千美元)。

...
def baseline_model():
model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
  在 scikit-learn 中用作回归估计器的 Keras 包装器对象称为 KerasRegressor。 我们创建一个实例并将创建神经网络模型的函数名称以及稍后传递给模型的 fit() 函数的一些参数传递给它,例如 epoch 数和批量大小。 这两个都设置为合理的默认值。最后一步是评估这个基线模型。 我们将使用 10 折交叉验证来评估模型。

...
kfold = KFold(n_splits=10)
results = cross_val_score(estimator, X, Y, cv=kfold)
print("Results: %.2f (%.2f) MSE" % (results.mean(), results.std()))
  将所有这些结合在一起,下面列出了完整的示例。

from pandas import read_csv
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
dataframe = read_csv("housing.csv", delim_whitespace=True, header=None)
dataset = dataframe.values
X = dataset[:,0:13]
Y = dataset[:,13]
def baseline_model():
model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
estimator = KerasRegressor(build_fn=baseline_model, epochs=100, batch_size=5, verbose=0)
kfold = KFold(n_splits=10)
results = cross_val_score(estimator, X, Y, cv=kfold)
print("Baseline: %.2f (%.2f) MSE" % (results.mean(), results.std()))
  运行此代码可以让我们估计模型在未见数据问题上的性能。

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

  注意:均方误差是负数,因为 scikit-learn 会反转,从而使度量最大化而不是最小化。 您可以忽略结果的符号。

  结果报告了均方误差,包括交叉验证评估的所有 10 倍的平均值和标准偏差(平均方差)。

Baseline: -32.65 (23.33) MSE
3 标准化数据集建模

  波士顿房价数据集的一个重要问题是输入属性的尺度各不相同,因为它们测量不同的数量。在使用神经网络模型对其进行建模之前准备数据几乎总是一种好习惯。从上述基线继续优化模型,我们可以使用输入数据集的标准化版本重新评估相同的模型。

  我们可以使用 scikit-learn 的 Pipeline 框架在模型评估过程中,在交叉验证的每个折叠中执行标准化。 这确保了每个测试集交叉验证折叠没有数据泄漏到训练数据中。下面的代码创建了一个 scikit-learn 管道,它首先标准化数据集,然后创建和评估基线神经网络模型。

  下面的代码创建了一个 scikit-learn 管道,它首先标准化数据集,然后创建和评估基线神经网络模型。

...
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=baseline_model, epochs=50, batch_size=5, verbose=0)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Standardized: %.2f (%.2f) MSE" % (results.mean(), results.std()))
from pandas import read_csv
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
dataframe = read_csv("housing.csv", delim_whitespace=True, header=None)
dataset = dataframe.values
X = dataset[:,0:13]
Y = dataset[:,13]
def baseline_model():
model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=baseline_model, epochs=50, batch_size=5, verbose=0)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Standardized: %.2f (%.2f) MSE" % (results.mean(), results.std()))
  注意:您的结果可能会因算法或评估过程的随机性或数值精度的差异而有所不同。 考虑运行该示例几次并比较平均结果。

  在没有标准化数据的情况下,运行该示例提供了比基线模型更好的性能,从而消除了错误。

Standardized: -29.54 (27.87) MSE
  本节的进一步扩展将类似地对输出变量应用重新缩放,例如将其归一化到 0-1 的范围,并在输出层上使用 Sigmoid 或类似的激活函数将输出预测缩小到相同的范围。

4 调整神经网络拓扑

  有很多问题可以针对神经网络模型进行优化。也许最大的杠杆点是网络本身的结构,包括层数和每层中的神经元数量。在本节中,我们将评估另外两个 网络拓扑结构,以进一步提高模型的性能。 我们将研究更深和更广泛的网络拓扑。

4.1 评估更深层次的网络拓扑

  提高神经网络性能的一种方法是添加更多层。 这可能允许模型提取和重组嵌入在数据中的高阶特征。在本节中,我们将评估向模型添加一个隐藏层的效果。 这就像定义一个新函数一样简单,该函数将创建这个更深层次的模型,从我们上面的基线模型中复制而来。 然后我们可以在第一个隐藏层之后插入一个新行。 在这种情况下,大约有一半的神经元数量。

...
def larger_model():
model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(6, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.compile(loss='mean_squared_error', optimizer='adam')
return model

  我们的网络拓扑现在看起来像:

13 inputs -> [13 -> 6] -> 1 output
  我们可以以与上述相同的方式评估此网络拓扑,同时还使用上述数据集的标准化来提高性能。

...
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=larger_model, epochs=50, batch_size=5, verbose=0)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Larger: %.2f (%.2f) MSE" % (results.mean(), results.std()))
  将这些结合在一起,下面列出了完整的示例。

from pandas import read_csv
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
dataframe = read_csv("housing.csv", delim_whitespace=True, header=None)
dataset = dataframe.values
X = dataset[:,0:13]
Y = dataset[:,13]
def larger_model():
model = Sequential()
model.add(Dense(13, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(6, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=larger_model, epochs=50, batch_size=5, verbose=0)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Larger: %.2f (%.2f) MSE" % (results.mean(), results.std()))
  注意:您的结果可能会因算法或评估过程的随机性或数值精度的差异而有所不同。 考虑运行该示例几次并比较平均结果。

  运行此模型确实显示性能进一步提高,从 28 降至 24000 平方美元。

4.2 评估更广泛的网络拓扑

  增加模型表示能力的另一种方法是创建更广泛的网络。在本节中,我们评估了保持浅层网络架构并将一个隐藏层中的神经元数量几乎翻倍的效果。 同样,我们需要做的就是定义一个新函数来创建我们的神经网络模型。 在这里,与基线模型相比,我们将隐藏层中的神经元数量从 13 个增加到 20 个。

...
def wider_model():
model = Sequential()
model.add(Dense(20, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
  我们的网络拓扑现在看起来像:

13 inputs -> [20] -> 1 output
  我们可以使用与上述相同的方案来评估更广泛的网络拓扑:

...
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=wider_model, epochs=100, batch_size=5, verbose=0)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Wider: %.2f (%.2f) MSE" % (results.mean(), results.std()))
  将这些结合在一起,下面列出了完整的示例。

from pandas import read_csv
from keras.models import Sequential
from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
dataframe = read_csv("housing.csv", delim_whitespace=True, header=None)
dataset = dataframe.values
X = dataset[:,0:13]
Y = dataset[:,13]
def wider_model():
model = Sequential()
model.add(Dense(20, input_dim=13, kernel_initializer='normal', activation='relu'))
model.add(Dense(1, kernel_initializer='normal'))
model.compile(loss='mean_squared_error', optimizer='adam')
return model
estimators = []
estimators.append(('standardize', StandardScaler()))
estimators.append(('mlp', KerasRegressor(build_fn=wider_model, epochs=100, batch_size=5, verbose=0)))
pipeline = Pipeline(estimators)
kfold = KFold(n_splits=10)
results = cross_val_score(pipeline, X, Y, cv=kfold)
print("Wider: %.2f (%.2f) MSE" % (results.mean(), results.std()))
  注意:您的结果可能会因算法或评估过程的随机性或数值精度的差异而有所不同。 考虑运行该示例几次并比较平均结果。

  构建模型确实看到误差进一步下降到大约 21000 平方美元。 对于这个问题,这不是一个坏结果。

Wider: -21.71 (24.39) MSE
  很难猜测更广泛的网络会在这个问题上胜过更深的网络。 结果证明了在开发神经网络模型时经验测试的重要性。

5 总结

  在这篇文章中,您发现了用于建模回归问题的 Keras 深度学习库。通过本教程,您学习了如何开发和评估神经网络模型,包括:

  • 如何加载数据和开发基线模型。
  • 如何使用标准化等数据准备技术提升性能。
  • 如何在一个问题上设计和评估具有不同拓扑的网络。

有关如何利用Keras 深度学习库的进行回归的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  4. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  5. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  6. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  7. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  8. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  9. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  10. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

随机推荐