带你读《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

相关文章
|
25天前
|
机器学习/深度学习 PyTorch TensorFlow
【机器学习】基于tensorflow实现你的第一个DNN网络
【机器学习】基于tensorflow实现你的第一个DNN网络
44 0
|
2天前
|
机器学习/深度学习 人工智能 自然语言处理
探索机器学习:从线性回归到深度学习
【9月更文挑战第4天】在这篇文章中,我们将深入探讨机器学习的世界,从基础的线性回归模型开始,逐步深入到复杂的深度学习网络。我们将通过实际的代码示例,揭示这些模型背后的数学原理,以及如何在现实世界的问题中应用它们。无论你是初学者还是有经验的数据科学家,这篇文章都将为你提供新的视角和深入的理解。
|
17天前
|
机器学习/深度学习 数据采集 TensorFlow
使用TensorFlow进行模型训练:一次实战探索
【8月更文挑战第22天】本文通过实战案例详解使用TensorFlow进行模型训练的过程。首先确保已安装TensorFlow,接着预处理数据,包括加载、增强及归一化。然后利用`tf.keras`构建卷积神经网络模型,并配置训练参数。最后通过回调机制训练模型,并对模型性能进行评估。此流程为机器学习项目提供了一个实用指南。
|
7天前
|
API UED 开发者
如何在Uno Platform中轻松实现流畅动画效果——从基础到优化,全方位打造用户友好的动态交互体验!
【8月更文挑战第31天】在开发跨平台应用时,确保用户界面流畅且具吸引力至关重要。Uno Platform 作为多端统一的开发框架,不仅支持跨系统应用开发,还能通过优化实现流畅动画,增强用户体验。本文探讨了Uno Platform中实现流畅动画的多个方面,包括动画基础、性能优化、实践技巧及问题排查,帮助开发者掌握具体优化策略,提升应用质量与用户满意度。通过合理利用故事板、减少布局复杂性、使用硬件加速等技术,结合异步方法与预设缓存技巧,开发者能够创建美观且流畅的动画效果。
26 0
|
7天前
|
开发者 算法 虚拟化
惊爆!Uno Platform 调试与性能分析终极攻略,从工具运用到代码优化,带你攻克开发难题成就完美应用
【8月更文挑战第31天】在 Uno Platform 中,调试可通过 Visual Studio 设置断点和逐步执行代码实现,同时浏览器开发者工具有助于 Web 版本调试。性能分析则利用 Visual Studio 的性能分析器检查 CPU 和内存使用情况,还可通过记录时间戳进行简单分析。优化性能涉及代码逻辑优化、资源管理和用户界面简化,综合利用平台提供的工具和技术,确保应用高效稳定运行。
17 0
|
7天前
|
前端开发 开发者 设计模式
揭秘Uno Platform状态管理之道:INotifyPropertyChanged、依赖注入、MVVM大对决,帮你找到最佳策略!
【8月更文挑战第31天】本文对比分析了 Uno Platform 中的关键状态管理策略,包括内置的 INotifyPropertyChanged、依赖注入及 MVVM 框架。INotifyPropertyChanged 方案简单易用,适合小型项目;依赖注入则更灵活,支持状态共享与持久化,适用于复杂场景;MVVM 框架通过分离视图、视图模型和模型,使状态管理更清晰,适合大型项目。开发者可根据项目需求和技术栈选择合适的状态管理方案,以实现高效管理。
16 0
|
12天前
|
机器学习/深度学习 人工智能 自然语言处理
探索机器学习的奥秘:从线性回归到深度学习
【8月更文挑战第26天】本文将带领读者走进机器学习的世界,从基础的线性回归模型开始,逐步深入到复杂的深度学习网络。我们将探讨各种算法的原理、应用场景以及实现方法,并通过代码示例加深理解。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的知识和技能。让我们一起揭开机器学习的神秘面纱,探索这个充满无限可能的领域吧!
|
2月前
|
机器学习/深度学习 人工智能 TensorFlow
🔥零基础逆袭!Python数据分析+机器学习:TensorFlow带你秒变AI大师
【7月更文挑战第29天】在这个数据驱动的时代,掌握Python与机器学习技能是进入AI领域的关键。即使从零开始,也能通过TensorFlow成为AI专家。
47 8
|
14天前
|
机器学习/深度学习 人工智能 算法
探索机器学习:Python中的线性回归模型实现
【8月更文挑战第24天】在机器学习的世界中,线性回归是最基础也是应用最广泛的算法之一。本文将通过Python编程语言,使用scikit-learn库来实现一个简单的线性回归模型。我们将从理论出发,逐步深入到代码实现,最后通过一个实际数据集来验证模型的效果。无论你是机器学习的初学者,还是想要复习线性回归的基础知识,这篇文章都将为你提供有价值的信息。让我们一起踏上这段探索之旅吧!
|
21天前
|
机器学习/深度学习 算法 TensorFlow
【人工智能】TensorFlow和机器学习概述
TensorFlow的性能优化将是持续的工作重点。这包括更高效的GPU和TPU支持、更快速的模型训练与推理、以及优化的内存使用。同时,随着硬件的发展,TensorFlow将不断优化其代码库以充分利用新型硬件的能力。
12 0

热门文章

最新文章

下一篇
DDNS