【神经网络基础】

news2025/1/20 12:29:42

目录

一、神经网络的构成

1.1什么是神经网络?

1.2 激活函数

1.2.1 Sigmoid

1.2.2 Tanh

1.2.3 ReLU

1.2.4 softmax

1.2.5 其他激活函数

1.2.6 选择激活函数

1.3 参数初始化

1.4 模型构建

二、损失函数

2.1 分类问题

2.1.1多分类(多分类交叉熵/softmax损失)

2.1.2 二分类(二分类交叉熵/sigmoid损失)

2.2 回归问题

2.2.1 MSE(L2 loss)

2.2.2 MAE(L1 loss)

2.2.3 Smooth L1

三、优化方法

3.1 反向传播

3.2 梯度下降的优化方法 

3.2.1 指数加权平均

3.2.2 动量算法Momentum

 3.2.3 AdaGrad

 3.2.4 RMSProp

3.2.5 Adam 

3.3 学习率衰减 

3.3.1 等间隔衰减

3.3.2 指定间隔衰减

3.3.3 指数衰减

四、正则化

4.1 Dropout正则化

4.2 批量归一化


一、神经网络的构成

1.1什么是神经网络?

人工神经网络( Artificial Neural Network, 简写为ANN)也简称为神经网络(NN),是一种模仿生物神经网络结构和功能的计算模型。由神经元(加权和 + 激活函数)构成
神经网络中信息只向一个方向移动,即从输入节点向前移动,通过隐藏节点,再向输出节点移动。
其中的基本部分是 :
1. 输入层 : 即输入 x 的那一层
2. 输出层 : 即输出 y 的那一层
3. 隐藏层 : 输入层和输出层之间都是隐藏层
特点是:
同一层的神经元之间没有连接。
N 层的每个神经元和第 N-1 层 的所有神经元相连(这就是 full connected 的含义 ) ,这就是全连接神经网络。
N-1 层神经元的输出就是第 N 层神经元的输入。
每个连接都有一个权重值( w 系数和 b 系数)。

1.2 激活函数

解释:激活函数由于对每层的输出数据进行变换,进而为整个网络注入了非线性因素。此时,神经网路就可以拟合各种曲线。

1. 没有引入非线性因素的网络等价于使用一个线性模型来拟合

2. 通过给网络输出增加激活函数, 实现引入非线性因素, 使得网络模型可以逼近任意函数, 提升网络对复杂问题的拟合能力.

1.2.1 Sigmoid

常见的激活函数-sigmoid 激活函数 :(适用于二分类的输出层)

① sigmoid 函数可以将任意的输入映射到 (0, 1) 之间,当输入的值大致在 <-6 或者 >6 时,意味着输入任何值得到的激 活值都是差不多的,这样会丢失部分的信息。比如:输入 100 和输出 10000 经过 sigmoid 的激活值几乎都是等于 1 的,但是输入的数据之间相差 100 倍的信息就丢失了。

② 对于 sigmoid 函数而言,输入值在 [-6, 6] 之间输出值才会有明显差异,输入值在 [-3, 3] 之间才会有比较好的效果

③ 通过上述导数图像,我们发现导数数值范围是 (0, 0.25),当输入 <-6 或者 >6 时,sigmoid 激活函数图像的导数接近 0,此时网络参数将更新极其缓慢,或者无法更新。

④ 一般来说, sigmoid 网络在 5 层之内就会产生梯度消失现象。而且,该激活函数并不是以 0 为中心的,所以在实践 中这种激活函数使用的很少。sigmoid函数一般只用于二分类的输出层

import torch
import matplotlib.pyplot as plt
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'

plt.rcParams['font.sans-serif'] = ['SimHei']  # 选择中文字体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 创建画布和坐标轴
_, axes = plt.subplots(1, 2)
# 函数图像
x = torch.linspace(-20, 20, 1000)
y = torch.sigmoid(x)
axes[0].plot(x, y)
axes[0].grid()
axes[0].set_title('sigmoid 函数图像')


# 导数图像
x = torch.linspace(-20, 20, 1000, requires_grad=True)
torch.sigmoid(x).sum().backward()
axes[1].plot(x.detach(), x.grad)
axes[1].grid()
axes[1].set_title('sigmoid导数图像')
plt.show()

1.2.2 Tanh

常见的激活函数 -tanh 激活函数:

  • 隐藏层中要使用指数型激活函数时,就选择tanh,不要使用sigmoid

  • [-1,1],关于0对称

  • 导数相对于sigmoid大,更新速度快,迭代次数少

  • x远离0点时,梯度为0,梯度消失/弥散

① Tanh 函数将输入映射到 (-1, 1) 之间,图像以 0 为中心,在 0 点对称,当输入 大概<-3 或者>3 时将被映射为 -1 或者 1。其导数值范围 (0, 1),当输入的值大概 <-3 或者 > 3 时,其导数近似 0。

② 与 Sigmoid 相比,它是以 0 为中心的,且梯度相对于sigmoid大,使得其收敛速度要比Sigmoid 快,减少迭代次数。然而,从图中可以看出,Tanh 两侧的导数也为 0,同样会造成梯度消失。

③ 若使用时可在隐藏层使用tanh函数,在输出层使用sigmoid函数

import torch
import matplotlib.pyplot as plt
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'

plt.rcParams['font.sans-serif'] = ['SimHei']  # 选择中文字体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 创建画布和坐标轴
_, axes = plt.subplots(1, 2)
# 函数图像
x = torch.linspace(-20, 20, 1000)
y = torch.tanh(x)
axes[0].plot(x, y)
axes[0].grid()
axes[0].set_title('Tanh 函数图像')
# 导数图像
x = torch.linspace(-20, 20, 1000, requires_grad=True)
torch.tanh(x).sum().backward()
axes[1].plot(x.detach(), x.grad)
axes[1].grid()
axes[1].set_title('Tanh 导数图像')
plt.show()

1.2.3 ReLU

常用的激活函数 -ReLU 激活函数:

- 隐藏层使用,最多
- 小于0 ,取值为0 ;大于0 ,本身
- 导数:小于0 ,取值为0 ;大于0 ,为1
- 大于0 :不会梯度消失
- 小于0:
  - 当某一部分神经元输出为0,神经元死亡,缓解过拟合
  - 当大部分神经元输出为0,从头开始或换激活函数leakyrelu
- 相对于sigmoid: 计算简单,计算量小(函数和求导)

① ReLU 激活函数将小于 0 的值映射为 0,而大于 0 的值则保持不变,它更加重视正信号,而忽略负信号,这种激活函数运算更为简单,能够提高模型的训练效率。

② 当x<0时,ReLU导数为0,而当x>0时,则不存在饱和问题。所以,ReLU 能够在x>0时保持梯度不衰减,从而缓解梯度消失问题。然而,随着训练的推进,部分输入会落入小于0区域,导致对应权重无法更新。这种现象被称为“神经元死亡” 。

ReLU是目前最常用的激活函数。与sigmoid相比,RELU的优势是:采用sigmoid函数,计算量大(指数运算),反向传播求误差梯度时,计算量相对大,而采用Relu激活函数,整个过程的计算量节省很多。 sigmoid函数反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练。 Relu会使一部分神经元的输出为0,这样就造成了网络的稀疏性,并且减少了参数的相互依存关系,缓解了过拟合问题的发生。

import torch
import matplotlib.pyplot as plt
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'

plt.rcParams['font.sans-serif'] = ['SimHei']  # 选择中文字体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 创建画布和坐标轴
_, axes = plt.subplots(1, 2)
# 函数图像
x = torch.linspace(-20, 20, 1000)
y = torch.relu(x)
axes[0].plot(x, y)
axes[0].grid()
axes[0].set_title('ReLU函数图像')
# 导数图像
x = torch.linspace(-20, 20, 1000, requires_grad=True)
torch.relu(x).sum().backward()
axes[1].plot(x.detach(), x.grad)
axes[1].grid()
axes[1].set_title('ReLU导数图像')
plt.show()

1.2.4 softmax

常用的激活函数-SoftMax 激活函数:

  • 多分类输出层

  • 将输出层的加权和(scores/logits)转换概率值,概率值之和是1

  • 选择概率最大的作为结果

  • 多分类的目标值:类别标注的热编码结果

softmax用于多分类过程中,它是二分类函数sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来 。计算方法如下图所示:

Softmax 就是将网络输出的 logits 通过 softmax 函数,就映射成为(0,1)的值,而这些值的累和为1(满足概率的性质),那么我们将它理解成概率,选取概率最大(也就是值对应最大的)节,作为我们的预测目标类别

1.2.5 其他激活函数

1.2.6 选择激活函数

对于隐藏层:

1. 优先选择ReLU激活函数

2. 如果ReLu效果不好,那么尝试其他激活,如Leaky ReLu等。

3. 如果你使用了ReLU, 需要注意一下Dead ReLU问题, 避免出现大的梯度从而导致过多的神经元死亡。

4. 少用使用sigmoid激活函数,可以尝试使用tanh激活函数

对于输出层:

1. 二分类问题选择sigmoid激活函数

2. 多分类问题选择softmax激活函数

3. 回归问题选择identity激活函数

1.3 参数初始化

①均匀分布初始化(对weight)

        权重参数初始化从区间均匀随机取值。即在(-1/根号d,1/根号d)均匀分布中生成当前神经元的权重,其中d为每个神经元的输入数量

    linear = nn.Linear(5, 3)#(in_features,out_features)
    # 从0-1均匀分布产生参数
    nn.init.uniform_(linear.weight)
    print(linear.weight.data)

②正态分布初始化(对weight)

        随机初始化从均值为0,标准差是1的高斯分布中取样,使用一些很小的值对参数W进行初始化

    linear = nn.Linear(5, 3)
    nn.init.normal_(linear.weight, mean=0, std=1)
    print(linear.weight.data)

0初始化(对bias)

        将神经网络中的所有权重参数初始化为0

    linear = nn.Linear(5, 3)
    nn.init.zeros_(linear.weight)
    print(linear.weight.data)

1初始化(对bias)

       将神经网络中的所有权重参数初始化为1

    linear = nn.Linear(5, 3)
    nn.init.ones_(linear.weight)
    print(linear.weight.data)

固定值初始化(对bais)

        将神经网络中的所有权重参数初始化为某个固定值

    linear = nn.Linear(5, 3)
    nn.init.constant_(linear.weight, 5)
    print(linear.weight.data)

⑥kaiming 初始化,也叫做 HE 初始化

         HE 初始化分为正态分布的 HE 初始化、均匀分布的 HE 初始化.

                --正态化的he初始化

                        stddev = sqrt(2 / fan_in)

    linear = nn.Linear(5, 3)
    nn.init.kaiming_normal_(linear.weight)
    print('kaiming正态分布:',linear.weight.data)

                 --均匀分布的he初始化

                         它从 [-limit,limit] 中的均匀分布中抽取样本, limitsqrt(6 / fan_in)

    linear = nn.Linear(5, 3)
    nn.init.kaiming_uniform_(linear.weight)
    print('kaiming均匀分布:',linear.weight.data)

                --fan_in 输入神经元的个数

⑦xavier 初始化,也叫做 Glorot初始化

        该方法也有两种,一种是正态分布的 xavier 初始化、一种是均匀分布的 xavier 初始化.

                --正态化的Xavier初始化

                        stddev = sqrt(2 / (fan_in + fan_out))

    linear = nn.Linear(5, 3)
    nn.init.xavier_normal_(linear.weight)
    print('xavier正态分布:',linear.weight.data)

                --均匀分布的Xavier初始化

                         [-limit,limit] 中的均匀分布中抽取样本, limit sqrt(6 / (fan_in + fan_out))

    linear = nn.Linear(5, 3)
    nn.init.xavier_uniform_(linear.weight)
    print('xavier均匀分布:',linear.weight.data)

                --fan_in 是输入神经元的个数, fan_out 是输出的神经元个数

总结:

1.4 模型构建

在pytorch中定义深度神经网络其实就是层堆叠的过程,继承自nn.Module,实现两个方法:

① __init__方法中定义网络中的层结构,主要是全连接层,并进行初始化

② forward方法,在实例化模型的时候,底层会自动调用该函数。该函数中可以定义学习率,

为初始化定义的layer传入数据等。

编码设计:

1.第一个隐藏层:权重初始化采用标准化的xavier初始化激活函数使用sigmoid

2.第二个隐藏层:权重初始化采用标准化的He初始化激活函数采用relu

3.out输出层线性层,假若二分类,采用softmax做数据归一化

'''
神经网络搭建流程
一个继承--继承自nn.moudle
两个方法 --__init__方法 网络层
        --forward方法  串联网络层
'''



import torch
import torch.nn as nn
from torchsummary import summary # 计算模型参数,查看模型结构, pip install torchsummary
# 创建神经网络模型类
class Model(nn.Module):
    # 初始化属性值
    def __init__(self):
        super(Model, self).__init__() # 调用父类的初始化属性值
        self.linear1 = nn.Linear(3, 3) # 创建第一个隐藏层模型, 3个输入特征,3个输出特征
        nn.init.xavier_normal_(self.linear1.weight) # 初始化权
        # 创建第二个隐藏层模型, 3个输入特征(上一层的输出特征),2个输出特征
        self.linear2 = nn.Linear(3, 2)
        # 初始化权重
        nn.init.kaiming_normal_(self.linear2.weight)
        # 创建输出层模型
        self.out = nn.Linear(2, 2)
    # 创建前向传播方法,自动执行forward()方法
    def forward(self, x):
        # 数据经过第一个线性层
        x = self.linear1(x)
        # 使用sigmoid激活函数
        x = torch.sigmoid(x)
        # 数据经过第二个线性层
        x = self.linear2(x)
        # 使用relu激活函数
        x = torch.relu(x)
        # 数据经过输出层
        x = self.out(x)
        # 使用softmax激活函数
        # dim=-1:每一维度行数据相加为1
        x = torch.softmax(x, dim=-1)
        return x
if __name__ == "__main__":
    # 实例化model对象
    my_model = Model()
    # 随机产生数据
    my_data = torch.randn(5, 3)
    print("mydata shape", my_data.shape)
    # 数据经过神经网络模型训练
    output = my_model(my_data)
    print("output shape-->", output.shape)
    # 计算模型参数
    # 计算每层每个神经元的w和b个数总和
    summary(my_model, input_size=(3,), batch_size=5)
    # 查看模型参数
    print("======查看模型参数w和b======")
    for name, parameter in my_model.named_parameters():
        print(name, parameter)

二、损失函数

2.1 分类问题

2.1.1多分类(多分类交叉熵/softmax损失)

# 分类损失函数:交叉熵损失使用nn.CrossEntropyLoss()实现。nn.CrossEntropyLoss()=softmax + 损失计算
def test():
# 设置真实值: 可以是热编码后的结果也可以不进行热编码
# y_true = torch.tensor([[0, 1, 0], [0, 0, 1]], dtype=torch.float32)
# 注意的类型必须是64位整型数据
y_true = torch.tensor([1, 2], dtype=torch.int64)
y_pred = torch.tensor([[0.2, 0.6, 0.2], [0.1, 0.8, 0.1]], dtype=torch.float32)
# 实例化交叉熵损失
loss = nn.CrossEntropyLoss()
# 计算损失结果
my_loss = loss(y_pred, y_true).numpy()
print('loss:', my_loss)

2.1.2 二分类(二分类交叉熵/sigmoid损失)

def test2():
    # 1 设置真实值和预测值
    # 预测值    是sigmoid输出的结果
    y_pred = torch.tensor([0.6901, 0.5459, 0.2469], requires_grad=True)
    y_true = torch.tensor([0, 1, 0], dtype=torch.float32)
    # 2 实例化二分类交叉熵损失
    criterion = nn.BCELoss()
    # 3 计算损失
    my_loss = criterion(y_pred, y_true).detach().numpy()
    print('loss:', my_loss)

2.2 回归问题

2.2.1 MSE(L2 loss)

采用均方误差方式:

def test4():
    # 1 设置真实值和预测值
    y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)
    y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float32)
    # 2 实例MSE损失对象
    loss = nn.MSELoss()
    # 3 计算损失
    my_loss = loss(y_pred, y_true).detach().numpy()
    print('myloss:', my_loss)

2.2.2 MAE(L1 loss)

平均绝对值误差:

# 计算算inputs与target之差的绝对值
    def test3():
    # 1 设置真实值和预测值
    y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)
    y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float32)
    # 2 实例MAE损失对象
    loss = nn.L1Loss()
    # 3 计算损失
    my_loss = loss(y_pred, y_true).detach().numpy()
    print('loss:', my_loss)

2.2.3 Smooth L1

def test5():
    # 1 设置真实值和预测值
    y_true = torch.tensor([0, 3])
    y_pred = torch.tensor ([0.6, 0.4], requires_grad=True)
    # 2 示例损失对象
    loss = nn.SmoothL1Loss()
    # 3 计算损失
    my_loss = loss(y_pred, y_true).detach().numpy()
    print('loss:', my_loss)

三、优化方法

3.1 反向传播(BP算法)

什么是反向传播?

利用损失函数ERROR,从后往前,结合梯度下降法,依次求各个参数的偏导,并进行参数更新

什么是前向传播?

指的是数据输入的神经网络中,逐层向前传输,一直运算到输出层为止

反向传播(BP算法):

3.2 梯度下降的优化方法 

梯度下降优化算法中,可能会碰到以下情况:

1. 碰到平缓区域,梯度值较小,参数优化变慢

2. 碰到 “鞍点” ,梯度为 0,参数无法优化

3. 碰到局部最小值,参数不是最优

3.2.1 指数加权平均

指数移动加权平均则是参考各数值,并且各数值的权重都不同,距离越远的数字对平均数计算的贡献就越小(权重较小),距离越近则对平均数的计算贡献就越大(权重越大)。比如:明天气温怎么样,和昨天气温有很大关系,而和一个月前的气温关系就小一些。

计算公式可以用下面的式子来表示:

3.2.2 动量算法Momentum

梯度计算公式:Dt = β * St-1 + (1- β) * Wt

1. St-1 表示历史梯度移动加权平均值

2. Wt 表示当前时刻的梯度值

3. Dt 为当前时刻的指数加权平均梯度值

4. β 为权重系数

假设:权重 β 为 0.9,例如:

第一次梯度值:s1 = d1 = w1

第二次梯度值:d2=s2 = 0.9 * s1 + w2 * 0.1

第三次梯度值:d3=s3 = 0.9 * s2 + w3 * 0.1

第四次梯度值:d4=s4 = 0.9 * s3 + w4 * 0.1

梯度下降公式中梯度的计算,就不再是当前时刻 t 的梯度值,而是历史梯度值的指数移动加权平

均值。公式修改为:

W_t+1 = W_t - a * Dt

 3.2.3 AdaGrad

AdaGrad 通过对不同的参数分量使用不同的学习率,AdaGrad 的学习率总体会逐渐减小

其计算步骤如下:

1. 初始化学习率 α、初始化参数 θ、小常数 σ = 1e-6

2. 初始化梯度累积变量 s = 0

3. 从训练集中采样 m 个样本的小批量,计算梯度 g

4. 累积平方梯度 s = s + g g表示各个分量相乘

 3.2.4 RMSProp

RMSProp 优化算法是对 AdaGrad 的优化. 最主要的不同是,其使用指数移动加权平均梯度替换历史梯度的平方和。其计算过程如下:

1. 初始化学习率 α、初始化参数 θ、小常数 σ = 1e-6

2. 初始化参数 θ

3. 初始化梯度累计变量 s

4. 从训练集中采样 m 个样本的小批量,计算梯度 g

5. 使用指数移动平均累积历史梯度,公式如下:

3.2.5 Adam 

3.3 学习率衰减 

3.3.1 等间隔衰减

3.3.2 指定间隔衰减

3.3.3 指数衰减

四、正则化

4.1 Dropout正则化

4.2 批量归一化

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

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

相关文章

【Linux】Linux入门(2)常见指令

目录 Linux下的文件ls 指令 --- 展示目录pwd指令 --- 显示当前目录cd 指令 --- 改变工作目录touch指令 --- 创建普通文件stat指令 --- 查看文件属性mkdir指令 --- 创建目录rmdir指令 --- 删除目录rm指令 --- 同时删除文件或目录man指令 --- 访问帮助手册cp指令 复制文件或目录m…

202509读书笔记|《飞花令·山》——两岸猿声啼不住,轻舟已过万重山

202509读书笔记|《飞花令山》——两岸猿声啼不住&#xff0c;轻舟已过万重山 《飞花令山》素心落雪编著&#xff0c;飞花令得名于唐代诗人韩翃《寒食》中的名句“春城无处不飞花”&#xff0c;类似于行酒令&#xff0c;是文人们的一种雅致的娱乐活动。 一直都比较喜欢看诗词&a…

GRGDSPC;H-Gly-Arg-Gly-Asp-Ser-Pro-Cys-OH;是一种末端巯基化的细胞粘附肽;91575-26-7

【GRGDSPC 简介】 GRGDSPC 是一种含 7 个氨基酸的多肽&#xff0c;且末端巯基化的细胞粘附肽。化学结构 是H-GLY-ARG-GLY-ASP-SER-PRO-CYS-OH&#xff0c;氨基酸序列为甘氨酸-精氨酸-甘氨酸-天冬氨酸-丝氨酸-脯氨酸-半胱氨酸&#xff0c;C端为羟基&#xff0c;是一种末端巯基化…

抖音ip属地不准是什么原因?可以改吗

在数字化时代&#xff0c;社交媒体平台如抖音已成为人们日常生活的重要组成部分。随着各大平台对用户隐私和数据安全的日益重视&#xff0c;IP属地的显示功能应运而生。然而&#xff0c;不少抖音用户在使用过程中发现&#xff0c;显示的IP属地与实际位置存在偏差&#xff0c;这…

.Net Core微服务入门全纪录(四)——Ocelot-API网关(上)

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…

Zemax 中的二向色分束器和荧光波偏移

二向色分光镜是一种专用光学元件&#xff0c;用于根据光的波长将一束光分成两束独立的光。“二向色”是指该元件根据光的波长选择性地透射或反射光的性质。 在大多数情况下&#xff0c;二向色分束器由一种对不同波长的光具有不同折射率的材料制成。分束器的表面涂有一层薄膜&a…

DevUI 2024 年度运营报告:开源生态的成长足迹与未来蓝图

在当今数字化飞速发展的时代&#xff0c;开源已成为推动技术创新与协作的重要力量。DevUI 作为开源领域的重要一员&#xff0c;其发展历程与成果备受关注。值此之际&#xff0c;GitCode 精心整理了 DevUI 年度运营报告&#xff0c;为您全面呈现 DevUI 社区在过去一年里的开源之…

3 前端(中):JavaScript

文章目录 前言&#xff1a;JavaScript简介一、ECMAscript&#xff08;JavaScript基本语法&#xff09;1 JavaScript与html结合方式&#xff08;快速入门&#xff09;2 基本知识&#xff08;1&#xff09;JavaScript注释&#xff08;和Java注释一样&#xff09;&#xff08;2&am…

rocketmq基本架构

简介 Name server 负责broker注册、心跳&#xff0c;路由等功能&#xff0c;类似Kafka的ZKname server节点之间不互相通信&#xff0c;broker需要和所有name server进行通信。扩容name server需要重启broker&#xff0c;不然broker不会和name server建立连接producer和consum…

ToDesk设置临时密码和安全密码都可以当做连接密码使用

ToDesk 在各领域办公都已经是非常常见了 为了安全 ToDesk 设置了连接密码&#xff0c;想连接 需要输入远程码和连接密码 我们刚打开 系统默认给我们用的是临时密码&#xff0c;安全性确实很强 和定时Tokey一样&#xff0c;固定时间切换。 但是 如果我们要经常连接这个电脑&a…

mysql 系统学习1

Linux C/C 操作MySQL - Henkk - 博客园

事件委托,其他事件,电梯导航,固定导航

事件委托改造 tab 栏切换 tab栏切换&#xff1a;前边的案例是 for 循环遍历每个 li 注册鼠标进入事件&#xff0c;给添加了 active类的 a 删除掉 active类&#xff0c;然后给点击的 a 添加上 active类&#xff08;也就是将已经有的 active 类删除掉&#xff0c;为当前点击到的…

mongoose 支持https踩坑纪实

简述 mongoose是C编写的嵌入式web服务&#xff0c;它能够支持https协议&#xff0c;可以简单的部署&#xff0c;但要做到完美部署&#xff0c;不是那么容易。 部署方法 本人使用的是最新的7.16版&#xff0c;以前版本似乎是要通过修改 头文件中的 MG_ENABLE_SSL 宏定义&…

科研绘图系列:R语言绘制多种图形(multiple plots)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍加载R包数据下载导入数据数据预处理画图输出画图2画图3画图4画图5系统信息介绍 科研绘图系列:R语言绘制多种图形(multiple plots) 加载R包 library(tidyverse) library(RColo…

QT 使用QSqlTableModel对数据库进行创建,插入,显示

文章目录 效果图概述功能点代码分析初始数据插入数据数据显示 总结 效果图 概述 本案例用于对数据库中的数据进行显示等其他操作&#xff0c;其他表格筛选&#xff0c;过滤等功能可看此博客 框架&#xff1a;数据模型使用QSqlTableModel&#xff0c;视图使用QTableView&#x…

Vscode:问题解决办法 及 Tips 总结

Visual Studio Code&#xff08;简称VSCode&#xff09;是一个功能强大的开源代码编辑器&#xff0c;广泛用于各种编程语言和开发场景&#xff0c;本博客主要记录在使用 VSCode 进行verilog开发时遇到的问题及解决办法&#xff0c;使用过程中的技巧 文章目录 扩展安装失败调试配…

FANUC机器人系统镜像备份与恢复的具体步骤(图文)

FANUC机器人系统镜像备份与恢复的具体步骤(图文) 镜像备份: 如下图所示,进入文件—工具—切换设备,找到插入的U盘UT1, 如下图所示,进入U盘目录后,创建目录,这里目录名称为11, 如下图所示࿰

模块化架构与微服务架构,哪种更适合桌面软件开发?

前言 在现代软件开发中&#xff0c;架构设计扮演着至关重要的角色。两种常见的架构设计方法是模块化架构与微服务架构。它们各自有独特的优势和适用场景&#xff0c;尤其在C#桌面软件开发领域&#xff0c;模块化架构往往更加具有实践性。本文将对这两种架构进行对比&#xff0…

使用Flask和Pydantic实现参数验证

使用Flask和Pydantic实现参数验证 1 简介 Pydantic是一个用于数据验证和解析的 Python 库&#xff0c;版本2的性能有较大提升&#xff0c;很多框架使用Pydantic做数据校验。 # 官方参考文档 https://docs.pydantic.dev/latest/# Github地址 https://github.com/pydantic/pyd…

游戏引擎学习第81天

仓库:https://gitee.com/mrxiao_com/2d_game_2 或许我们应该尝试在地面上添加一些绘图 在这段时间的工作中&#xff0c;讨论了如何改进地面渲染的问题。虽然之前并没有专注于渲染部分&#xff0c;因为当时主要的工作重心不在这里&#xff0c;但在实现过程中&#xff0c;发现地…