带你读《TensorFlow机器学习实战指南(原书第2版)》之三:基于TensorFlow的线性回归

简介: 本书由资深数据科学家撰写,从实战角度系统讲解TensorFlow基本概念及各种应用实践。真实的应用场景和数据,丰富的代码实例,详尽的操作步骤,带领读者由浅入深系统掌握TensorFlow机器学习算法及其实现。本书第1章和第2章介绍了关于TensorFlow使用的基础知识,后续章节则针对一些典型算法和典型应用场景进行了实现,并配有较详细的程序说明,可读性非常强。读者如果能对其中代码进行复现,则必定会对TensorFlow的使用了如指掌。

点击查看第一章
点击查看第二章

第3章

基于TensorFlow的线性回归
本章将介绍TensorFlow是如何工作的,以及如何访问本书的数据集和补充学习资源。学完本章将掌握以下知识点:

  • 用TensorFlow求逆矩阵
  • 用TensorFlow实现矩阵分解
  • 用TensorFlow实现线性回归
  • 理解线性回归中的损失函数
  • 用TensorFlow实现戴明回归(Deming Regression)
  • 用TensorFlow实现Lasso回归和岭回归(Ridge Regression)
  • 用TensorFlow实现弹性网络回归(Elastic Net Regression)
  • 用TensorFlow实现逻辑回归

3.1 简介

线性回归算法是统计分析、机器学习和科学计算中最重要的算法之一,也是最常使用的算法之一,所以需要理解其是如何实现的,以及线性回归算法的各种优点。相对于许多其他算法来讲,线性回归算法是最易解释的。以每个特征的数值直接代表该特征对目标值或者因变量的影响。本章将揭晓线性回归算法的经典实现,然后讲解其在TensorFlow中的实现。
请读者注意,本书的所有源码均可以在GitHub中访问,网址为https://github.com/nfmcclure/tensorflow_cookbook ,也可访问Packt代码库https://github.com/PackPublishing/TensorFlow-Machine-Learning-Cookbook-Second-Edition

3.2 用TensorFlow求逆矩阵

本节将使用TensorFlow求逆矩阵的方法解决二维线性回归问题。

3.2.1 开始

线性回归算法能表示为矩阵计算,Ax = b。这里要解决的是用矩阵x来求解系数。注意,如果观测矩阵不是方阵,那求解出的矩阵x为x = (ATA) - 1ATb。为了更直观地展示这种情况,我们将生成二维数据,用TensorFlow来求解,然后绘制最终结果(见图3-1)。

image.png

3.2.2 动手做

1.导入必要的编程库,初始化计算图,并生成数据,代码如下:
image.png

2.创建后续求逆方法所需的矩阵。创建A矩阵,其为矩阵x_vals_column和ones_column的合并。然后以矩阵y_vals创建b矩阵,代码如下:
image.png

3.将A和b矩阵转换成张量,代码如下:
image.png

4.现在,使用TensorFlow的tf.matrix_inverse()方法,代码如下:
image.png

5.从解中抽取系数、斜率和y截距y-intercept,代码如下:
image.png

3.2.3 工作原理

与本书的大部分章节不一样的是,这里的解决方法是通过矩阵操作直接求解结果。大部分TensorFlow算法是通过迭代训练实现的,利用反向传播自动更新模型变量。这里通过实现数据直接求解的方法拟合模型,仅仅是为了说明TensorFlow的灵活用法。
我们使用了二维数据例子来展示数据的拟合。需要注意的是,求取系数的公式(x = (AT A)-1 AT b)能够根据需要扩展到数据中任意数量(但对共线性问题无效)。

3.3 用TensorFlow实现矩阵分解

本节将用TensorFlow为线性回归算法实现矩阵分解。特别地,我们会使用Cholesky矩阵分解法,相关的函数已在TensorFlow中实现。

3.3.1 开始

在上一节中实现的求逆矩阵的方法在大部分情况下是低效率的,特别地,当矩阵非常大时效率更低。另外一种实现方法是矩阵分解,此方法使用TensorFlow内建的Cholesky矩阵分解法。用户对将一个矩阵分解为多个矩阵的方法感兴趣的原因是,结果矩阵的特性使得其在应用中更高效。Cholesky矩阵分解法把一个矩阵分解为上三角矩阵和下三角矩阵,L和L'(L'和L互为转置矩阵)。求解Ax = b,改写成LL'x = b。首先求解Ly = b,然后求解L'x = y得到系数矩阵x。

3.3.2 动手做

1.导入编程库,初始化计算图,生成数据集。接着获取矩阵A和b,代码如下:
image.png
image.png

2.找到方阵的Cholesky矩阵分解,ATA:
image.png

注意,TensorFlow的cholesky()函数仅仅返回矩阵分解的下三角矩阵,因为上三角矩阵是下三角矩阵的转置矩阵。
3.抽取系数:
image.png

3.3.3 工作原理

正如你所看到的,最终求解的结果与前一节的相似。记住,通过分解矩阵的方法求解有时更高效并且数值稳定(见图3-2)。

3.4 用TensorFlow实现线性回归算法

虽然使用矩阵和分解方法非常强大,但TensorFlow有另一种方法来求解斜率和截距。它可以通过迭代做到这一点,逐步学习将最小化损失的最佳线性回归参数。

image.png

3.4.1 开始

本节将遍历批量数据点并让TensorFlow更新斜率和y截距。这次将使用Scikit Learn的内建iris数据集。特别地,我们将用数据点(x值代表花瓣宽度,y值代表花瓣长度)找到最优直线。选择这两种特征是因为它们具有线性关系,在后续结果中将会看到。下一节将讲解不同损失函数的影响,本节将使用L2正则损失函数。

3.4.2 动手做

1.导入必要的编程库,创建计算图,加载数据集,代码如下:
image.png

2.声明学习率、批量大小、占位符和模型变量,代码如下:
image.png

3.增加线性模型,y = Ax + b,代码如下:
image.png

4.声明L2损失函数,其为批量损失的平均值。初始化变量,声明优化器。注意,学习率设为0.05,代码如下:
image.png

5.现在遍历迭代,并在随机选择的批量数据上进行模型训练。迭代100次,每25次迭代输出变量值和损失值。注意,这里保存每次迭代的损失值,将其用于后续的可视化。代码如下:
image.png

6.抽取系数,创建最佳拟合直线,代码如下:
image.png

7.这里将绘制两幅图。第一幅图(见图3-3)是拟合的直线;第二幅图(见图3-4)是迭代100次的L2正则损失函数,代码如下:
image.png

image.png

image.png

这里很容易看出算法模型是过拟合还是欠拟合。将数据集分割成测试数据集和训练数据集,如果训练数据集的准确度更大,而测试数据集准确度更低,那么该拟合为过拟合;如果在测试数据集和训练数据集上的准确度都一直在增加,那么该拟合是欠拟合,需要继续训练。

3.4.3 工作原理

并不能保证最优直线是最佳拟合的直线。最佳拟合直线的收敛依赖迭代次数、批量大小、学习率和损失函数。最好时刻观察损失函数,它能帮助我们进行问题定位或者超参数
调整。

3.5 理解线性回归中的损失函数

理解各种损失函数在算法收敛的影响是非常重要的。这里将展示L1正则和L2正则损失函数对线性回归算法收敛的影响。

3.5.1 开始

这次继续使用上一节中的iris数据集,通过改变损失函数和学习率来观察收敛性的
变化。

3.5.2 动手做

1.除了损失函数外,程序的开始与以往一样,导入必要的编程库,创建一个会话,加载数据,创建占位符,定义变量和模型。我们将抽出学习率和模型迭代次数,以便展示调整这些参数的影响。代码如下:
image.png

2.损失函数改为L1正则损失函数,代码如下:
image.png

3.现在继续初始化变量,声明优化器,遍历迭代训练。注意,为了度量收敛性,每次迭代都会保存损失值。代码如下:
image.png
image.png

3.5.3 工作原理

当选择了一个损失函数时,也要选择对应的学习率。这里展示了两种解决方法,一种是上一节的L2正则损失函数,另一种是L1正则损失函数。
如果学习率太小,算法收敛耗时将更长。但是如果学习率太大,算法有可能产生不收敛的问题。下面绘制iris数据的线性回归问题的L1正则和L2正则损失(见图3-5),其中学习率为0.05。
从图3-5中可以看出,当学习率为0.05时,L2正则损失更优,其有更低的损失值。当学习率增加为0.4时,绘制其损失函数(见图3-6)。

image.png

从图3-6中可以发现,学习率大导致L2损失过大,而L1正则损失收敛。

image.png

3.5.4 延伸学习

为了更容易地理解上述的情况,这里清晰地展示大学习率和小学习率对L1正则和L2正则损失函数的影响。这里可视化的是L1正则和L2正则损失函数的一维情况,如图3-7所示。

image.png

3.6 用TensorFlow实现戴明回归算法

本节将实现戴明回归(Deming Regression),其意味着需要不同的方式来度量模型直线和数据集的数据点间的距离。
戴明回归有很多别名,例如全回归、正交回归(ODR)或者最短路径回归。

3.6.1 开始

如果最小二乘线性回归算法最小化到回归直线的竖直距离(即,平行于y轴方向),则戴明回归最小化到回归直线的总距离(即,垂直于回归直线)。其最小化x值和y值两个方向的误差,具体的对比图如图3-8所示。

image.png

为了实现戴明回归算法,我们修改一下损失函数。线性回归算法的损失函数最小化竖直距离;而这里需要最小化总距离。给定直线的斜率和截距,则求解一个点到直线的垂直距离有已知的几何公式。代入几何公式并使TensorFlow最小化距离。

3.6.2 动手做

1.除了损失函数外,其他的步骤跟前面的类似。导入必要的编程库,创建一个计算图会话,加载数据集,声明批量大小,创建占位符、变量和模型输出,代码如下:
image.png

2.损失函数是由分子和分母组成的几何公式。给定直线y = mx + b,点(x0, y0),则求两者间的距离的公式为:
image.png

3.现在初始化变量,声明优化器,遍历迭代训练集以得到参数,代码如下:
image.png

4.绘制输出结果(见图3-9)的代码如下:
image.png

3.6.3 工作原理

戴明回归算法与线性回归算法得到的结果基本一致。两者之间的关键不同点在于预测值与数据点间的损失函数度量:线性回归算法的损失函数是竖直距离损失;而戴明回归算法是垂直距离损失(到x轴和y轴的总距离损失)。

image.png

注意,这里戴明回归算法的实现类型是总体回归(总的最小二乘法误差)。总体回归算法是假设x值和y值的误差是相似的。我们也可以根据不同的理念使用不同的误差来扩展x轴和y轴的距离计算。

3.7 用TensorFlow实现lasso回归和岭回归算法

也有些正则方法可以限制回归算法输出结果中系数的影响,其中最常用的两种正则方法是lasso回归和岭回归。本节将详细介绍如何实现这两种方法。

3.7.1 开始

lasso回归和岭回归算法跟常规线性回归算法极其相似,有一点不同的是,在公式中增加正则项来限制斜率(或者净斜率)。这样做的主要原因是限制特征对因变量的影响,通过增加一个依赖斜率A的损失函数实现。
对于lasso回归算法,在损失函数上增加一项:斜率A的某个给定倍数。我们使用TensorFlow的逻辑操作,但没有这些操作相关的梯度,而是使用阶跃函数的连续估计,也称作连续阶跃函数,其会在截止点跳跃扩大。一会就可以看到如何使用lasso回归算法。
对于岭回归算法,增加一个L2范数,即斜率系数的L2正则。这个简单的修改将在3.7.4节介绍。

3.7.2 动手做

1.这次还是使用iris数据集,使用方式跟前面的类似。首先,导入必要的编程库,创建一个计算图会话,加载数据集,声明批量大小,创建占位符、变量和模型输出,代码如下:
image.png

2.增加损失函数,其为改良过的连续阶跃函数,lasso回归的截止点设为0.9。这意味着限制斜率系数不超过0.9,代码如下:
image.png

3.初始化变量和声明优化器,代码如下:
image.png

4.遍历迭代运行一段时间,因为需要过一会儿才会收敛。最后结果显示斜率系数小于0.9,代码如下:
image.png
image.png

3.7.3 工作原理

通过在标准线性回归估计的基础上,增加一个连续的阶跃函数,实现lasso回归算法。由于阶跃函数的坡度,我们需要注意步长,因为太大的步长会导致最终不收敛。对于岭回归算法,将在下一节介绍对其的必要修改。

3.7.4 延伸学习

对于岭回归算法,在上一节的代码基础上稍微改变损失函数即可,代码如下:
image.png

3.8 用TensorFlow实现弹性网络回归算法

弹性网络回归算法(Elastic Net Regression)是综合lasso回归和岭回归的一种回归算法,通过在损失函数中增加L1和L2正则项。

3.8.1 开始

在学完前面两节之后,可以轻松地实现弹性网络回归算法。本节使用多线性回归的方法实现弹性网络回归算法,以iris数据集为训练数据,用花瓣长度、花瓣宽度和花萼宽度三个特征预测花萼长度。

3.8.2 动手做

1.导入必要的编程库并初始化一个计算图,代码如下:
image.png

2.加载数据集。这次,x_vals数据将是三列值的数组,代码如下:
image.png
image.png

3.声明批量大小、占位符、变量和模型输出。这里唯一不同的是x_data占位符的大小为3,代码如下:
image.png

4.对于弹性网络回归算法,损失函数包含斜率的L1正则和L2正则。创建L1和L2正则项,然后加入到损失函数中,代码如下:
image.png

5.现在初始化变量,声明优化器,然后遍历迭代运行,训练拟合得到系数,代码如下:
image.png

6.下面是代码运行的输出结果:
image.png
image.png

7.现在能观察到,随着训练迭代后损失函数已收敛(见图3-10),代码如下:

image.png

3.8.3 工作原理

弹性网络回归算法的实现是多线性回归。我们能发现,增加L1和L2正则项后的损失函数中的收敛变慢。

3.9 用TensorFlow实现逻辑回归算法

本节将实现逻辑回归算法,预测低出生体重的概率。

3.9.1 开始

逻辑回归算法可以将线性回归转换成一个二值分类器。通过sigmoid函数将线性回归的输出缩放到0和1之间。目标值是0或者1代表着一个数据点是否属于某一类。如果预测值在截止值以上,则预测值被标记为“1”类;否则,预测值标为“0”类。在本例中,为方便简单起见,将指定截止值设为0.5。
在本例中使用的低出生体重的数据来自本书作者的GitHub数据仓库(https://github. com/nfmcclure/tensorflow_cookbook/raw/master/01_Introduction/07_Working_with_Data_Sources/birthweight_data/birthweight. dat )。我们将从多个因素来预测低出生体重。

3.9.2 动手做

1.导入必要的编程库,包括requests模块,因为我们将通过超链接访问低出生体重数据集。初始化一个计算图,代码如下:
image.png

2.通过requests模块加载数据集,指定要使用的特征。实际出生体重特征和ID两列不需要,代码如下:
image.png
image.png

3.分割数据集为测试集和训练集:
image.png

4.将所有特征缩放到0和1区间(min-max缩放),逻辑回归收敛的效果更好。下面将归一化特征,代码如下:
image.png

注意,在缩放数据集前,先分割数据集为测试集和训练集,这是相当重要的。我们要确保训练集和测试集互不影响。如果我们在分割数据集前先缩放,就无法保证它们不相互影响。
5.声明批量大小、占位符、变量和逻辑模型。这步不需要用sigmoid函数封装输出结果,因为sigmoid操作是包含在内建损失函数中的,代码如下:
image.png

6.声明损失函数,其包含sigmoid函数。初始化变量,声明优化器,代码如下:
image.png
image.png

7.除记录损失函数外,也需要记录分类器在训练集和测试集上的准确度。所以创建一个返回准确度的预测函数,代码如下:
image.png

8.开始遍历迭代训练,记录损失值和准确度,代码如下:
image.png

9.绘制损失和准确度,代码如下:
image.png

3.9.3 工作原理

这里是迭代过程中的损失,以及训练集和测试集的准确度。数据集只有189个观测值,但训练集和测试集的准确度图由于数据集的随机分割将会变化,如图3-11和图3-12所示。

image.png

image.png

相关文章
|
16天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
51 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
26天前
|
机器学习/深度学习 TensorFlow API
机器学习实战:TensorFlow在图像识别中的应用探索
【10月更文挑战第28天】随着深度学习技术的发展,图像识别取得了显著进步。TensorFlow作为Google开源的机器学习框架,凭借其强大的功能和灵活的API,在图像识别任务中广泛应用。本文通过实战案例,探讨TensorFlow在图像识别中的优势与挑战,展示如何使用TensorFlow构建和训练卷积神经网络(CNN),并评估模型的性能。尽管面临学习曲线和资源消耗等挑战,TensorFlow仍展现出广阔的应用前景。
55 5
|
2月前
|
机器学习/深度学习 人工智能 算法
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
玉米病害识别系统,本系统使用Python作为主要开发语言,通过收集了8种常见的玉米叶部病害图片数据集('矮花叶病', '健康', '灰斑病一般', '灰斑病严重', '锈病一般', '锈病严重', '叶斑病一般', '叶斑病严重'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。再使用Django搭建Web网页操作平台,实现用户上传一张玉米病害图片识别其名称。
63 0
【玉米病害识别】Python+卷积神经网络算法+人工智能+深度学习+计算机课设项目+TensorFlow+模型训练
|
3月前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
110 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
29天前
|
机器学习/深度学习 数据采集 算法
探索机器学习中的线性回归
【10月更文挑战第25天】本文将深入浅出地介绍线性回归模型,一个在机器学习领域中广泛使用的预测工具。我们将从理论出发,逐步引入代码示例,展示如何利用Python和scikit-learn库实现一个简单的线性回归模型。文章不仅适合初学者理解线性回归的基础概念,同时也为有一定基础的读者提供实践指导。
|
2月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
探索机器学习:从线性回归到深度学习
在这篇文章中,我们将一起踏上一场激动人心的旅程,穿越机器学习的广阔天地。我们将从最基本的线性回归开始,逐步深入到复杂的深度学习模型。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深入的理解。让我们一起探索这个充满无限可能的世界吧!
|
2月前
|
机器学习/深度学习 API
机器学习入门(七):线性回归原理,损失函数和正规方程
机器学习入门(七):线性回归原理,损失函数和正规方程
|
3月前
|
机器学习/深度学习 人工智能 自然语言处理
探索机器学习:从线性回归到深度学习
【9月更文挑战第4天】在这篇文章中,我们将深入探讨机器学习的世界,从基础的线性回归模型开始,逐步深入到复杂的深度学习网络。我们将通过实际的代码示例,揭示这些模型背后的数学原理,以及如何在现实世界的问题中应用它们。无论你是初学者还是有经验的数据科学家,这篇文章都将为你提供新的视角和深入的理解。
|
4月前
|
持续交付 测试技术 jenkins
JSF 邂逅持续集成,紧跟技术热点潮流,开启高效开发之旅,引发开发者强烈情感共鸣
【8月更文挑战第31天】在快速发展的软件开发领域,JavaServer Faces(JSF)这一强大的Java Web应用框架与持续集成(CI)结合,可显著提升开发效率及软件质量。持续集成通过频繁的代码集成及自动化构建测试,实现快速反馈、高质量代码、加强团队协作及简化部署流程。以Jenkins为例,配合Maven或Gradle,可轻松搭建JSF项目的CI环境,通过JUnit和Selenium编写自动化测试,确保每次构建的稳定性和正确性。
62 0
|
4月前
|
缓存 开发者 测试技术
跨平台应用开发必备秘籍:运用 Uno Platform 打造高性能与优雅设计兼备的多平台应用,全面解析从代码共享到最佳实践的每一个细节
【8月更文挑战第31天】Uno Platform 是一种强大的工具,允许开发者使用 C# 和 XAML 构建跨平台应用。本文探讨了 Uno Platform 中实现跨平台应用的最佳实践,包括代码共享、平台特定功能、性能优化及测试等方面。通过共享代码、采用 MVVM 模式、使用条件编译指令以及优化性能,开发者可以高效构建高质量应用。Uno Platform 支持多种测试方法,确保应用在各平台上的稳定性和可靠性。这使得 Uno Platform 成为个人项目和企业应用的理想选择。
71 0