Machine Learning Specialization 学习笔记(3)

news2024/11/13 12:58:29

文章目录

  • 前言
  • 一、神经网络
    • 基本概念
      • 基本组成
      • 工作流程
      • 训练过程
      • 类型
      • 应用举例
        • 不同层次特征的学习
      • 为什么从基础特征到复杂特征逐渐推进
        • 什么是感受野
        • 更简单的解释
        • 具体示例
        • 总结
  • 二、TensorFlow实现简单神经网络
    • 安装及环境配置
    • 数据预处理
      • 标准化
    • Dense层
    • Convolutional Layer
    • 训练
    • DEBUG
  • 三、激活函数
    • RELU
    • Softmax
      • Softmax的优化
      • 多分类问题
  • 四、高级优化方法
    • Adam


前言

博客仅记录个人学习进度和一些查缺补漏。
学习内容:BV1Bq421A74G


一、神经网络

神经网络(Artificial Neural Networks,ANNs)是受人脑结构启发而构建的计算模型,用于模拟大脑神经元网络处理信息的方式。它们是机器学习和深度学习领域的核心技术之一,能够解决多种复杂的模式识别和预测问题。

基本概念

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

基本组成

神经网络由以下基本组件构成:

  1. 神经元(Neurons):网络的基本单元,类似于人脑中的神经元。每个神经元接收输入,进行加权求和,并通过激活函数处理这个求和值来产生输出。
  2. 层(Layers):神经元被组织成层。一个基本的神经网络包括输入层、一个或多个隐藏层以及输出层。
  3. 连接权重(Weights):连接神经元的边具有权重,这些权重在训练过程中学习得到。
  4. 偏置(Biases):每个神经元还可以有一个偏置项,它用来调整神经元的输出。
  5. 激活函数(Activation Functions):用于引入非线性,使得神经网络能够学习和执行更复杂的任务。

工作流程

  1. 前向传播(Forward Propagation):输入数据在网络中从输入层经过隐藏层传递到输出层,每一层的输出成为下一层的输入。
  2. 损失函数(Loss Function):计算模型预测值和真实值之间的差异。
  3. 反向传播(Backpropagation):利用损失函数计算的梯度,通过网络反向传播这些梯度,以更新网络中的权重和偏置。
  4. 优化算法(Optimization Algorithms):如梯度下降(Gradient Descent)及其变体,用于在每次迭代中更新权重,以最小化损失函数。

训练过程

训练神经网络通常涉及以下步骤:

  1. 初始化:随机初始化网络权重和偏置。
  2. 迭代训练:通过多次迭代训练数据集,每次迭代都会进行前向传播和反向传播。
  3. 评估和调整:在验证集上评估模型性能,并根据需要调整模型结构或训练过程。
  4. 测试:使用测试集评估训练好的模型的性能。

类型

  • 前馈神经网络(Feedforward Neural Networks,FNN):最常见的类型,信息只向前流动,没有反馈连接。
  • 卷积神经网络(Convolutional Neural Networks,CNN):特别适合处理图像数据,具有卷积层来捕捉局部特征。
  • 循环神经网络(Recurrent Neural Networks,RNN):适合处理序列数据,如时间序列分析和自然语言处理。
  • 长短期记忆网络(Long Short-Term Memory,LSTM):一种特殊的RNN,能够学习长期依赖关系。

应用举例

在这里插入图片描述

在这里插入图片描述
g->激活函数
在这里插入图片描述
基于TensorFlow的简单dense层
在这里插入图片描述

不同层次特征的学习

第一层:低级特征
边缘和纹理:第一层的卷积核(filters)通常检测图像的基本边缘、线条和简单的纹理。这些特征包括水平、垂直和对角线方向的边缘。
局部感受野:第一层的卷积核通常应用于图像的小局部区域(称为感受野),这使得它们只能提取局部的一些基础特征。

中间层:中级特征
模式和形状:中间层的神经元结合了前几层检测到的低级特征,形成更复杂的模式和形状,如角元素、曲线、简单几何图形。
增大的感受野:随着层数增加,每层的神经元感受的图像区域会变大,即“感受野”会变大。这样它们可以综合前面层次的信息,识别更加复杂的模式。

高级层:高级特征
物体组件和语义特征:在更深的层中,神经网络开始组合之前学习到的复杂模式,识别出具体物体的部分或更抽象的语义特征。例如,一些神经元可能对人脸的某些组件(如眼睛、鼻子)特别敏感。
全图感知:最深的层一般具有最大的感受野,能够感知到整个输入图像的信息,因而能识别出完整的物体或者整个场景。

为什么从基础特征到复杂特征逐渐推进

在多层神经网络中,尤其是卷积神经网络(CNN),特征提取往往是从基础特征到复杂特征逐渐推进。这是因为:

  1. 局部到全局:早期层的卷积滤波器(filters)处理的是图像的小块区域,只能检测出简单的边缘和纹理。随着层数的增加,高层的滤波器能够结合更多早期层的输出,逐渐构建出更复杂的特征,如形状、物体部件,最终形成完整的物体识别。

  2. 逐层组合:每一层的输出是前一层的输入。早期层提取简单的特征,这些特征被传递到后续层,后续层将在此基础上进一步组合和加工这些特征,形成更高级的描述。

  3. 有效特征表征:通过这样的层次化结构,神经网络能有效地表示和处理图像中的信息,从而更好地完成识别任务。从简单到复杂的特征提取过程,使得模型能够理解和处理多种多样的视觉模式,增强了其泛化能力。

什么是感受野

感受野(Receptive Field)是一个神经元在输入图像上“看到”或响应的区域。更简单地说,它指的是输出层的一个特定神经元对应于输入图像的哪些位置。

更简单的解释
  1. 直观理解
    • 小感受野:在神经网络的早期层,每个神经元只对图像的一小块区域负责,就像你用放大镜仅仅看到图像中的非常小的一部分,比如一个小方块的边缘。
    • 大感受野:在后续层,每个神经元能够"看到"更大范围的图像,就像你逐渐放远视角,能看到图像中更大的部分,比如整个形状或物体的一部分。
具体示例

假设你有一个三层卷积神经网络,每一层都有一个3x3的卷积核:

  • 第一层:每个神经元看到3x3的图像区域。此时的感受野是3x3。
  • 第二层:接受第一层3x3区域的输出作为输入,相当于每个第二层的神经元看到了5x5的图像区域(因为第一层看3x3区域的每一个会扩大感受野)。
  • 第三层:这个神经元的感受野会更大,达到7x7。

通过层叠更多层次,每个神经元能够逐渐"感知"到输入图像中更大的区域,最终高层的神经元可以拥有整个图像的全局视角,这使得它们能够识别整体的复杂特征和物体。

总结

从基础特征到复杂特征的逐层推进源自网络各层对信息逐渐复杂和综合的处理方式。感受野是帮助理解这一过程的一个关键概念,它直观描述了每个神经元在输入图像中负责的具体区域。从小感受野到大感受野,使得神经网络能够逐步从细节到整体进行信息处理和特征提取。

二、TensorFlow实现简单神经网络

安装及环境配置

安装TensorFlow的前置:

  • NVIDIA GPU 驱动程序已安装。
  • CUDA Toolkit 和 cuDNN 已安装(版本需要与 TensorFlow 版本兼容)。
  • 也可以一键安装:
pip install tensorflow[and-cuda]

在~/.bashrc文件末尾添加以下内容:(以cuda-12.1为例)

export PATH=/usr/local/cuda-12.1/bin${PATH:+:${PATH}}
export LD_LIBRARY_PATH=/usr/local/cuda-12.1/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}

然后运行source ~/.bashrc来使环境变量生效。
nvcc --version 查看是否安装成功

运行时会出现很多warning,能识别GPU,代码能运行就行。

数据预处理

标准化

使用 tf.keras.layers.Normalization 进行标准化处理
标准化(Standardization)是一种数据预处理技术,它将数据的特征值转换为具有零均值(0)和单位方差(1)的分布。标准化的公式如下:
在这里插入图片描述
其中:

  • x 是原始数据点。
  • μ 是数据点的均值。
  • σ 是数据点的标准差。

就像之前做的正态分布的标准化。

print(f"Temperature Max, Min pre normalization: {np.max(X[:,0]):0.2f}, {np.min(X[:,0]):0.2f}")
print(f"Duration    Max, Min pre normalization: {np.max(X[:,1]):0.2f}, {np.min(X[:,1]):0.2f}")
norm_l = tf.keras.layers.Normalization(axis=-1)
norm_l.adapt(X)  # learns mean, variance
Xn = norm_l(X)
print(f"Temperature Max, Min post normalization: {np.max(Xn[:,0]):0.2f}, {np.min(Xn[:,0]):0.2f}")
print(f"Duration    Max, Min post normalization: {np.max(Xn[:,1]):0.2f}, {np.min(Xn[:,1]):0.2f}")

在 TensorFlow 中,tf.keras.layers.Normalization 是一个层(Layer),它用于对输入数据进行标准化处理,使得每个样本的每个特征的均值为0,标准差为1。这种标准化通常在数据预处理阶段使用,有助于提高模型的训练效率和性能。

这里的 norm_l 是一个 Normalization 层的实例,它被创建并设置了 axis 参数。axis=-1 表示标准化将以最后一个轴进行,对这个轴位上的所有数据进行处理,这通常是特征轴。这意味着层将对每个样本的特征进行独立的标准化,而不是在整个批次或整个特征集上进行。

在机器学习和数据处理中,数据通常以多维数组(例如,二维数组或矩阵)的形式存在。在这些数组中,每个维度(或轴)代表了数据的不同方面。在 TensorFlow 和 Keras 中,axis 参数用于指定在哪个维度上进行操作。

在本例中:当你在使用 tf.keras.layers.Normalization 层时,axis=-1 的设置意味着标准化操作将在输入数据的最后一个维度上进行。在大多数情况下,对于输入数据:

  • axis=0 指的是样本轴(batch size 或样本数量)。
  • axis=1 指的是特征轴(在二维数组中,这通常是列,代表每个样本的特征)。
  • axis=-1 等同于 axis=1,因为它指的是最后一个维度,也就是特征轴。
    因此,当你设置 axis=-1 时,你告诉标准化层对每个样本的特征进行独立的标准化,而不是在整个数据集的所有特征上进行标准化。这意味着每个样本的特征将被调整为具有0的均值和1的标准差,而不考虑其他样本的特征。这样做的目的是使得模型训练不会受到单个样本特征值范围的影响,从而有助于模型更快地收敛,并可能提高模型的性能。

Dense层

Dense的官方文档:https://tensorflow.google.cn/api_docs/python/tf/keras/layers/Dense

tf.random.set_seed(1234)  # applied to achieve consistent results
model = Sequential(
    [
        tf.keras.Input(shape=(2,)),
        Dense(3, activation='sigmoid', name = 'layer1'),
        Dense(1, activation='sigmoid', name = 'layer2')
     ]
)

在TensorFlow中,tf.random.set_seed(seed) 函数用于设置随机数生成器的种子,以确保每次运行代码时都能获得一致的结果。这对于实验的可重复性非常重要,因为不同的随机种子可能会导致模型初始化权重的随机性,从而影响模型训练的结果。
定义了一个Sequential模型,它是一个线性堆叠的层序列。模型包含一个Input层和两个Dense层:

  • f.keras.Input 是一个用于定义输入层的类。它用于指定模型输入数据的形状。当你构建一个模型时,Input 层是模型的第一层,它告诉模型期望的输入数据的维度。tf.keras.Input(shape=(2,)) 表示模型的输入数据应该有 2 个特征。这里的 shape 参数是一个 tuple(元组),它定义了输入数据的形状。在这种情况下,形状是 (2,),这意味着每个输入样本都应该是一个包含两个数值的向量。
  • 第一个Dense层有3个神经元,使用sigmoid激活函数,命名为layer1。
  • 第二个Dense层有1个神经元,也使用sigmoid激活函数,命名为layer2。
    每个Dense层都是全连接层,其中神经元的数量对应于该层的输出维度。sigmoid激活函数是一个将输入映射到(0, 1)区间的激活函数,它在二分类问题中经常被用作输出层的激活函数。

在这里插入图片描述
注意:W(原输入特征数量,该层w参数的数量)
更直观的:
在这里插入图片描述
在这里插入图片描述

Convolutional Layer

在这里插入图片描述
卷积神经网络
在这里插入图片描述

训练

model.compile(
    loss = tf.keras.losses.BinaryCrossentropy(),
    optimizer = tf.keras.optimizers.Adam(learning_rate=0.01),
)

model.fit(
    Xt,Yt,            
    epochs=10,
)
  • model.compile 方法用于配置模型的学习过程。它接收损失函数、优化器和其他可选参数(如评估指标)。
  • loss = tf.keras.losses.BinaryCrossentropy():指定了模型的损失函数为二元交叉熵(Binary Crossentropy),这适用于二分类问题。
  • optimizer = tf.keras.optimizers.Adam(learning_rate=0.01):指定了模型的优化器为 Adam 优化器,并将学习率设置为 0.01。Adam 是一种自适应学习率优化算法,它结合了 RMSprop 和 Momentum 两种优化算法的优点
  • model.fit 方法用于训练模型。
  • Xt 和 Yt 分别代表训练数据的特征和标签。Xt 应该是一个形状为 (samples, features) 的数组,而 Yt 应该是一个形状为 (samples,) 的数组或二维数组(如果使用 one-hot 编码)。
  • epochs=10:指定了训练过程中整个数据集将被遍历的次数。每个 epoch 都会对所有训练数据进行一次前向和后向传播。
    在这里插入图片描述
    其中,fit已经帮我们完成了反向传播

DEBUG

在这里插入图片描述

三、激活函数

除了常常用于分类的SIGMOD函数,还有其他的激活函数可供使用
在这里插入图片描述
在这里插入图片描述
需要根据你的标签类型需要去01或是正负或是非负,事实证明在隐藏层最常用的就是relu。
Q 为什么需要激活函数:

A 引入非线性
无论是多层感知机还是卷积神经网络,若没有激活函数,它们都只会做线性变换,层与层之间的叠加仍然是线性的。这时,无论多少层的神经网络,其输出都可以用一个线性变换来表示,无法捕捉复杂的数据模式和特征。引入非线性激活函数后,神经网络可以学习和表示更复杂的非线性关系,从而增强模型的表达能力。

激发多样性
不同的激活函数使各个神经元对输入信号的响应不同。这样,在网络的不同部分可以捕捉和表示数据的不同特征和模式,从而促进特征学习和分类。

梯度传播
常见的激活函数,例如ReLU、sigmoid和tanh,具有可微性质,允许通过反向传播算法计算和传递梯度。反向传播是神经网络训练的重要方法,只有激活函数使得梯度存在且易于计算,网络才能通过调整权重逐步逼近目标输出。

数值稳定性
适当的激活函数可以帮助缓解梯度消失或爆炸问题。例如,ReLU函数的引入极大地改善了深层神经网络的训练效果,因为它在正区间不饱和,能够有效传递梯度。

引入非线性激活函数使神经网络能够更好地学习复杂特征,主要原因有以下几个方面:

复杂函数逼近:
线性函数的组合仍然是线性函数,无法捕捉输入和输出之间的复杂非线性关系。而由于现实世界中的大多数问题(如图像、语音识别等)往往具有高度非线性和复杂性,单纯的线性变换无法有效地建模这些问题。激活函数如ReLU、sigmoid等引入了非线性,使得网络有能力逼近任意复杂的非线性函数。这基于著名的通用逼近定理,该定理指出,具有非线性激活函数的单隐层前馈神经网络在适当的条件下可以逼近任意连续函数。

特征选取能力:
通过非线性激活函数,每一层的神经元在处理输入数据时可以进行更加多样和丰富的特征变换。例如,ReLU激活函数可以强化正值输入、抑制负值输入,从而有助于提取关键特征,而sigmoid函数则可以将输入映射到0到1的范围,从而有助于概率分布的建模。这些非线性变换使得神经网络能够在多层次上提取和组合特征,从而捕捉更高阶的特征关系。

增加模型复杂度:
激活函数通过引入非线性,使得每一层网络输出的特征变换更加复杂和灵活。多层神经网络中,每一层都对前一层的输出进行加权求和并通过激活函数处理。这些处理步骤叠加起来,使得整体网络具备更强的表达能力,能够学习和表征更加复杂和细致的特征。

决策边界:
没有非线性激活函数,神经网络只能形成线性分类器,学习到的决策边界是线性的,无法分类线性不可分的数据。引入非线性激活函数后,神经网络可以学习到复杂的非线性决策边界,从而能够对复杂的、高维数据进行更有效的分类。

RELU

在这里插入图片描述
relu保证了激活后的函数值非负

ReLU(Rectified Linear Unit,修正线性单元)是深度学习中常用的一种激活函数。它的数学表达式非常简单:
在这里插入图片描述

这意味着当输入 ( x ) 为正数时,ReLU 函数输出 ( x );当输入 ( x ) 为负数时,ReLU 函数输出 0。这个函数的图形是一个斜率为 1 的直线,从 ( x = 0 ) 开始。

ReLU 激活函数的优点包括:

  1. 计算简单:ReLU 函数的计算非常快速,因为它只涉及一个阈值操作。

  2. 减少梯度消失问题:在正区间内,ReLU 的梯度是常数 1,这有助于缓解梯度消失问题,特别是在深层网络中。

  3. 稀疏激活:由于负值被置为 0,ReLU 函数会产生稀疏的输出,这意味着在任何时候只有一部分神经元被激活,这有助于提高模型的稀疏性和计算效率。

  4. 减少模型复杂度:在某些情况下,ReLU 可以减少模型的复杂度和过拟合的风险。

然而,ReLU 也有一些缺点,例如:

  1. 死亡ReLU问题:如果输入 ( x ) 持续为负,ReLU 函数的梯度将为 0,这可能导致在训练过程中某些神经元不再更新(即“死亡”)。

  2. 不饱和:ReLU 函数在正区间内不饱和,这意味着它不会像 sigmoid 或 tanh 函数那样在一定范围内达到稳定值。

尽管如此,ReLU 及其变体(如 Leaky ReLU、Parametric ReLU(PReLU)、Exponential Linear Unit(ELU)等)在许多深度学习应用中仍然是首选的激活函数之一。在 TensorFlow 中,你可以很容易地在神经网络层中使用 ReLU 激活函数:

Softmax

在这里插入图片描述

Softmax 函数是一种在多类分类问题中常用的激活函数,特别是在神经网络的输出层。它的作用是将一个向量或一组实数转换为概率分布,使得每个元素的值都在0到1之间,并且所有元素的和为1。这使得Softmax函数非常适合用作分类任务的输出,因为它可以解释为属于某个类别的概率。

Softmax 函数的数学表达式定义如下:

设z 为一个实数向量,σ(z) 为 Softmax 函数,则对于向量z 中的每个元素z_i ,Softmax 函数定义为:

在这里插入图片描述

其中,分子是 z_i 的指数,分母是所有 z 中元素指数的总和。这个公式确保了输出值在0到1之间,并且所有输出值的和为1。

Softmax 函数的特点:

  1. 概率解释:Softmax 函数的输出可以被解释为概率,这对于分类问题非常有用。

  2. 处理多个类别:Softmax 可以处理任意数量的类别,使得每个类别都有一个相应的概率输出。

  3. 数值稳定性:在实际计算中,直接计算指数可能会因为数值过大而导致溢出。为了避免这个问题,通常会从每个 ( z_i ) 中减去 ( z ) 中的最大值,即在这里插入图片描述

  4. 梯度特性:Softmax 函数的梯度相对于其他激活函数(如 Sigmoid)更平滑,这有助于梯度下降算法的稳定性。
    在这里插入图片描述
    在这里插入图片描述

Softmax的优化

之前是做了一步中间变化将z转换成了a然后再进行损失函数的计算,这就会导致在z->a这一步的softmax激活函数后,过大或者过小的数会损失精度,所以直接将这一层用线性函数激活然后在最终计算损失函数的时候,确认进行逻辑回归(true)。这样在底层TensorFlow就回自动安排计算顺序使得精度增加。
在这里插入图片描述

多分类问题

在这里插入图片描述
在机器学习和深度学习中,“Multiple Class”(多类)和"Multiple Label"(多标签)是两种不同的分类任务,它们在目标和处理方式上有所区别:

  1. Multiple Class(多类分类)

    • 多类分类任务是指每个样本仅属于一个类别的情况。
    • 目标是预测样本属于预定义类别中的哪一个。
    • 例如,一个图像识别任务,目标是识别图像中的物体是猫、狗还是鸟(假设每个图像中只有一个物体)。
    • 在神经网络的输出层,通常使用 Softmax 激活函数来处理多类分类问题,因为 Softmax 可以输出每个类别的概率,并且这些概率的总和为1。
    • 多类分类问题通常使用交叉熵损失函数(Cross-Entropy Loss)来训练模型。
  2. Multiple Label(多标签分类)

    • 多标签分类任务是指每个样本可以同时属于多个类别的情况。
    • 目标是预测样本同时属于哪些类别。
    • 例如,一个图像识别任务,目标是识别图像中同时存在的多个物体,如猫、狗和汽车(一个图像中可能同时包含多个物体)。
    • 在神经网络的输出层,通常使用 Sigmoid 激活函数来处理多标签分类问题,因为 Sigmoid 可以为每个类别输出一个概率,表示样本属于该类别的概率。
    • 多标签分类问题可以使用二元交叉熵损失函数(Binary Cross-Entropy Loss)来训练模型,每个类别独立计算损失。

四、高级优化方法

在这里插入图片描述
以前的单纯梯度下降,如果学习率太低就回导致进度缓慢,如果学习率太高就会导致震荡

在这里插入图片描述

Adam

Adam(Adaptive Moment Estimation)是一种广泛使用的深度学习优化算法,由Diederik P. Kingma和Jimmy Ba在2014年提出。它结合了动量法(Momentum)和RMSProp的思想,通过计算梯度的一阶矩估计和二阶矩估计来调整每个参数的学习率,从而实现更高效的网络训练。Adam算法的关键组成部分之一是使用指数加权移动平均值来估算梯度的动量和第二力矩,即它使用状态变量来存储这些估计值,并对其进行偏差校正,以确保在训练初期时梯度估计不会偏向于0。

Adam算法的优点包括:

  1. 自适应学习率:Adam通过计算一阶和二阶矩估计来为每个参数自适应地调整学习率。
  2. 偏差校正:初始阶段梯度估计可能偏低,通过偏差校正可以加速初期的学习速率。
  3. 适应性强:Adam在很多不同的模型和数据集上都表现出了良好的性能。

然而,Adam算法也存在一些缺点,如训练过程中可能会出现震荡现象,影响收敛速度,以及算法对于初始参数的选择较为敏感。

在实际应用中,Adam算法的参数配置包括学习率(alpha)、一阶矩估计的指数衰减率(beta1)、二阶矩估计的指数衰减率(beta2)和非常小的数(epsilon),以防止在实现中除以零。通常,这些超参数的默认值在很多情况下都表现良好,但某些问题可能需要仔细的超参数调整。

Adam算法在深度学习领域内是十分流行的算法,因为它能很快地实现优良的结果。在原论文中,作者经验性地证明了Adam算法的收敛性符合理论性的分析,并在多个数据集上应用优化算法,证明了其高效性。

在PyTorch中,使用Adam优化器非常简单,首先需要导入torch.optim模块,然后选择Adam优化器。例如:

import torch
import torch.nn as nn
import torch.optim as optim
# 定义一个简单的线性模型
model = nn.Linear(10, 1)
# 定义损失函数
criterion = nn.MSELoss()
# 定义Adam优化器
optimizer = optim.Adam(model.parameters(), lr=0.001)

总的来说,Adam算法是一种高效的优化算法,在深度学习领域具有广泛的应用前景。随着计算资源和算法技术的不断发展,Adam算法在未来有望在更多领域取得突破性成果。

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

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

相关文章

独立站技能树/工具箱1.0 总纲篇丨出海笔记

正所谓要把一件事做到90分很难,但做到60分基本上照着SOP做到位都没问题,如果我们能把每件事都做到60分,那绝对比至少60%的人都强,除非你的对手不讲武德——那就是他很可能看了我这篇文章,不但每方面都超过及格线&#…

MySQL高阶1853-转换日期格式

目录 题目 准备数据 分析数据 总结 题目 给定一个Days表,请你编写SQL查询语句,将Days表中的每一个日期转化为"day_name, month_name day, year"格式的字符串。 返回的结果表 不计顺序 。 准备数据 Create table If Not Exists Days (d…

Arthas 全攻略:让调试变得简单

文章目录 一、简介二、命令列表 一、简介 Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常&#xff…

排序---冒泡排序、堆排序

一、冒泡排序 相邻两个位置交换,假设排升序,就不断把最大的往后拿,所以这段序列从后往前变得有序。 //flag为0,即这个数组已经是有序的了,节省循环次数 二、堆排序(数组实现) 具体原理介绍看这…

jetcache-阿里多级缓存框架神器一定要掌握

文章目录 1. 简介2. springboot集成jetcache2.1 引入依赖2.2 配置文件2.3 高级API模式:通过CacheManager使用缓存,2.7 版本才可使用2.4 (推荐)AOP模式:通过Cached,CacheUpdate,CacheInvalidate注解 1. 简介 JetCache是…

局部整体(六)利用python绘制树状图

局部整体(六)利用python绘制树状图 树状图( Dendrogram)简介 由一个根节点组成,根节点产生多个通过分支连接的子节点。常用于表示层次结构或显示聚类算法的结果。树状图既可以看明白数据的层次结构,也能明…

兴业小知识|法拍房你不知道的省钱小技巧~划走可就亏大了

如果说二手房市场是买卖双方之间的博弈,那法拍房市场则是纯买方的心理游戏。 在法拍房竞拍过程中,有人稳如泰山,有人坐立不安,每一次的出价都是对相互底线的一番试探。 有激进竞拍,拍出天价的,有一举夺魁…

2024.9.20营养小题【2】(动态分配二维数组)

这道题里边涉及到了动态分配二维数组的知识点,不刷这道题我也不知道这个知识点,算是一个比较进阶一点的知识点了。 参考:C语言程序设计_动态分配二维数组_哔哩哔哩_bilibili【C/C 数据结构 】二维数组结构解析 - 知乎 (zhihu.com)

网络爬虫Request静态页面数据获取

在现代 Web 开发中,HTTP 请求(Request)是与服务器进行通信的核心操作。无论是在前端还是后端开发中,数据的获取、传递以及处理都离不开请求的应用。特别是在静态页面的数据获取中,使用请求可以将页面变得更加动态和互动,从而大大提升用户体验,使得页面内容更加丰富和灵活…

电风扇制造5G智能工厂物联数字孪生平台,推进制造业数字化转型

电风扇正悄然成为制造业数字化转型浪潮中的一颗璀璨新星。通过构建5G智能工厂物联数字孪生平台,电风扇制造业正以前所未有的速度和精度,推进着整个行业的智能化、网络化与个性化发展。5G技术的飞速发展,为制造业带来了前所未有的通信速度和低…

vue 入门一

参考&#xff1a;丁丁的哔哩哔哩 1.使用vue 1.1 使用CDN的方式使用Vue mount和<div id"counter">关联起来 1.2 vue中的createApp import { createApp } from "vue"; import App from "./App.vue"; createApp(App).mount("#app&qu…

【软件测试】如何设计测试用例? 设计测试用例常用的方法.

目录 一.什么是测试用例?二.总体设计测试用例的万能公式.2.1 功能性能界面兼容易用安全2.2 弱网测试2.3 安装卸载测试. 三. 常用设计具体测试用例的方法3.1 等价类3.2 边界值3.3 正交法3.3.1 正交表3.3.2 如何设计正交表,并根据正交表编写测试用例 3.4 判定表法3.4.1 根据判定…

红日药业携手实在智能,构建RPA数字员工平台满足业务一体化需求 | 实在RPA案例

近日&#xff0c;天津红日药业股份有限公司&#xff08;简称“红日药业”&#xff09;与实在智能达成合作&#xff0c;依托实在智能业内领先的AIRPA技术&#xff0c;红日药业着手构建企业数字员工平台&#xff0c;满足业务一体化需求&#xff0c;培育新质生产力&#xff0c;为企…

基于PHP的电脑线上销售系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于phpMySQL的电脑线上销售系…

小程序服务零工市场

零工市场小程序有着信息发布、岗位匹配、线上接单、零工人员保障险参保、技能培训、费用结算、完工确认、服务评价、纠纷调解等功能&#xff0c;为求职者和雇主搭建一座高效、便捷、精准的对接桥梁。 用工单位通过小程序的“雇主找人”&#xff0c;发布招聘信息&#xff0c;找到…

react-native连接android原生模块

目录 搭建react-native项目 搭建node和jdk的环境 搭建Android的环境 创建React-native项目 运行react-native项目 下载夜神模拟器 使用adb连接夜神浏览器。 运行react-native项目 编写原生安卓的apk android studio中编写原生代码 在React-native编写代码。 搭建rea…

【干货分享】2024软件测试面试题汇总

前言 本篇分享的软件测试面试题内容主要包括&#xff1a;测试总体、需求分析、测试计划、测试策略、测试用例、缺陷报告、测试总结报告、白盒测试、单元测试、集成测试、系统测试、验收测试等等26个模块。 1. 什么是软件测试&#xff1f; 答&#xff1a;为了发现程序中的错误…

滚动条指定距离滚动

/*** scroller 滚动条元素* to 滚动到位置* duration 滚动时间*/ function scrollLeftTo (scroller, to, duration) {let rafIdlet count 0const from scroller.scrollLeftconst frames duration 0 ? 1 : Math.round((duration * 1000) / 16)function cancel () {cancelAn…

学习CubeIDE——定时器开发

在b站上学习洋桃电子关于HAL库开发&#xff0c;发现使用CubeIDE是真的简单又方便。 实验现象&#xff1a;使用定时器来产生中断&#xff0c;中断程序是LED灯翻转 在我看来&#xff0c;定时器&#xff0c;是一个从0开始增1&#xff08;常规&#xff09;&#xff0c;增加到一定…

存量新篇,商机无限,2024中国重庆建博会将于下月开展

在步入存量房时代的全新篇章中&#xff0c;中国家居建材行业正孕育着前所未有的转型机遇与商业蓝海。重庆作为西南地区的璀璨明珠与战略要地&#xff0c;以前所未有的决心与力度&#xff0c;推进实施了旧改局改与以旧换新等一系列创新政策。 《关于加快推进中心城区旧城改造工…