实验8 梯度下降法

news2024/9/21 16:19:08

1. 实验目的

① 掌握深度学习框架中的自动求导机制;
② 掌握梯度下降法的基本原理,能够使用梯度下降法求解一元和多元线性回归问题。

2. 实验内容

① 使用TensorFlow的可训练变量和自动求导机制实现梯度下降法;
② 使用梯度下降法训练线性回归模型,测试模型性能;

3. 实验过程

题目一:

下载波士顿房价数据集,编写程序实现下述功能:
⑴使用波士顿房价数据集中的“低收入人口比例”属性,训练一元线性回归模型,并测试其性能,以可视化的形式展现训练测试的过程。
⑵使用波士顿房价数据集中的所有属性,训练多元线性回归模型,并测试其性能,以可视化的形式展现训练和测试的过程及结果。
⑶尝试调试学习率、迭代次数等超参数,使模型达到最优的性能,请记录超参数的调试过程及结果,并简要分析和总结;
⑷在第⑴和第⑵小题中,分别选择了单一属性和全部属性建立和训练模型,比较两者的学习率、迭代次数等超参数、在训练集和测试集上的均方差损失、以及模型训练时间,以表格或其他合适的图表形式展示。分析以上结果,可以得到什么结论,或对你有什么启发。

  1. 代码(一元线性回归模型)
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import time

plt.rcParams['font.sans-serif'] = "SimHei"  #设置中文黑体为默认字体

boston_housing = tf.keras.datasets.boston_housing
(train_x, train_y), (test_x, test_y) = boston_housing.load_data()  #导入训练集和测试集数据

x_train = train_x[:, 12]  #使用低收入人口比例
y_train = train_y
x_test = test_x[:, 12]
y_test = test_y

#设置超参数
learn_rate = 0.009
iter = 2000
display_step = 50
#设置模型参数初始值
np.random.seed(612)
w = tf.Variable(np.random.randn())
b = tf.Variable(np.random.randn())

mse_train = []  #记录训练集上的损失
mse_test = []  #记录测试集上的损失
start = time.perf_counter() # 返回系统当时时间
for i in range(0, iter + 1):
    with tf.GradientTape() as tape:  #梯度带对象的with语句,实现对w和b的自动监视
        pred_train = w * x_train + b
        loss_train = 0.5 * tf.reduce_mean(
            tf.square(y_train - pred_train))  #计算训练集上的误差

        pred_test = w * x_test + b
        loss_test = 0.5 * tf.reduce_mean(
            tf.square(y_test - pred_test))  #计算测试集上的误差

    mse_train.append(loss_train)
    mse_test.append(loss_test)

    dL_dw, dL_db = tape.gradient(loss_train, [w, b])  #使用训练集中的数据更新模型参数,梯度下降,自动求导
    w.assign_sub(learn_rate * dL_dw)
    b.assign_sub(learn_rate * dL_db)

    if i % display_step == 0:
        print('i: %-5i,Train Loss:%-10f,Test Loss: %-10f' %
              (i, loss_train, loss_test))  #输出训练误差和测试误差
end = time.perf_counter()
print("训练模型所耗时长:", end - start)

plt.figure(figsize=(15,10))

#第一个图
plt.subplot(221)
plt.scatter(x_train,y_train,color = "b",label = "data") #散点图
plt.plot(x_train,pred_train,color = "r",label = "model")
plt.title("波士顿房价与低收入人口的比例关系",fontsize = 14)
plt.legend(loc = "upper right")      #图例
#第二个图
plt.subplot(222)
plt.plot(mse_train,color = "r",linewidth = 3,label = "train loss")
plt.plot(mse_test,color = "b",linewidth = 1.5,label = "test loss")
plt.title("损失值随迭代次数变化的曲线",fontsize = 14)
plt.legend(loc = "upper right")      #图例
#第三个图
plt.subplot(223)
plt.plot(y_train,color = "b",marker = "o",label = "true_price")
plt.plot(pred_train,color = "r",marker = '.',label = "predict")
plt.title("训练集中的实际房价与预测的对比",fontsize = 14)
plt.legend(loc = "upper right")      #图例
#第四个图
plt.subplot(224)
plt.plot(y_test,color = "b",marker = "o",label = "true_price")
plt.plot(pred_test,color = "r",marker = '.',label = "predict")
plt.title("测试集中的实际房价与预测的对比",fontsize = 14)
plt.legend(loc = "upper right")      #图例

plt.show()

  1. 结果记录

在这里插入图片描述
在这里插入图片描述

  1. 实验总结
学习率训练轮数测试损失值所花时间
11e-2200017.6368015.7470852
21e-310000
31e-320000
  1. 代码(多元线性回归模型)
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

plt.rcParams["font.family"] = "SimHei"

#下载波士顿数据集
boston_housing = tf.keras.datasets.boston_housing
(train_x,train_y),(test_x,test_y) = boston_housing.load_data()
num_train = len(train_x)
num_test = len(test_x)


#运用广播运算进行归一化操作
x_train = (train_x - test_x.min(axis = 0)) / (train_x.max(axis = 0) - train_x.min(axis = 0))
y_train = train_y
x_test = (test_x - test_x.min(axis = 0)) / (test_x.max(axis = 0) - test_x.min(axis = 0))
y_test = test_y

x0_train = np.ones(num_train).reshape(-1,1)
x0_test = np.ones(num_test).reshape(-1,1)

X_train = tf.cast(tf.concat([x0_train,x_train],axis = 1),tf.float32)
X_test = tf.cast(tf.concat([x0_test,x_test],axis=1),tf.float32)

#将房价转换为列向量
Y_train = tf.constant(y_train.reshape(-1,1),tf.float32)
Y_test = tf.constant(y_test.reshape(-1,1),tf.float32)

#设置超参数
learn_rate = 0.01   #学习率
iter = 2000         #迭代次数
display_step = 200  #显示间隔

#设置模型变量初值
np.random.seed(612)
W = tf.Variable(np.random.randn(14,1),dtype=tf.float32)

mse_train = []
mse_test = []

for i in range(iter + 1):
    with tf.GradientTape() as tape:
        PRED_train = tf.matmul(X_train,W)
        Loss_train = 0.5 * tf.reduce_mean(tf.square(Y_train - PRED_train))
        PRED_test = tf.matmul(X_test,W)
        Loss_test = 0.5 * tf.reduce_mean(tf.square(Y_test - PRED_test))

    mse_train.append(Loss_train)
    mse_test.append(Loss_test)

    dL_dW = tape.gradient(Loss_train,W)
    W.assign_sub(learn_rate * dL_dW)
    if i % display_step == 0:
        print("i:%d,Train Loss:%f,Test Loss:%f"%(i,Loss_train,Loss_test))

#画图
plt.figure(figsize=(15,4))

plt.subplot(131)
plt.ylabel("MSE")
plt.plot(mse_train,color = "b",linewidth = 3,label = "train loss")
plt.plot(mse_test,color = "r",linewidth = 1.5,label = "test loss")
plt.title("损失值随迭代次数变化的曲线",fontsize = 14)
plt.legend(loc = "upper right")

plt.subplot(132)
plt.plot(Y_train,color = "b",marker = "o",label = "true_price")
plt.plot(PRED_train,color = "r",marker = ".",label = "predict")
plt.legend()
plt.ylabel("Price")
plt.title("训练集中实际房价与预测的对比",fontsize = 14)
plt.legend(loc = "upper right")

plt.subplot(133)
plt.plot(Y_test,color = "b",marker = "o",label = "true_price")
plt.plot(PRED_test,color = "r",marker = '.',label = "predict")
plt.ylabel("Price")
plt.title("测试集中的实际房价与预测的对比",fontsize = 14)
plt.legend(loc = "upper right")

plt.show()
  1. 实验结果
    在这里插入图片描述

在这里插入图片描述

  1. 实验总结
学习率训练轮数测试损失值
11e-3500026.834869
21e-2500020.631872
31e-2280019.298813

题目二:

观察6.4小节中给出的波士顿房价数据集中各个属性与房价关系的可视化结果(如图1所示),编写代码实现下述功能:

在这里插入图片描述

图1 波士顿房价数据集各个属性与房价关系

要求:
  ⑴观察图1,分析各个属性对房价的影响,从中选择你认为对房价影响最明显的属性并说明理由;
  ⑵使用第(1)问中选择的属性,编写代码建立并训练多元线性回归模型预测房价,并测试模型性能;
  ⑶尝试调试学习率、迭代次数等超参数,使模型达到最优性能,请记录超参数的调试过程以及训练和测试的结果,并简要分析和总结;
  ⑷分析和总结:
  比较分别使用单一属性、全部属性和你自己选择的属性组合训练模型时,学习率、迭代次数等参数,以及在训练集和测试集上的均方差损失和模型训练时间等结果,以表格或其他合适的图表形式展示。通过以上结果,可以得到什么结论,或对你有什么启发。

源代码

import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf

plt.rcParams['font.sans-serif'] = "SimHei"  #设置中文黑体为默认字体

# 加载数据集
boston_housing = tf.keras.datasets.boston_housing
(train_x, train_y), (test_x, test_y) = boston_housing.load_data()

train_X = train_x[:,[5,12]]
test_X = test_x[:,[5,12]]

num_train = len(train_X)
num_test = len(test_X)

#运用广播运算对数据进行归一化处理
x_train = (train_X - train_X.min(axis=0)) / (train_X.max(axis=0) -
                                             train_X.min(axis=0))
y_train = train_y
x_test = (test_X - test_X.min(axis=0)) / (test_X.max(axis=0) -
                                          test_X.min(axis=0))
y_test = test_y

x0_train = np.ones(num_train).reshape(-1, 1)
x0_test = np.ones(num_test).reshape(-1, 1)

X_train = tf.cast(tf.concat([x0_train, x_train], axis=1), tf.float32)  #数组堆叠
X_test = tf.cast(tf.concat([x0_test, x_test], axis=1), tf.float32)  #指定为32位浮点数

#把房价转化为列向量
Y_train = tf.constant(y_train.reshape(-1, 1), tf.float32)
Y_test = tf.constant(y_test.reshape(-1, 1), tf.float32)

#设置超参数
learn_rate = 0.01  #学习率
iter = 2000  #迭代次数
display_step = 200  #显示间隔

#设置模型变量初值
np.random.seed(612)
W = tf.Variable(np.random.randn(3, 1), dtype=tf.float32)

mse_train = []
mse_test = []

for i in range(0, iter + 1):
    with tf.GradientTape() as tape:

        PRED_train = tf.matmul(X_train, W)
        Loss_train = 0.5 * tf.reduce_mean(tf.square(Y_train - PRED_train))

        PRED_test = tf.matmul(X_test, W)
        Loss_test = 0.5 * tf.reduce_mean(tf.square(Y_test - PRED_test))

    mse_train.append(Loss_train)
    mse_test.append(Loss_test)

    dL_dW = tape.gradient(Loss_train, W)
    W.assign_sub(learn_rate * dL_dW)

    if i % display_step == 0:
        print('i: %-5i,Train Loss:%-10f,Test Loss: %-10f' %
              (i, Loss_train, Loss_test))

plt.figure(figsize=(20, 4))

plt.subplot(131)
plt.ylabel('MSE')
plt.plot(mse_train, color='blue', linewidth=3)
plt.plot(mse_test, color='red', linewidth=1.5)
plt.title("损失值随迭代次数变化的曲线", fontsize=14)

plt.subplot(132)
plt.plot(Y_train, color='blue', marker='o', label='true_price')
plt.plot(PRED_train, color='red', marker='.', label='predict')
plt.legend()
plt.ylabel('Price')
plt.title("训练集中的实际房价与预测的对比", fontsize=14)

plt.subplot(133)
plt.plot(Y_test, color='blue', marker='o', label='true_price')
plt.plot(PRED_test, color='red', marker='.', label='predict')
plt.legend()
plt.ylabel('Price')
plt.title("测试集中的实际房价与预测的对比", fontsize=14)

plt.show()

实验结果
在这里插入图片描述
在这里插入图片描述
实验总结
使用了第6和13个属性,低收入人口及平均房间数

学习率训练轮数测试损失值
11e-3500031.471260
21e-2500023.086786
31e-2280025.460329
因本人实力较弱,拓展题便不再列举,有兴趣的博主可以私信我,我可以将题目发给你。

4. 实验小结&讨论题

  1. 为什么要对数据归一化?除了课程中介绍的方法,查阅资料,看看还有哪些归一化方法?各有什么特点?分别适用于什么类型的数据。
    答:归一化后加快了梯度下降求最优解的速度、归一化有可能提高精度。
    ① Decimal place normalization,小数位归一化
    小数位归一化发生在具有数字类型的数据表中。如果你使用过 Excel,你就会知道这是如何发生的。默认情况下,Excel 会保留小数点后两位数字,也可以设定小数的位数,并在整个表格中进行统一。
    ② Data type normalization,数据类型归一化
    另一种常见是对数据类型的归一化。在 Excel 或 SQL 查询数据库中构建数据表时,可能会发现自己查看的数字数据有时被识别为货币,有时被识别为文本,有时被识别为数字,有时被识别为逗号分割的字符串。
    ③ Formatting normalization,格式的归一化
    这对于字符串(文本)是很常见的,并且在印刷和打印上出现的更多。虽然这些问题不会对分析产生影响,但是他可能会分散我们的注意力和现实的效果,例如斜体、粗体或下划线或者字体与其他的文字显示不一样。
    ④ Z-Score normalization
    Z-Score 将数据按比例缩放,使之落入一个特定区间
    ⑤ Linear normalization (“Max-Min”)
    它允许分析人员获取集合中最大 x 值和最小 x 值之间的差值,并建立一个基数。
    ⑥ Clipping normalization,剪裁归一化
    裁剪并不完全是一种归一化技术,他其实是在使用归一化技术之前或之后使用的一个操作。简而言之,裁剪包括为数据集建立最大值和最小值,并将异常值重新限定为这个新的最大值或最小值。需要注意的是,裁剪不会从数据集中删除点,它只是重新计算数据中的统计值。
    ⑦ Standard Deviation Normalization,标准差归一化

  2. 在使用梯度下降法对波士顿房价数据集进行模型训练时,怎样设置超参数能够使得模型快速收敛?怎样能够找到合适的超参数?想一想,并查阅资料,总结寻找合适的超参数都有哪些方法。
    答:对训练集和测试集归一化,可以采用以下3种方式:①先把测试集和训练集放在一起,进行属性归一化,然后再分开。②先划分训练集和测试集,然后分别归一化。③先划分训练集和测试集,归一化训练集,记录训练集的归一化参数(最大值,最小值),然后再使用训练集的参数去归一化测试集。

  3. 解析法和梯度下降法都能求解线性回归问题,它们的区别在哪?
    答:在线性回归算法求解中,常用的是解析法与梯度下降法,其中梯度下降法是解析法求解方法的优化,但这并不说明梯度下降法好于解析法,实际应用过程中,二者各有特点,需结合实际案例具体分析。相对于解析法来说,梯度下降法须要归一化处理以及选取学习速率,且需多次迭代更新来求得最终结果,而解析法则不需要。
    相对于梯度下降法来说,解析法须要求解(XTX)-1,其计算量为o(n3),当训练数据集过于庞大的话,其求解过程非常耗时,而梯度下降法耗时相对较小。
    所以,当模型相对简单,训练数据集相对较小,用解析法较好;对于更复杂的学习算法或者更庞大的训练数据集,用梯度下降法较好,一般当特征变量小于10的四次方时,使用解析法较稳妥,而大于10的四次方时,则应该使用梯度下降法来降低计算量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/453491.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023-04-23 算法面试中常见的动态规划问题

动态规划 1 什么是动态规划 以菲波那切数列求和为例,通过 1.普通的递归2.引入记忆数组memo3.自下而上地解决问题,即动态规划 动态规划的定义 dynamic programming (also known as dynamic optimization) is a method for solving a complex problem by…

Redis-cli Go代码

Redis-cli Go代码 安装 go get github.com/redis/go-redis/v9 建立连接 import ("context""fmt""github.com/redis/go-redis/v9" )client : redis.NewClient(&redis.Options{Addr: "localhost:6379",Password: "", …

支付宝 网站支付Demo 案例【沙箱环境】IDEA如何配置启动Eclipse项目

前言 在跑支付宝提供的支付案例Demo的时候,遇到了一些问题。支付宝提供的Demo是用Eclipse跑的JAVAEE项目。我想用IDEA来跑一下看看、结果使用习惯了Mavne管理jar包和SpringBoot项目。启动web项目的时候,还遇到一些问题。特此记录遇到的一些小问题。顺便回…

c++之常见函数

文章目录 一、inline函数二、函数重载三、函数模板 一、inline函数 1.当进行函数的调用时,系统要建立栈空间,保护现场,传递参数等等,这些工作都需要系统时间和空间得开销然而inline 函数是以空间换时间的做法,省去调用…

FL Studio 21最新发布的版本主要的新功能

FL Studio 21是最新发布的版本,其主要的新功能有: 1. 全新的UI设计:FL 21采用全新的 FLAT UI 设计风格,简洁而不简单,颜值大大提高。 2. 多窗口支持:可以将FL Studio窗口分别显示在不同的显示器上,实现屏幕间切换和多视图编辑。 3. 混音台增强:新增后置通道、多输入输入和多…

反垃圾邮件产品技术要求和测试评价方法

声明 本文是学习信息安全技术 反垃圾邮件产品技术要求和测试评价方法. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 反垃圾邮件产品等级划分 根据产品功能要求和安全保证要求的不同,以及反垃圾邮件产品适用应用环境的不同,将…

ROS1学习笔记:常用可视化工具的使用(ubuntu20.04)

参考B站古月居ROS入门21讲:常用可视化工具的实现 基于VMware Ubuntu 20.04 Noetic版本的环境 文章目录 一、日志输出工具:rqt_console二、绘制数据曲线:rqt_plot三、 图像渲染工具:rqt_image_view四、图形界面总接口:r…

FE之TSNE:基于MNIST手写数字数据集利用T-SNE/TSNE方法实现高维数据集可视化应(二维可视化和三维可视化)应用案例之详细攻略

FE之TSNE:基于MNIST手写数字数据集利用T-SNE/TSNE方法实现高维数据集可视化应(二维可视化和三维可视化)应用案例之详细攻略 目录 基于MNIST手写数字数据集利用T-SNE/TSNE方法实现高维数据集可视化应(二维可视化和三维可视化)应用案例 # 1、定义数据集 # 2、数据预…

docker部署springboot(jar)项目的方式概括

1、docker挂载目录 实现原理:docker中只需要安装一个JDK镜像,把该镜像的目录挂载到外部的Linux中,如挂载到/usr/data/jar,我们只需要把Jenkins构建的jar文件传输到该目录中,在通过docker命令启动jar即可: …

【代码随想录】刷题Day5

1.链表重复节点删除 82. 删除排序链表中的重复元素 II 前后指针实现 1.做这道题最大的感受就是:不要觉得开辟空间浪费,多用临时变量去记录。越精确越容易成功 2.首先没有节点或者一个节点直接返回 3.因为头部会出现一样元素的情况,以至于我不…

C语言之详解静态变量static

在C语言中static是用来修饰变量和函数的,这篇文章详细介绍了static主要作用,文章中有详细的代码实例,需要的朋友可以参考阅读 在C语言中: static是用来修饰变量和函数的 static主要作用为: 1. 修饰局部变量 - 静态局部变量 2. …

linux软件安装指令---yum和rpm

这里写目录标题 一 yum指令1. yum install 软件名2. yum remove 软件名3 检查已经安装成功的软件 二 rpm指令1 rpm -q2 rpm -qa|less3 rpm -qa| grep python4 搜索文件的详细信息5 查询一个rpm中的包安装到哪里去了6 查询一个文件属于那个包7 软件包的卸载 三 总结四 示范安装 …

【面试系列】四种经典限流算法讲解

固定窗口限流算法 介绍 固定窗口限流算法(Fixed Window Rate Limiting Algorithm)是一种最简单的限流算法,其原理是在固定时间窗口(单位时间)内限制请求的数量。该算法将时间分成固定的窗口,并在每个窗口内限制请求的数量。具体来…

锦江展焕新演绎,憬黎公寓住造理想

2023年4月19-21日,“万物春生,赴锦程”锦江酒店(中国区)投资加盟品鉴会,在上海世博展览馆完美收官。这是一场迎着酒店行业复苏浪潮的年度盛会。 插图丨锦江酒店(中国区) 作为锦江酒店&#xff…

60 openEuler 22.03-LTS 搭建MySQL数据库服务器-安装、运行和卸载

文章目录 60 openEuler 22.03-LTS 搭建MySQL数据库服务器-安装、运行和卸载60.1 安装60.2 运行60.3 卸载 60 openEuler 22.03-LTS 搭建MySQL数据库服务器-安装、运行和卸载 60.1 安装 配置本地yum源,详细信息请参考《openEuler 22.03-LTS 搭建repo服务器》。 清除…

JavaWeb01(WEB环境的搭建)

目录 一.JDK 1.1 JDK是什么? 1.2 如何下载和安装jdk? 1.3 如何配置环境变量? 1.4 如何测试java环境变量是否配置成功? 二.Tomcat 2.1 Tomcat是什么? 2.2 为什么需要使用它? 2.3 如何下载? 2.4 了解Tomcat目录结构 2.5 如何修改Tomcat端口号(0-65535) 2.6 如何使…

Nginx的优化及防盗链

Nginx程序优化 模块 ngx_http_access_module模块 访问模块 ngx_http_auth_basic_module模块 用户访问控制 ngx_http_stub_status_module模块 查看http状态统计模块 ngx_http_gzip_module模块 压缩模块 ngx_http_ssl_module模块 设置http的连接模块 ngx_http_rewrite_mod…

Python selenium 模块使用find_element_by_id无效

一、发生异常: 二、原因 查询安装selenium的版本是4.5.0 这个版本不支持页面对象的定位find_element_by_id方法,以前版本支持这些进行元素定位: find_element_by_id find_element_by_name find_element_by_xpath find_element_by_link_text find_elem…

找工作半年,四月成功拿到华为offer,分享一波面经...

前言 不论是校招还是社招都避免不了各种⾯试、笔试,如何去准备这些东⻄就显得格外重要。不论是笔试还是⾯试都是有章可循的,我这个“有章可循”说的意思只是说应对技术⾯试是可以提前准备,所谓不打无准备的仗就是这个道理。 以下为大家&…

【李宏毅】Bert家族

课程资料来自李宏毅老师油土鳖频道的BERT家族教程:上,下。 这两章主要是如何在pre-train的模型上做fine-turn,如何利用大模型来做自己的task。 目录 前言 什么是预训练 What is pre-train model 如何微调 How to fine-tune 入参 出参 …