深度学习阶段性回顾

        本文针对过去两周的深度学习理论做阶段性回顾,学习资料来自吴恩达老师的2021版deeplearning.ai课程,内容涵盖深度神经网络改善一直到ML策略的章节。视频链接如下:吴恩达深度学习视频链接

     (注:本文出自深度学习初学者,此文内容将以初学者的感悟与见解讲述。当然我也会努力搜寻资料以弥补自身认知的不足,希望本文能对深度学习的其他初学者也有所帮助,文章若有不当之处,望大家在评论区多多指正,我将虚心接纳,多谢!)

Charpter1: 改善神经网络

1.训练集,开发集,测试集

        深度学习的关键组成部分是神经网络,而神经网络具有深层次的网络结构,是一种依靠大量数据样本,通过正向传播、逆向传播算法对数据进行训练与学习,进而提取复杂数据特征与模式,从而完成指定任务的计算模型。正如小孩子通过体察世界、阅读书籍等方式认知世界,机器的学习也需要借助学习原料,这些原料就是大量的样本数据(注:已有了解的同学可跳过段)

        模型构建的过程常包括模型的训练,模型参数的调整以及模型的精确度检验,对应的所需数据集合成为训练集,开发集与测试集。

        1.1三个数据集的基本概念

        训练集指构建深度学习模型的数据集,机器需要依靠大量数据来识别与认知这个世界,而训练集就是机器的学习材料,使机器学习与认识输入数据与对应数据的标签输出之间的关系,让模型不断通过优化迭代算法,调节模型的参数与权重,最大限度地减少模型在训练集上地训练误差。

        开发集用于调节与选择模型的超参数与结构,机器在开发集上进行模型选择、调整和验证,评估模型的性能、进行参数调优,并避免对训练集的过拟合,对于模型构建起到关键的评估与选择的作用,从而提高模型在测试集上的泛化能力。

        测试集用于最终评估模型的性能与泛化能力,衡量模型在真实环境下的效果与实际的预测能力。

        三个数据集往往相互独立,如果机器也能参加高考,那么三个数据集的作用比喻为:训练集是机器学习的学习原材料,用于学习知识点与掌握考点;然而单凭学习还不足以证明你有所掌握,此时开发集就是检验你学习效果的模拟考试,机器在模拟考试之后也会查漏补缺(对应为模式选择与参数调优等操作),从而扩充与巩固知识点;测试集便是机器的高考,用于检验“高中三年”学习训练的最终效果。若成绩优良,那自然是皆大欢喜,否则只能含泪复读了(重新训练或则调节参数)。

1.2 偏差与方差

        偏差与方差是机器学习中的两个重要概念,用于衡量机器在训练样本与新样本上的预测效果,与欠拟合与过拟合之间存在着密切的关系。

        偏差是指模型对于训练样本的预测值与真实值之间的差距,比如猫识别器识别一张猫图为非猫图,则称预测结果与真实值不符,存在偏差。高偏差通常意味着模型未能提取数据中的特征与模式无法对数据的真实分布进行准确建模,导致欠拟合问题。

        方差是指模型预测结果的变化程度,它反映了模型对训练数据的敏感性和抗干扰能力,方差较高的模型对训练集的小波动过度敏感,可能过度拟合训练数据中的噪声。低偏差与高方差的模型可能表现出良好1的拟合能力,当新数据上的泛化能力较差,导致过拟合。

2.欠拟合与过拟合

        2.1判别拟合的方法

        判别模型的拟合类别比较简单,欠拟合的判断方法是看模型在训练集上的预测值与真实值上的差距,如果差距较大,出现了高偏差,那么说明模型出现了欠拟合问题,模型还没能提取出数据的复杂特征模式。

        判断过度拟合的方式是,在模型出现低偏差的条件下,看模型是否在新的数据集上出现高方差,即模型虽然能够很好地拟合训练集上的数据,但对于新数据缺乏拟合能力,谓之模型出现了过拟合问题。可见,新数据可来源于开发集与测试集。

        2.2 欠拟合与过拟合的图解

欠(过)拟合

        (注:图片来源于博客http://t.csdn.cn/lNUAn) 

        上图展示构建曲线拟合数据样本点的特征,曲线一出现欠拟合问题,模型无法拟合训练样本的数据特征,预测值与真实值存在高偏差(高误差),即模型出现欠拟合;曲线二则是恰当的拟合曲线,即模型能够提取数据的模式并拟合出数据样本的总体特征;曲线三出现了过拟合问题,模型学习训练集时学得过于精细了(曲线经过了训练数据的所有点),过度适应了训练数据集合,导致模型在新的数据上缺乏预测能力。

        2.3解决方法

        解决欠拟合的方法有:增加模型复杂度、引入更多特征、增加训练数据量等;

        解决过拟合的方法有:降低模型复杂度、增加正则化技术、增加训练数据等,以下将着重讲解正则化技术。

3.正则化技术

        正则化技术的用途在于解决模型的过拟合问题,而模型的过拟合问题常常来源于训练数据不足、模型网络过于复杂(学习能力太强了)、模型参数过多且权重过大、数据特征选择不当、数据标注错误、训练时间过长等原因,以下将讲解正则化技术是如何解决过拟合问题。

        (注:本人对于正则化技术的理解来源于这位大佬的博客http://t.csdn.cn/TfZF0,所谓站在巨人的肩膀上才能学得更快,感兴趣的同学可以通过该博客了解正则化技术,本博客毕竟也只是初学者的见解!)

   3.1 L1正则化

        3.1.1 公式解释

       L1正则化通过在损失函数中添加模型参数绝对值之和的惩罚项,将大部分参数压缩为0,从而实现特征选择和稀疏性。它倾向于生成稀疏权重向量,可以用于特征选择,即通过减小不相关的特征的权重使其趋近于0.

        L1正则化的损失函数:Loss_{regulation} = Loss_{origin} + \frac{\lambda}{n}\sum_{i=1}^{n}|w_{i}|

        L1正则化的参数偏导:dw_{regulation} = dw_{origin}+\frac{\lambda}{n}

        新的损失函数在原损失函数的基础上添加了参数绝对值之和的惩罚项,其中\lambda是惩罚系数,\lambda越大,惩罚就越狠。由于模型在梯度下降算法下,以损失函数最小化为目标,而新添的参数绝对值之和会增大损失函数,这意味着模型在训练的过程中,倾向于把参数变小。而参数代表模型对于数据某个特征赋予的权重,当损失函数渴望变小的同时保留对于训练数据的拟合能力,那么它就只能保留那些最重要且最能概括训练数据特征的参数权重,其余代表复杂特征的参数权重统统置为0(或很小值),从而提高了模型的泛化能力,解决了过拟合问题。

        3.1.2举个栗子

        举个例子(当然大佬那篇博客的例子也很不错,本人的例子不愿看可直接跳过),假设我们需要训练一个猫识别器,且为了简化问题只考虑猫的毛色与形态两个特征。我们知道凡是猫都具有普遍的形态:体型小,全身毛被密而柔软,锁骨小,吻部短,眼睛圆,颈部粗壮,四肢较短,足下有数个球形肉垫,舌面被有角质层的丝状钩形乳突等等;但猫的毛色却不尽相同,有白,黄,棕等等,屈指难数,如下为一些不同毛色猫猫的图片:

       

         当我们的训练样本较少(假设只有上面四张图片)且网络结构较复杂(识别复杂特征的能力较强)时,模型同时记住猫的形态与这些猫的各种肤色,此时便出现了过拟合。它会认为只有当新测试样本(假设也是一猫但它的肤色不属于上述任意一种)满足猫的形态且猫的肤色满足上述四种颜色时,这个测试样本才会被判断为猫。由于新样本的肤色特征不符合模型要求,所以它被错判为非猫了。

        为了解决这种过拟合问题,我加入惩罚项,迫使模型忘记数据的复杂特征,而只记住普遍特征,于是机器就思考:由于猫的肤色各不相同,若学习这些肤色特征需要消耗大量成本(给每个复杂特征对应的参数赋予高权重,导致损失函数数值过大),但如果只单独学习猫的形态其实便能判断一个动物是否猫,因此它单独学习猫的形态这一猫的普遍特征,因而当新的猫图输入时便能很自然被机器判断为猫啦!

        3.1.3 L1正则化求解稀疏解

        关于L1正则化是如何产生稀疏解的疑问,我觉得大佬的那篇博客已经解释得够清楚,而本人由于数学能力有限在此也难做解释,但也可以给出一些我的思考:由于模型训练的本质就是调节参数,而损失函数是关于参数的函数,训练目的在于找到损失函数的最优解。当我们限定参数的绝对值之和为一个定值时,由于训练参数较多,高维参数的绝对值之和为定值在高维空间中的图像是某个高维的几何体,几何体的端点比较突出,往往容易触碰到损失函数的最优解领域,从而对于参数向量v = \{w_{1},w_2.\cdots,w_n\}只有少部分分量大于0,而大部分分量等于0,因而得到稀疏解。(注:本人也自觉解释得不到位,恰当的解释还是建议看大佬的博客,或者也可以参考这篇博客:http://t.csdn.cn/9bjhl

3.2 L2正则化

        L2正则化通过在损失函数中添加模型参数平方和的惩罚项,限制模型参数的值域大小。L2正则化会使模型的参数接近于0,但不等于0,因此不会得到稀疏权重向量。它对异常值的敏感度较低,可以有效地防止过拟合

        3.2.1 公式解释

        L2正则化损失函数:Loss_{regulation} = Loss_{origin}+\frac{\lambda}{2n}\sum_{i=1}^{n}w_{i}^2

        L2正则化参数偏导:dw_{regulation} = dw_{origin}+\frac{\lambda}{n}w

        关于L2正则化如何通过惩罚项解决正则化问题,其道理与L1正则化解决过拟合问题的道理是互通的,在此不多加解释。

        3.2.2 L1L2正则化的区别

  1. 计算方式的不同:两者在损失函数与参数偏导上的所添加的公式不同;
  2. 参数限制程度:L1正则化鼓励模型的参数稀疏性,即通过将一部分参数的权重推向零来减少特征的依赖性;L2正则化更倾向于将参数权重均匀地减小,但不会强制将其推向零。L2正则化会使得模型的参数权重趋向于较小的值,但不会稀疏参数;
  3. 形状:L1正则化项形状是由参数的绝对值之和构成的一个等边矩形(L1范数的等值线为菱形),其对应的正则化项的图像为“角”状;L2正则化的正则化项形状是由参数的平方和的平方根构成的一个球体(L2范数的等值线为圆),其对应的正则化项的图像为“球”状;

3.3 Dropout正则化 

        Dropout是一种特殊的正则化技术,其基本思想是在训练过程中以一定的概率丢弃(置零)随机选择的隐藏层单元。这样可以防止某些特征值过度依赖于特定的隐藏单元,并促使模型学习到多个独立的特征表示。通过随机丢弃隐藏层单元,正则化抑制可以减少模型对特定训练样例的过度依赖,从而提高泛化能力和鲁棒性.

        3.3.1 python代码实现

        Dropout的正向传播代码:

# GRADED FUNCTION: forward_propagation_with_dropoutdef forward_propagation_with_dropout(X, parameters, keep_prob = 0.5):"""Implements the forward propagation: LINEAR -> RELU + DROPOUT -> LINEAR -> RELU + DROPOUT -> LINEAR -> SIGMOID.Arguments:X -- input dataset, of shape (2, number of examples)parameters -- python dictionary containing your parameters "W1", "b1", "W2", "b2", "W3", "b3":W1 -- weight matrix of shape (20, 2)b1 -- bias vector of shape (20, 1)W2 -- weight matrix of shape (3, 20)b2 -- bias vector of shape (3, 1)W3 -- weight matrix of shape (1, 3)b3 -- bias vector of shape (1, 1)keep_prob - probability of keeping a neuron active during drop-out, scalarReturns:A3 -- last activation value, output of the forward propagation, of shape (1,1)cache -- tuple, information stored for computing the backward propagation"""np.random.seed(1)# retrieve parametersW1 = parameters["W1"]b1 = parameters["b1"]W2 = parameters["W2"]b2 = parameters["b2"]W3 = parameters["W3"]b3 = parameters["b3"]#原文有缩进问题,请注意!# LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SIGMOIDZ1 = np.dot(W1, X) + b1A1 = relu(Z1)### START CODE HERE ### (approx. 4 lines)         # Steps 1-4 below correspond to the Steps 1-4 described above. # Step 1: initialize matrix D1 = np.random.rand(..., ...)#rand是随机生成0~1之间的数D1 = np.random.rand(A1.shape[0],A1.shape[1])# Step 2: convert entries of D1 to 0 or 1 (using keep_prob as the threshold)D1 = D1<keep_prob# Step 3: shut down some neurons of A1A1 = A1*D1# Step 4: scale the value of neurons that haven't been shut downA1/=keep_prob### END CODE HERE ###Z2 = np.dot(W2, A1) + b2A2 = relu(Z2)### START CODE HERE ### (approx. 4 lines)# Step 1: initialize matrix D2 = np.random.rand(..., ...)D2 = np.random.rand(A2.shape[0],A2.shape[1])# Step 2: convert entries of D2 to 0 or 1 (using keep_prob as the threshold)D2 = D2<keep_prob# Step 3: shut down some neurons of A2A2 = A2*D2# Step 4: scale the value of neurons that haven't been shut downA2/=keep_prob### END CODE HERE ####输出层只有一层,无需dropout,再dropout就没意思了 ^_^Z3 = np.dot(W3, A2) + b3A3 = sigmoid(Z3)cache = (Z1, D1, A1, W1, b1, Z2, D2, A2, W2, b2, Z3, A3, W3, b3)return A3, cache

        Dropout的逆向传播代码实现:

# GRADED FUNCTION: backward_propagation_with_dropoutdef backward_propagation_with_dropout(X, Y, cache, keep_prob):"""Implements the backward propagation of our baseline model to which we added dropout.Arguments:X -- input dataset, of shape (2, number of examples)Y -- "true" labels vector, of shape (output size, number of examples)cache -- cache output from forward_propagation_with_dropout()keep_prob - probability of keeping a neuron active during drop-out, scalarReturns:gradients -- A dictionary with the gradients with respect to each parameter, activation and pre-activation variables"""m = X.shape[1](Z1, D1, A1, W1, b1, Z2, D2, A2, W2, b2, Z3, A3, W3, b3) = cachedZ3 = A3 - YdW3 = 1./m * np.dot(dZ3, A2.T)db3 = 1./m * np.sum(dZ3, axis=1, keepdims = True)dA2 = np.dot(W3.T, dZ3)### START CODE HERE ### (≈ 2 lines of code)# Step 1: Apply mask D2 to shut down the same neurons as during the forward propagationdA2 = dA2*D2# Step 2: Scale the value of neurons that haven't been shut downdA2/=keep_prob### END CODE HERE ####确保A2大于0dZ2 = np.multiply(dA2, np.int64(A2 > 0))dW2 = 1./m * np.dot(dZ2, A1.T)db2 = 1./m * np.sum(dZ2, axis=1, keepdims = True)dA1 = np.dot(W2.T, dZ2)### START CODE HERE ### (≈ 2 lines of code)# Step 1: Apply mask D1 to shut down the same neurons as during the forward propagationdA1 = dA1*D1# Step 2: Scale the value of neurons that haven't been shut downdA1/=keep_prob### END CODE HERE ###dZ1 = np.multiply(dA1, np.int64(A1 > 0))dW1 = 1./m * np.dot(dZ1, X.T)db1 = 1./m * np.sum(dZ1, axis=1, keepdims = True)gradients = {"dZ3": dZ3, "dW3": dW3, "db3": db3,"dA2": dA2,"dZ2": dZ2, "dW2": dW2, "db2": db2, "dA1": dA1, "dZ1": dZ1, "dW1": dW1, "db1": db1}return gradients

        代码来源于吴恩达的课后编程作业,上述代码实现对3层神经网络实施dropout操作。注意dropout在每一次迭代时会抛弃一部分神经元,被遗弃的神经元无需进行正向传播与逆向传播。

  3.4 过拟合的原因解释

        有了对于L1正则化如何解决过拟合问题的认识,便能很好地解释出现过拟合原因的所以然,过拟合原因的解释如下:

  1. 训练数据不足:训练数据不足的反面是训练数据充足,众所周知,模型的训练数据量越大,模型的预测能力越强,泛化能力也越强,为什么呢?第一,训练数据的增多意味着数据多样性的增多,模型自然能见多识广,捕捉罕见样本,涵盖更广泛的场景;第二,当模型的复杂程度一定时,它学习特征与模式的能力也有限,当数据量很大时,模型自然无法对每个数据进行精细化的学习,为了降低损失函数数值,它只能在大量的数据中学习样本的普遍特征,就好比如当样本中有上亿种猫的肤色时,模型学习这种特定特征的能力就有限了,因为它觉得去学习普遍特征更加值得,从而模型的泛化能力较强。反之亦然,当训练的数据量较少时,模型便容易出现过拟合现象,道理都是互通的。(注:此处内容来源于在阅读其他资料后思考得出的见解)
  2. 模型网络过于复杂:同理,当思考复杂的模型网络会引发过拟合前,,也需要控制其他变量,当数据量一定时,模型网络结构过于复杂,它的特征识别能力也就过强了。(例如,小样本训练复杂模型)当机器“学有余力”时,它便会去提取数据特定的特征(例如,去学习猫的肤色),过度适应训练样本,导致在新数据上缺乏泛化能力。
  3. 模型参数过多且权重过大:道理都是互通的,当模型参数过多且权重过大时往往意味着模型网络结构过于复杂,自然会导致过拟合。
  4. 数据特征选择不当:道理都是互通的,训练时模型选择了不当的特征,比如选择了事物的非普遍性特征,便会在预测新数据时出现过拟合问题。

  

      

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

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

相关文章

Vue中如何更好地封装组件?

子组件接受父组件传递的事件 1.子组件使用事件名"$emit(父组件中传递的事件名,想给父组件传递的参数(可选))" click"$emit(click)" 2.子组件使用 v-on"$listeners" 父组件&#xff1a; <template><div id"app"><myCo…

MyBatis的XML映射文件

Mybatis的开发有两种方式&#xff1a; 注解 XML配置文件 通过XML配置文件的形式来配置SQL语句&#xff0c;这份儿XML配置文件在MyBatis当中也称为XML映射文件。 导学&#xff1a;在MyBatis当中如何来定义一份儿XML映射文件&#xff1f; 在MyBatis当中&#xff0c;定义XML…

使用 HTML、CSS 和 JavaScript 创建多步骤表单

使用 HTML、CSS 和 JavaScript 创建多步骤表单 为了处理又长又复杂的表单&#xff0c;我们需要将它们分成多个步骤。通过一次只在屏幕上显示一些输入&#xff0c;表单会感觉更容易理解&#xff0c;并防止用户感到被大量的表单字段淹没。 在本文中&#xff0c;我将逐步指导如何…

基础堆排序(Java 实例代码)

目录 基础堆排序 一、概念及其介绍 二、适用说明 三、过程图示 四、Java 实例代码 src/runoob/heap/Heapify.java 文件代码&#xff1a; 基础堆排序 一、概念及其介绍 堆排序&#xff08;Heapsort&#xff09;是指利用堆这种数据结构所设计的一种排序算法。 堆是一个近…

Linux_5_Shell脚本编程

目录 1 基础1.1 程序组成1.2 程序编程风格1.3 编程语言1.4 编程逻辑处理方式 2 shell 脚本语言的基本结构2.1 shell脚本的用途2.2 shell脚本基本结构2.3 创建shell脚本过程2.4 脚本注释规范2.5 第一个脚本2.6 脚本调试2.7 变量2.7.1 变量2.7.2 变量类型2.7.3 编程语言分类2.7.4…

【MAC】 M2 brew安装 docker 运行失败 解决

MAC 安装 brew install --cask docker 之后一直显示docker: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?. 网上看了一些文章 发现 这个不适用于M2 所以要从官网上下载 docker 安装成功

C++ 动态规划经典案例解析之最长公共子序列(LCS)_窥探递归和动态规划的一致性

1. 前言 动态规划处理字符相关案例中&#xff0c;求最长公共子序列以及求最短编辑距离&#xff0c;算是经典中的经典案例。 讲解此类问题的算法在网上一抓应用一大把&#xff0c;即便如此&#xff0c;还是忍不住有写此文的想法。毕竟理解、看懂都不算是真正掌握&#xff0c;唯…

多线程与并发编程面试题总结

多线程与并发编程 多线程 线程和进程的区别&#xff1f; 从操作系统层面上来讲&#xff1a;进程(process)在计算机里有单独的地址空间&#xff0c;而线程只有单独的堆栈和局部内存空间&#xff0c;线程之间是共享地址空间的&#xff0c;正是由于这个特性&#xff0c;对于同…

vscode debug python 带参数

两种方法 第一种&#xff1a; 1&#xff0c;侧边栏选择运行和调试 2&#xff0c;请先创建一个launch.json文件 3&#xff0c;并选择配置文件为python文件 此时你的工作目录下会多一个目录.vscode和该目录下一个launch.json文件&#xff0c;该文件则配置了你的debug配置。在…

【报错】ModuleNotFoundError: No module named ‘websocket‘

1 报错 ModuleNotFoundError: No module named websocket 2 解决方法 pip install websocket 1 报错 AttributeError: module websocket has no attribute enableTrace 2 分析 一般是由于websocket的依赖包没有安装造成的。websocket.enableTrace()方法是在websocket-cli…

C语言第十课----------------扫雷----------数组的经典练手题

作者前言 &#x1f382; ✨✨✨✨✨✨&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f367;&#x1f382; &#x1f382; 作者介绍&#xff1a; &#x1f382;&#x1f382; &#x1f382;…

React构建的JS优化思路

背景 之前个人博客搭建时&#xff0c;发现页面加载要5s才能完成并显示 问题 React生成的JS有1.4M&#xff0c;对于个人博客服务器的带宽来说&#xff0c;压力较大&#xff0c;因此耗费了5S的时间 优化思路 解决React生成的JS大小&#xff0c;因为我用的是react-router-dom…

prometheus告警发送组件部署

一、前言 要实现Prometheus的告警发送需要通过alertmanager组件&#xff0c;当prometheus触发告警策略时&#xff0c;会将告警信息发送给alertmanager&#xff0c;然后alertmanager根据配置的策略发送到邮件或者钉钉中&#xff0c;发送到钉钉需要安装额外的prometheus-webhook…

模拟实现消息队列(以 RabbitMQ 为蓝本)

目录 1. 需求分析1.1 介绍一些核心概念核心概念1核心概念2 1.2 消息队列服务器&#xff08;Broker Server&#xff09;要提供的核心 API1.3 交换机类型1.3.1 类型介绍1.3.2 转发规则&#xff1a; 1.4 持久化1.5 关于网络通信1.5.1 客户端与服务器提供的对应方法1.5.2 客户端额外…

【LangChain概念】了解语言链️:第2部分

一、说明 在LangChain的帮助下创建LLM应用程序可以帮助我们轻松地链接所有内容。LangChain 是一个创新的框架&#xff0c;它正在彻底改变我们开发由语言模型驱动的应用程序的方式。通过结合先进的原则&#xff0c;LangChain正在重新定义通过传统API可以实现的极限。 在上一篇博…

一文读懂!一年耗能堪比2个三峡电站的大数据中心,背后竟隐藏着这些秘密......

全国大数据中心1年的能耗规模相当于2个三峡电站一整年的发电量&#xff0c;这是为什么&#xff1f; 大数据中心每耗费1度电&#xff0c;只有一半用在了“计算”上面&#xff0c;其他的都应用在散热、照明等方面到底是怎么回事&#xff1f; 为什么说在算力上每投入1元&#xff0…

【二】数据库系统

数据库系统的分层抽象DBMS 数据的三个层次从 数据 到 数据的结构----模式数据库系统的三级模式&#xff08;三级视图&#xff09;数据库系统的两层映像数据库系统的两个独立性数据库系统的标准结构 数据模型从 模式 到 模式的结构----数据模型三大经典数据模型 数据库的演变与发…

【系统软件03】centos7安装和使用node-v18.16.0(centos7升级glibc 2.28)

【系统软件03】centos7安装和使用node-v18.16.0&#xff08;centos7升级glibc 2.28&#xff09; 前言&#xff1a;本文是解决node 18.16.0的依赖问题&#xff0c;具体的node安装流程&#xff0c;可以参考我的另外一篇文章。一、下载node v18.16.0二、下载glibc2.28&#xff08;…

uniapp使用阿里矢量库

然后解压复制全部到你的项目文件 最后只要这几个 然后引入 最后在你需要的页面使用

JavaWeb中Json传参的条件

JavaWeb中我们常用json进行参数传递 对应的注释为RequestBody 但是json传参是有条件的 最主要是你指定的实体类和对应的json参数能否匹配 1.属性和对应的json参数名称对应 2.对应实体类实现了Serializable接口&#xff0c;可以进行序列化和反序列化&#xff0c;这个才是实体类转…