【动手学深度学习】多层感知机模型选择、欠拟合和过拟合研究详情

目录

🌊1. 研究目的

🌊2. 研究准备

🌊3. 研究内容

🌍3.1 多层感知机模型选择、⽋拟合和过拟合

🌍3.2 基础练习

🌊4. 研究体会


🌊1. 研究目的

  • 多层感知机模型选择:比较不同多层感知机模型的性能,选择最适合解决给定问题的模型;

  • 欠拟合和过拟合:研究模型在训练数据上出现欠拟合或过拟合的情况,以便了解模型的泛化能力和优化方法的效果;

  • 模型正则化和调参:通过实验观察和比较,研究正则化技术和调参对模型的影响,以改善模型的泛化性能;

  • 模型复杂度与性能:探究多层感知机模型的复杂度对训练和测试性能的影响,以及如何找到合适的模型复杂度。


🌊2. 研究准备

  • 根据GPU安装pytorch版本实现GPU运行研究代码;

  • 配置环境用来运行 Python、Jupyter Notebook和相关库等相关库。


🌊3. 研究内容

启动jupyter notebook,使用新增的pytorch环境新建ipynb文件,为了检查环境配置是否合理,输入import torch以及torch.cuda.is_available() ,若返回TRUE则说明研究环境配置正确,若返回False但可以正确导入torch则说明pytorch配置成功,但研究运行是在CPU进行的,结果如下:


🌍3.1 多层感知机模型选择、拟合和过拟合

(1)使用jupyter notebook新增的pytorch环境新建ipynb文件,完成基本数据操作的研究代码与练习结果如下:

导入相关库:

import math
import numpy as np
import torch
from torch import nn
from d2l import torch as d2l

生成数据集

max_degree = 20  # 多项式的最大阶数
n_train, n_test = 100, 100  # 训练和测试数据集大小
true_w = np.zeros(max_degree)  # 分配大量的空间
true_w[0:4] = np.array([5, 1.2, -3.4, 5.6])

features = np.random.normal(size=(n_train + n_test, 1))
np.random.shuffle(features)
poly_features = np.power(features, np.arange(max_degree).reshape(1, -1))
for i in range(max_degree):
    poly_features[:, i] /= math.gamma(i + 1)  # gamma(n)=(n-1)!
# labels的维度:(n_train+n_test,)
labels = np.dot(poly_features, true_w)
labels += np.random.normal(scale=0.1, size=labels.shape)

# NumPy ndarray转换为tensor
true_w, features, poly_features, labels = [torch.tensor(x, dtype=
    torch.float32) for x in [true_w, features, poly_features, labels]]

features[:2], poly_features[:2, :], labels[:2]

对模型进行训练和测试

def evaluate_loss(net, data_iter, loss):  #@save
    """评估给定数据集上模型的损失"""
    metric = d2l.Accumulator(2)  # 损失的总和,样本数量
    for X, y in data_iter:
        out = net(X)
        y = y.reshape(out.shape)
        l = loss(out, y)
        metric.add(l.sum(), l.numel())
    return metric[0] / metric[1]


def train(train_features, test_features, train_labels, test_labels,
          num_epochs=400):
    loss = nn.MSELoss(reduction='mean')
    input_shape = train_features.shape[-1]
    # 不设置偏置,因为我们已经在多项式中实现了它
    net = nn.Sequential(nn.Linear(input_shape, 1, bias=False))
    batch_size = min(10, train_labels.shape[0])
    train_iter = d2l.load_array((train_features, train_labels.reshape(-1,1)),
                                batch_size)
    test_iter = d2l.load_array((test_features, test_labels.reshape(-1,1)),
                               batch_size, is_train=False)
    trainer = torch.optim.SGD(net.parameters(), lr=0.01)
    animator = d2l.Animator(xlabel='epoch', ylabel='loss', yscale='log',
                            xlim=[1, num_epochs], ylim=[1e-3, 1e2],
                            legend=['train', 'test'])
    for epoch in range(num_epochs):
        d2l.train_epoch_ch3(net, train_iter, loss, trainer)
        if epoch == 0 or (epoch + 1) % 20 == 0:
            animator.add(epoch + 1, (evaluate_loss(net, train_iter, loss),
                                     evaluate_loss(net, test_iter, loss)))
    print('weight:', net[0].weight.data.numpy())

三阶多项式函数拟合(正常)

# 从多项式特征中选择前4个维度,即1,x,x^2/2!,x^3/3!
train(poly_features[:n_train, :4], poly_features[n_train:, :4],
      labels[:n_train], labels[n_train:])

 线性函数拟合(欠拟合)

# 从多项式特征中选择前2个维度,即1和x
train(poly_features[:n_train, :2], poly_features[n_train:, :2],
      labels[:n_train], labels[n_train:])

高阶多项式函数拟合(过拟合)

# 从多项式特征中选取所有维度
train(poly_features[:n_train, :], poly_features[n_train:, :],
      labels[:n_train], labels[n_train:], num_epochs=1500)


🌍3.2 基础练习

1.这个多项式回归问题可以准确地解出吗?提示:使用线性代数。

可以求解。多项式回归问题可以转化为一个线性方程组的求解问题。

假设多项式回归模型是一个关于特征变量 x 的多项式函数,形式为 y = w0 + w1 * x + w2 * x^2 + ... + wn * x^n,其中 wi 是待求解的系数。

现在假设有 m 个样本点,每个样本点的特征变量 x 和对应的目标变量 y 都已知。你可以将这 m 个样本点组成一个矩阵 X 和一个向量 Y,其中 X 是一个 m×(n+1) 的矩阵,每一行包含特征变量 x 的不同幂次的值,Y 是一个 m 维的向量,包含每个样本点的目标变量 y。

通过线性代数的方法,可以使用最小二乘法求解以下方程组来找到系数向量 w:

X^T * X * w = X^T * Y

其中 X^T 表示 X 的转置矩阵。

解这个方程组可以得到系数向量 w 的准确解,从而得到多项式回归模型。

需要注意的是,这种方法只在样本点的数量 m 大于等于系数的数量 n+1 时才能准确求解。当 m 小于 n+1 时,这个线性方程组是一个超定方程组,可能没有准确解。在这种情况下,可以使用最小二乘法的近似解。

总结起来,对于多项式回归问题,当样本点的数量充足(m >= n+1)时,可以使用线性代数的方法准确求解系数向量 w。当样本点的数量不足时,可以使用最小二乘法来近似求解。

2.考虑多项式的模型选择。

2.1.绘制训练损失与模型复杂度(多项式的阶数)的关系图。观察到了什么?需要多少阶的多项式才能将训练损失减少到0?

在这个修改后的代码中,循环遍历不同的多项式阶数,对于每个阶数,调用train函数并将返回的训练损失添加到train_losses列表中。最后使用plt.plot函数绘制多项式阶数与训练损失之间的关系图表。

运行修改后的代码,将会生成训练损失与多项式阶数之间的图表。观察图表,可以看到随着多项式阶数的增加,训练损失逐渐减小。然而,当多项式阶数过高时,训练损失可能会变得很小,甚至降低到接近零的程度。但需要注意的是,过高的多项式阶数可能导致过拟合问题。

根据图表,可以看出多项式阶数为4时,训练损失已经减少到接近零的程度。因此,至少需要4阶的多项式才能将训练损失减少到零。

import matplotlib.pyplot as plt

def train(train_features, test_features, train_labels, test_labels,
          num_epochs=400):
    loss = nn.MSELoss(reduction='mean')
    input_shape = train_features.shape[-1]
    # 不设置偏置,因为我们已经在多项式中实现了它
    net = nn.Sequential(nn.Linear(input_shape, 1, bias=False))
    batch_size = min(10, train_labels.shape[0])
    train_iter = d2l.load_array((train_features, train_labels.reshape(-1,1)),
                                batch_size)
    test_iter = d2l.load_array((test_features, test_labels.reshape(-1,1)),
                               batch_size, is_train=False)
    trainer = torch.optim.SGD(net.parameters(), lr=0.01)
    animator = d2l.Animator(xlabel='epoch', ylabel='loss', yscale='log',
                            xlim=[1, num_epochs], ylim=[1e-3, 1e2],
                            legend=['train', 'test'])
    for epoch in range(num_epochs):
        d2l.train_epoch_ch3(net, train_iter, loss, trainer)
        if epoch == 0 or (epoch + 1) % 20 == 0:
            animator.add(epoch + 1, (evaluate_loss(net, train_iter, loss),
                                     evaluate_loss(net, test_iter, loss)))
    
    train_loss = evaluate_loss(net, train_iter, loss)
    return net, train_loss

degrees = np.arange(max_degree)
train_losses = []

for degree in degrees:
    _, train_loss = train(poly_features[:n_train, :(degree+1)],
                          poly_features[n_train:, :(degree+1)],
                          labels[:n_train], labels[n_train:])
    train_losses.append(train_loss)

plt.plot(degrees, train_losses)
plt.xlabel('Degree of Polynomial')
plt.ylabel('Train Loss')
plt.show()

2.2 在这种情况下绘制测试的损失图。

degree = 4
_, test_loss = train(poly_features[:n_train, :degree+1],
                     poly_features[n_train:, :degree+1],
                     labels[:n_train], labels[n_train:])

print(f"Test Loss (Degree {degree}): {test_loss}")

plt.plot([degree], [test_loss], 'ro')
plt.xlabel('Degree of Polynomial')
plt.ylabel('Test Loss')
plt.show()

2.3 生成同样的图,作为数据量的函数。

degrees = np.arange(1, max_degree+1)
test_losses = []

for degree in degrees:
    _, test_loss = train(poly_features[:degree*n_train, :4],
                         poly_features[n_train:, :4],
                         labels[:degree*n_train], labels[n_train:])
    test_losses.append(test_loss)

plt.plot(degrees * n_train, test_losses)
plt.xlabel('Number of Data Points')
plt.ylabel('Test Loss')
plt.show()

依次是1阶至20阶的图像数据:

3.如果不对多项式特征x^i进行标准化(1/i!),会发生什么事情?能用其他方法解决这个问题吗?

如果不对多项式特征 x^i 进行标准化(1/i!),会导致不同阶数的多项式特征具有不同的数值范围和尺度。这可能会使训练过程变得困难,因为不同特征的权重更新可能会受到不同程度的影响,使得模型难以收敛。

另一种解决这个问题的方法是使用特征缩放(feature scaling)。特征缩放是将不同特征的数值范围映射到相同范围的过程,常见的方法是将特征值减去均值并除以标准差(即进行标准化)。这样做可以确保所有特征具有相似的尺度,有助于加速模型的训练过程和收敛性。

在多项式特征的情况下,如果不进行标准化,可以尝试对原始特征进行标准化,而不是对多项式特征进行标准化。这意味着对输入特征 x 进行标准化,然后再进行多项式特征的构建。这样可以确保所有输入特征具有相似的尺度,并且多项式特征也会受到相同的标准化影响。

以下是修改后的代码示例:

import math
import numpy as np
import torch
from torch import nn
from d2l import torch as d2l
import matplotlib.pyplot as plt

max_degree = 20  # 多项式的最大阶数
n_train, n_test = 100, 100  # 训练和测试数据集大小
true_w = np.zeros(max_degree)  # 分配大量的空间
true_w[0:4] = np.array([5, 1.2, -3.4, 5.6])

features = np.random.normal(size=(n_train + n_test, 1))
np.random.shuffle(features)

# 特征缩放:对原始特征进行标准化
mean = np.mean(features)
std = np.std(features)
features = (features - mean) / std

poly_features = np.power(features, np.arange(max_degree).reshape(1, -1))
labels = np.dot(poly_features, true_w)
labels += np.random.normal(scale=0.1, size=labels.shape)

# NumPy ndarray转换为tensor
true_w, features, poly_features, labels = [torch.tensor(x, dtype=torch.float32) for x in [true_w, features, poly_features, labels]]

def evaluate_loss(net, data_iter, loss):
    """评估给定数据集上模型的损失"""
    metric = d2l.Accumulator(2)  # 损失的总和,样本数量
    for X, y in data_iter:
        out = net(X)
        y = y.reshape(out.shape)
        l = loss(out, y)
        metric.add(l.sum(), l.numel())
    return metric[0] / metric[1]

def train(train_features, test_features, train_labels, test_labels, num_epochs=400):
    loss = nn.MSELoss(reduction='mean')
    input_shape = train_features.shape[-1]
    # 不设置偏置,因为我们已经在多项式中实现了它
    net = nn.Sequential(nn.Linear(input_shape, 1, bias=False))
    batch_size = min(10, train_labels.shape[0])
    train_iter = d2l.load_array((train_features, train_labels.reshape(-1,1)), batch_size)
    test_iter = d2l.load_array((test_features, test_labels.reshape(-1,1)), batch_size, is_train=False)
    trainer = torch.optim.SGD(net.parameters(), lr=0.01)
    animator = d2l.Animator(xlabel='epoch', ylabel='loss', yscale='log', xlim=[1, num_epochs], ylim=[1e-3, 1e2], legend=['train', 'test'])
    for epoch in range(num_epochs):
        d2l.train_epoch_ch3(net, train_iter, loss, trainer)
        if epoch == 0 or (epoch + 1) % 20 == 0:
            animator.add(epoch + 1, (evaluate_loss(net, train_iter, loss), evaluate_loss(net, test_iter, loss)))
    print('weight:', net[0].weight.data.numpy())

# 从多项式特征中选择前4个维度,即1,x,x^2/2!,x^3/3!
train(poly_features[:n_train, :4], poly_features[n_train:, :4], labels[:n_train], labels[n_train:])

这段代码会生成训练损失与模型复杂度(多项式的阶数)的关系图。观察图可以帮助理解模型复杂度和训练损失之间的关系。

在代码中,通过标准化原始特征来处理多项式特征,即将特征进行了缩放,以便在训练过程中更好地优化模型。这样做有助于保持不同特征的相对重要性,并提高模型的训练效果。

如果不对多项式特征进行标准化,可能会导致模型训练过程中的数值不稳定性。特征缩放有助于避免梯度爆炸或梯度消失等问题,提高训练的稳定性和效果。

除了标准化之外,还可以考虑使用其他方法来处理多项式特征。例如采用正则化方法(如L1正则化、L2正则化)来控制模型的复杂度,以避免过拟合。另外,还可以尝试使用特征选择方法,选择对模型性能影响较大的特征,以减少特征的维度和模型的复杂度。

综上所述,标准化多项式特征是一种常用且有效的方法,可以提高模型的训练效果和稳定性。

4.泛化误差可能为零吗?

在实际情况下,泛化误差几乎不可能为零。泛化误差是指模型在未见过的数据上的误差,即在训练集之外的数据上的性能。即使模型在训练集上表现得非常好,泛化误差仍然存在,因为模型需要适应新的数据和不同的样本。

泛化误差的存在是由于数据的噪声、样本的多样性、模型的假设等因素。即使使用了良好的模型选择和训练方法,泛化误差也无法完全消除。

一个模型的目标是尽可能减小泛化误差,即在训练集和测试集上都能获得较低的误差。通过合适的模型选择、正则化技术、交叉验证等方法,可以帮助减小模型的泛化误差,并提高模型的性能。

因此,泛化误差几乎不可能为零,但可以通过优化模型和数据处理的方法来尽可能地减小泛化误差,以获得更好的模型性能。


🌊4. 研究体会

通过这次实验,我尝试使用不同的多层感知机模型架构,如不同的隐藏层数和隐藏单元数等超参数组合来构建多个模型。通过在训练集上训练这些模型,并在验证集上进行评估,比较它们在给定问题上的性能。

在实验中,可以选择使用流行的深度学习框架如TensorFlow或PyTorch来实现和训练多层感知机模型。需要定义模型的结构,包括输入层、多个隐藏层和输出层,并选择适当的激活函数和损失函数。

在模型训练过程中,使用适当的优化算法(如随机梯度下降)和合适的学习率来更新模型参数。通过记录训练集和验证集上的性能指标,比如准确率和损失函数值,评估不同模型的性能。根据实验结果,可以选择性能最好的模型,并进一步进行优化,以提高其性能。

研究模型在训练数据上出现欠拟合或过拟合现象,是为了了解模型的泛化能力和优化方法的效果。欠拟合指模型在训练数据上表现不佳,而过拟合指模型过度拟合了训练数据,导致在新数据上的性能下降。为了探究这些问题,可以通过调整模型的复杂度来观察欠拟合和过拟合的现象。通过增加隐藏层数或隐藏单元数,增加了模型的复杂度,可能更好地拟合训练数据,但也可能导致过拟合。相反,减少隐藏层数或隐藏单元数,模型的复杂度降低,可能导致欠拟合。

模型正则化是解决过拟合的常用方法之一。可以尝试引入正则化项,如L1正则化或L2正则化,来限制模型参数的大小,防止过拟合。此外,还可以使用Dropout技术,在训练过程中随机地将一些隐藏单元设置为零,以减少不同单元之间的依赖关系,从而增加模型的泛化能力。另外,调参也是改善模型泛化性能的重要步骤。在实验中,我们可以尝试调整学习率、批量大小、优化算法等超参数,以找到最佳的组合。使用网格搜索、随机搜索或贝叶斯优化等方法,可以自动搜索超参数空间,以寻找最佳的超参数配置。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2D 生存角色扮演游戏《Cryptara Conquest》即将登录 Eclipse

接下来是为狂热的游戏玩家们带来的又一个惊喜。《Cryptara Conquest》是一款以故事叙述和冒险元素作为驱动的 2D 生存 RPG 游戏,该游戏即将在 Eclipse 平台上发布。该游戏将经典老派游戏魅力与现代生存机制相结合,旨在通过怀旧、创新和区块链技术融合&am…

Linux网络编程:网络层协议|IP

前言: 网络层协议解决什么问题 当我们在上层实现了应用层协议将字符流数据转化为结构体数据,在传输层完成了通信的实现,数据的传输,但是数据最终还是得从本主机输出,从网络中进入到远端的另外一台主机。 网络层协议I…

瘦”AP与“胖”AP的区别

1. AP基本概念 无线AP,简单说就是一个无线接入点,它是无线网络的关键部分,就像是无线网络的大脑。这个无线AP啊,它跟无线路由器、无线网关、无线网桥这些设备差不多,都是干一件事儿的。它的作用就是把家里或公司里用线…

Redis 异常三连环

本文针对一种特殊情况下的Reids连环异常,分别是下面三种异常: NullPointerException: Cannot read the array length because “arg” is nullJedisDataException: ERR Protocol error: invalid bulk lengthJedisConnectionException: Unexpected end o…

续航1977公里的穿越之旅:比亚迪秦L DM-i试驾体验

5月31日,在西安这座古老而又充满活力的城市,一群自媒体驾驶着比亚迪秦L DM-i,踏上了从祖国西北到东南的穿越之旅。 在本次试驾活动中,自媒体们不仅要体验这款新能源车型的驾驶性能,而且还要亲自验证它在实际道路和极端…

基于聚类和回归分析方法探究蓝莓产量影响因素与预测模型研究

🌟欢迎来到 我的博客 —— 探索技术的无限可能! 🌟博客的简介(文章目录) 目录 背景数据说明数据来源思考 正文数据预处理数据读取数据预览数据处理 相关性分析聚类分析数据处理确定聚类数建立k均值聚类模型 多元线性回…

【专利 超音速】基于分类模型的轻量级工业图像关键点检测方法

申请号CN202311601629.7公开号(公开)CN117710683A申请日2023.11.27申请人(公开)超音速人工智能科技股份有限公司发明人(公开)张俊峰(总); 杨培文(总); 沈俊羽; 张小村 摘要 本发明涉及一种基于分类模型的…

【Makefile笔记】小白入门篇

【Makefile笔记】小白入门篇 文章目录 【Makefile笔记】小白入门篇所需组件一、简单了解Makefile1.Makefile简介2.Makefile 原理 二、为什么要使用Makefile1.解决编译时链库的不便2.提高编译效率,缩短编译时间(尤其是大工程) 三、Makefile语法…

vue 使用 Vxe UI vxe-print 实现复杂的 Web 打印,支持页眉、页尾、分页的自定义模板

Vxe UI vue 使用 Vxe UI vxe-print 实现复杂的 Web 打印,支持页眉、页尾、分页的自定义模板 官方文档 https://vxeui.com 查看 github、gitee 页眉-自定义标题 说明:vxe-print-page-break标签用于定义分页,一个标签一页内容,超…

Rust 性能分析

都说Rust性能好,但是也得代码写得好,猜猜下面两个代码哪个快 . - 力扣&#xff08;LeetCode&#xff09; use std::collections::HashMap; use lazy_static::lazy_static;lazy_static! {static ref DIGIT: HashMap<char, usize> {let mut m HashMap::new();for c in …

最新版点微同城源码34.7+全套插件+小程序前后端

带全套插件 自己耐心点配置一下插件 可以H5可以小程序 一款专属的同城服务平台对于企业和个人而言&#xff0c;无疑是拓展业务、提升服务品质的重要一环。点微同城源码搭配全套插件&#xff0c;以及完善的小程序前后端&#xff0c;将为您的业务发展提供强大支持 源码免费下载…

【PB案例学习笔记】-15怎样限制应用程序运行次数?

写在前面 这是PB案例学习笔记系列文章的第15篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上传到了gite…

python词云生成库-wordcloud

内容目录 一、模块介绍二、WordCloud常用的方法1. generate(self, text)2. generate_from_frequencies(frequencies)3. fit_words(frequencies)4. generate_from_text(text) 三、进阶技巧1. 设置蒙版2. 设置过滤词 WordCloud 是一个用于生成词云的 Python 库&#xff0c;它可以…

【算法速查】万字图解带你快速入门八大排序(下)

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;首先在这里祝大家中秋国庆双节同乐&#xff01;&#xff01;抓住假期的小尾巴&#xff0c;今天来把算法速查的八大排序的后续写完&#xff0c;当…

用 OpenCV 实现图像中水平线检测与校正

前言 在本文中&#xff0c;我们将探讨如何使用 Python 和 OpenCV 库来检测图像中的水平线&#xff0c;并对图像进行旋转校正以使这些线条水平。这种技术可广泛应用于文档扫描、建筑摄影校正以及机器视觉中的各种场景。 环境准备 首先&#xff0c;确保您的环境中安装了 OpenC…

gulimall-search P125 springboot整合elasticsearch版本冲突

一、问题 spring-boot.version 2.2.4.RELEASE,在gulimall-search pom.xml中添加elasticsearch.version 7.4.2后&#xff0c;发现出现如下问题&#xff1a;elasticsearch版本是springboot引入的6.8.6&#xff0c;没有变为7.4.2。 二、原因 在gulimall-search 的pom文件中&#…

01_初识微服务

文章目录 一、微服务概述1.1 什么是微服务1.2 对比微服务架构与单体架构1.3 微服务设计原则1.4 微服务开发框架1.5 简单理解分布式部署与集群部署 二、微服务的核心概念2.1 服务注册与发现2.2 微服调用&#xff08;通信&#xff09;2.3 服务网关2.4 服务容错2.5 链路追踪参考链…

初级网络工程师之入门到入狱(一)

本文是我在学习过程中记录学习的点点滴滴&#xff0c;目的是为了学完之后巩固一下顺便也和大家分享一下&#xff0c;日后忘记了也可以方便快速的复习。 网络工程师从入门到入狱 前言一、交换机二、路由器三、DHCP&#xff08;动态主机配置协议&#xff09;四、路由器配置 DHCP自…

前端面试宝典总结2-CSS(1)

前端面试宝典总结之CSS&#xff08;1&#xff09; 本文章 对各大学习技术论坛知识点&#xff0c;进行总结、归纳自用学习&#xff0c;共勉&#x1f64f; 上一篇&#x1f449;: 前端面试宝典总结1- html 文章目录 前端面试宝典总结之CSS&#xff08;1&#xff09;1.分析比较 o…

C++ | Leetcode C++题解之第129题求根节点到叶节点数字之和

题目&#xff1a; 题解&#xff1a; class Solution { public:int sumNumbers(TreeNode* root) {if (root nullptr) {return 0;}int sum 0;queue<TreeNode*> nodeQueue;queue<int> numQueue;nodeQueue.push(root);numQueue.push(root->val);while (!nodeQueu…