CV09_深度学习模块之间的缝合教学(4)--调参

news2024/9/22 3:06:06

深度学习就像炼丹。炉子就是模型,火候就是那些参数,材料就是数据集。

1.1 参数有哪些

调参调参,参数到底是哪些参数?

1.网络相关的参数:(1)神经网络网络层

(2)隐藏层的神经元个数等

(3)卷积核的数量

(4)损失层函数的选择

2.数据预处理的相关参数:(1)batch normalization(2)等等

3.超参数:(1)激活函数(2)初始化(凯明初始化等)

(3)梯度下降(SGD、Adam)

(4)epoch (5)batch size

(6)学习率lr (7)衰减函数、正则化等

1.2 常见的情况及原因

1.通常是在网络训练的结果:(1)过拟合----样本数量太少了

(2)欠拟合----样本多但模型简单

(3)拟合,但是在上下浮动(震荡)

(4)恰好拟合

(5)模型不收敛

1.3 解决方法

(1)过拟合----数据增强、早停法、drop out、降低学习率、调整epoch

(2)欠拟合----加深层数、尽量用非线性的激活函数如relu

(3)拟合但震荡----降低数据增强的程度、学习率

(4)

(5)模型不收敛----数据集有问题、网络模型有问题

1.4 调参的过程

1.搭建网络模型

2.先用小样本进行尝试模型效果

3.根据小样本的效果,进行调参,包括分析损失。

1.5 代码(CPU训练)

# Author:SiZhen
# Create: 2024/7/14
# Description: 调参练习-以手写数字集为例

import  torch
import torch.nn as nn
import torchvision
import torch.utils
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
#设置超参数
from torch import optim
from torch.nn import init

batch_size = 64
hidden_size = 128
learning_rate = 0.001
num_epoch = 10

#将图片进行预处理转换成pytorch张量
transform = transforms.Compose([transforms.ToTensor(),
                                 transforms.Normalize((0.5,),(0.5,),)]) #mnist是单通道,所以括号内只有一个0.5

#下载训练集
train_set = torchvision.datasets.MNIST(root="./data",train=True,download=True,transform=transform)

#下载测试集
test_set = torchvision.datasets.MNIST(root="./data",train=False,download=True,transform=transform)

#加载数据集
train_loader= torch.utils.data.DataLoader(train_set,batch_size=batch_size,shuffle=True)

test_loader = torch.utils.data.DataLoader(test_set,batch_size=batch_size,shuffle=False)#测试不shuffle

input_size = 784 #mnist,28x28像素
num_classes = 10



class SEAttention(nn.Module):
    # 初始化SE模块,channel为通道数,reduction为降维比率
    def __init__(self, channel=1, reduction=8):
        super().__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)  # 自适应平均池化层,将特征图的空间维度压缩为1x1
        self.fc = nn.Sequential(  # 定义两个全连接层作为激励操作,通过降维和升维调整通道重要性
            nn.Linear(channel, channel // reduction, bias=False),  # 降维,减少参数数量和计算量
            nn.ReLU(inplace=True),  # ReLU激活函数,引入非线性
            nn.Linear(channel // reduction, channel, bias=False),  # 升维,恢复到原始通道数

            nn.Sigmoid(),  # Sigmoid激活函数,输出每个通道的重要性系数
        )

    # 权重初始化方法
    def init_weights(self):
        for m in self.modules():  # 遍历模块中的所有子模块
            if isinstance(m, nn.Conv2d):  # 对于卷积层
                init.kaiming_normal_(m.weight, mode='fan_out')  # 使用Kaiming初始化方法初始化权重
                if m.bias is not None:
                    init.constant_(m.bias, 0)  # 如果有偏置项,则初始化为0
            elif isinstance(m, nn.BatchNorm2d):  # 对于批归一化层
                init.constant_(m.weight, 1)  # 权重初始化为1
                init.constant_(m.bias, 0)  # 偏置初始化为0
            elif isinstance(m, nn.Linear):  # 对于全连接层
                init.normal_(m.weight, std=0.001)  # 权重使用正态分布初始化
                if m.bias is not None:
                    init.constant_(m.bias, 0)  # 偏置初始化为0

    # 前向传播方法
    def forward(self, x):
        b, c, _, _ = x.size()  # 获取输入x的批量大小b和通道数c
        y = self.avg_pool(x).view(b, c)  # 通过自适应平均池化层后,调整形状以匹配全连接层的输入
        y = self.fc(y).view(b, c, 1, 1)  # 通过全连接层计算通道重要性,调整形状以匹配原始特征图的形状
        return x * y.expand_as(x)  # 将通道重要性系数应用到原始特征图上,进行特征重新校准
import torch
import torch.nn as nn
from torch.nn import Softmax

# 定义一个无限小的矩阵,用于在注意力矩阵中屏蔽特定位置
def INF(B, H, W):
    return -torch.diag(torch.tensor(float("inf")).repeat(H), 0).unsqueeze(0).repeat(B * W, 1, 1)

class CrissCrossAttention(nn.Module):
    """ Criss-Cross Attention Module"""
    def __init__(self, in_dim):
        super(CrissCrossAttention, self).__init__()
        # Q, K, V转换层
        self.query_conv = nn.Conv2d(in_channels=in_dim, out_channels=in_dim // 8, kernel_size=1)
        self.key_conv = nn.Conv2d(in_channels=in_dim, out_channels=in_dim // 8, kernel_size=1)
        self.value_conv = nn.Conv2d(in_channels=in_dim, out_channels=in_dim, kernel_size=1)
        # 使用softmax对注意力分数进行归一化
        self.softmax = Softmax(dim=3)
        self.INF = INF
        # 学习一个缩放参数,用于调节注意力的影响
        self.gamma = nn.Parameter(torch.zeros(1))

    def forward(self, x):
        m_batchsize, _, height, width = x.size()
        # 计算查询(Q)、键(K)、值(V)矩阵
        proj_query = self.query_conv(x)
        proj_query_H = proj_query.permute(0, 3, 1, 2).contiguous().view(m_batchsize * width, -1, height).permute(0, 2, 1)
        proj_query_W = proj_query.permute(0, 2, 1, 3).contiguous().view(m_batchsize * height, -1, width).permute(0, 2, 1)

        proj_key = self.key_conv(x)
        proj_key_H = proj_key.permute(0, 3, 1, 2).contiguous().view(m_batchsize * width, -1, height)
        proj_key_W = proj_key.permute(0, 2, 1, 3).contiguous().view(m_batchsize * height, -1, width)

        proj_value = self.value_conv(x)
        proj_value_H = proj_value.permute(0, 3, 1, 2).contiguous().view(m_batchsize * width, -1, height)
        proj_value_W = proj_value.permute(0, 2, 1, 3).contiguous().view(m_batchsize * height, -1, width)

        # 计算垂直和水平方向上的注意力分数,并应用无穷小掩码屏蔽自注意
        energy_H = (torch.bmm(proj_query_H, proj_key_H) + self.INF(m_batchsize, height, width)).view(m_batchsize, width, height, height).permute(0, 2, 1, 3)
        energy_W = torch.bmm(proj_query_W, proj_key_W).view(m_batchsize, height, width, width)

        # 在垂直和水平方向上应用softmax归一化
        concate = self.softmax(torch.cat([energy_H, energy_W], 3))

        # 分离垂直和水平方向上的注意力,应用到值(V)矩阵上
        att_H = concate[:, :, :, 0:height].permute(0, 2, 1, 3).contiguous().view(m_batchsize * width, height, height)
        att_W = concate[:, :, :, height:height + width].contiguous().view(m_batchsize * height, width, width)

        # 计算最终的输出,加上输入x以应用残差连接
        out_H = torch.bmm(proj_value_H, att_H.permute(0, 2, 1)).view(m_batchsize, width, -1, height).permute(0, 2, 3, 1)
        out_W = torch.bmm(proj_value_W, att_W.permute(0, 2, 1)).view(m_batchsize, height, -1, width).permute(0, 2, 1, 3)

        return self.gamma * (out_H + out_W) + x


class Net(nn.Module):
    def __init__(self, input_size, hidden_size, num_classes):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, num_classes)
        self.conv1 =nn.Conv2d(1,64,kernel_size=1)
        self.se = SEAttention(channel=1)
        self.cca = CrissCrossAttention(64)
        self.conv2 = nn.Conv2d(64,1,kernel_size=1)
    def forward(self, x):
        x = self.se(x)
        x = self.conv1(x)
        x = self.cca(x)
        x = self.conv2(x)

        out = self.fc1(x.view(-1, input_size))
        out = self.relu(out)
        out = self.fc2(out)
        return out


model = Net(input_size,hidden_size,num_classes)
criterion = nn.CrossEntropyLoss()

optimizer = optim.Adam(model.parameters(),lr=learning_rate)

train_loss_list = []
test_loss_list = []

#训练
total_step = len(train_loader)
for epoch in range(num_epoch):
    for i,(images,labels) in enumerate(train_loader):
        outputs = model(images) #获取模型分类后的结果
        loss = criterion(outputs,labels) #计算损失
        optimizer.zero_grad() #反向传播前,梯度清零
        loss.backward() #反向传播

        optimizer.step() #更新参数
        train_loss_list.append(loss.item())

        if (i+1)%100 ==0:
            print('Epoch[{}/{}],Step[{}/{}],Train Loss:{:.4f}'
                  .format(epoch+1,num_epoch,i+1,total_step,loss.item()))


    model.eval()

    with torch.no_grad(): #禁止梯度计算
        test_loss = 0.0
        for images,labels in test_loader:
            outputs = model(images)
            loss = criterion(outputs,labels)

            test_loss +=loss.item()*images.size(0) #累加每个批次总损失得到总损失

        test_loss /=len(test_loader.dataset) #整个测试集的平均损失

        # 将计算得到的单个平均测试损失值扩展到一个列表中,长度为total_step
        # 这样做可能是为了在绘图时每个step都有一个对应的测试损失值,尽管实际测试损失在整个epoch内是恒定的
        test_loss_list.extend([test_loss]*total_step) #方便可视化

    model.train()
    print("Epoch[{}/{}],Test Loss:{:.4f}".format(epoch+1,num_epoch,test_loss))


plt.plot(train_loss_list,label='Train Loss')
plt.plot(test_loss_list,label='Test Loss')
plt.title('model loss')
plt.xlabel('iterations')
plt.ylabel('Loss')
plt.legend()
plt.show()




1.6 代码(GPU训练)

要想模型在GPU上训练,需要两点:

(1)模型在GPU上

(2)所有参与运算的张量在GPU上

# Author:SiZhen
# Create: 2024/7/14
# Description: 调参练习-以手写数字集为例

import  torch
import torch.nn as nn
import torchvision
import torch.utils
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
#设置超参数
from torch import optim
from torch.nn import init

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

batch_size = 64
hidden_size = 128
learning_rate = 0.001
num_epoch = 10

#将图片进行预处理转换成pytorch张量
transform = transforms.Compose([transforms.ToTensor(),
                                 transforms.Normalize((0.5,),(0.5,),)]) #mnist是单通道,所以括号内只有一个0.5

#下载训练集
train_set = torchvision.datasets.MNIST(root="./data",train=True,download=True,transform=transform)

#下载测试集
test_set = torchvision.datasets.MNIST(root="./data",train=False,download=True,transform=transform)

#加载数据集
train_loader= torch.utils.data.DataLoader(train_set,batch_size=batch_size,shuffle=True,pin_memory=True)

test_loader = torch.utils.data.DataLoader(test_set,batch_size=batch_size,shuffle=False,pin_memory=True)#测试不shuffle

input_size = 784 #mnist,28x28像素
num_classes = 10



class SEAttention(nn.Module):
    # 初始化SE模块,channel为通道数,reduction为降维比率
    def __init__(self, channel=1, reduction=8):
        super().__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)  # 自适应平均池化层,将特征图的空间维度压缩为1x1
        self.fc = nn.Sequential(  # 定义两个全连接层作为激励操作,通过降维和升维调整通道重要性
            nn.Linear(channel, channel // reduction, bias=False),  # 降维,减少参数数量和计算量
            nn.ReLU(inplace=True),  # ReLU激活函数,引入非线性
            nn.Linear(channel // reduction, channel, bias=False),  # 升维,恢复到原始通道数

            nn.Sigmoid(),  # Sigmoid激活函数,输出每个通道的重要性系数
        )

    # 权重初始化方法
    def init_weights(self):
        for m in self.modules():  # 遍历模块中的所有子模块
            if isinstance(m, nn.Conv2d):  # 对于卷积层
                init.kaiming_normal_(m.weight, mode='fan_out')  # 使用Kaiming初始化方法初始化权重
                if m.bias is not None:
                    init.constant_(m.bias, 0)  # 如果有偏置项,则初始化为0
            elif isinstance(m, nn.BatchNorm2d):  # 对于批归一化层
                init.constant_(m.weight, 1)  # 权重初始化为1
                init.constant_(m.bias, 0)  # 偏置初始化为0
            elif isinstance(m, nn.Linear):  # 对于全连接层
                init.normal_(m.weight, std=0.001)  # 权重使用正态分布初始化
                if m.bias is not None:
                    init.constant_(m.bias, 0)  # 偏置初始化为0

    # 前向传播方法
    def forward(self, x):
        b, c, _, _ = x.size()  # 获取输入x的批量大小b和通道数c
        y = self.avg_pool(x).view(b, c)  # 通过自适应平均池化层后,调整形状以匹配全连接层的输入
        y = self.fc(y).view(b, c, 1, 1)  # 通过全连接层计算通道重要性,调整形状以匹配原始特征图的形状
        return x * y.expand_as(x)  # 将通道重要性系数应用到原始特征图上,进行特征重新校准
import torch
import torch.nn as nn
from torch.nn import Softmax

# 定义一个无限小的矩阵,用于在注意力矩阵中屏蔽特定位置
def INF(B, H, W):
    return -torch.diag(torch.tensor(float("inf")).repeat(H), 0).unsqueeze(0).repeat(B * W, 1, 1)

class CrissCrossAttention(nn.Module):
    """ Criss-Cross Attention Module"""
    def __init__(self, in_dim):
        super(CrissCrossAttention, self).__init__()
        # Q, K, V转换层
        self.query_conv = nn.Conv2d(in_channels=in_dim, out_channels=in_dim // 8, kernel_size=1)
        self.key_conv = nn.Conv2d(in_channels=in_dim, out_channels=in_dim // 8, kernel_size=1)
        self.value_conv = nn.Conv2d(in_channels=in_dim, out_channels=in_dim, kernel_size=1)
        # 使用softmax对注意力分数进行归一化
        self.softmax = Softmax(dim=3)
        self.INF = INF
        # 学习一个缩放参数,用于调节注意力的影响
        self.gamma = nn.Parameter(torch.zeros(1))

    def forward(self, x):
        m_batchsize, _, height, width = x.size()
        # 计算查询(Q)、键(K)、值(V)矩阵
        proj_query = self.query_conv(x)
        proj_query_H = proj_query.permute(0, 3, 1, 2).contiguous().view(m_batchsize * width, -1, height).permute(0, 2, 1)
        proj_query_W = proj_query.permute(0, 2, 1, 3).contiguous().view(m_batchsize * height, -1, width).permute(0, 2, 1)

        proj_key = self.key_conv(x)
        proj_key_H = proj_key.permute(0, 3, 1, 2).contiguous().view(m_batchsize * width, -1, height)
        proj_key_W = proj_key.permute(0, 2, 1, 3).contiguous().view(m_batchsize * height, -1, width)

        proj_value = self.value_conv(x)
        proj_value_H = proj_value.permute(0, 3, 1, 2).contiguous().view(m_batchsize * width, -1, height)
        proj_value_W = proj_value.permute(0, 2, 1, 3).contiguous().view(m_batchsize * height, -1, width)

        # 计算垂直和水平方向上的注意力分数,并应用无穷小掩码屏蔽自注意
        energy_H = (torch.bmm(proj_query_H, proj_key_H)+ self.INF(m_batchsize, height, width).to(device)).view(m_batchsize, width, height, height).permute(0, 2, 1, 3).to(device)
        energy_W = torch.bmm(proj_query_W, proj_key_W).view(m_batchsize, height, width, width)

        # 在垂直和水平方向上应用softmax归一化
        concate = self.softmax(torch.cat([energy_H, energy_W], 3))

        # 分离垂直和水平方向上的注意力,应用到值(V)矩阵上
        att_H = concate[:, :, :, 0:height].permute(0, 2, 1, 3).contiguous().view(m_batchsize * width, height, height)
        att_W = concate[:, :, :, height:height + width].contiguous().view(m_batchsize * height, width, width)

        # 计算最终的输出,加上输入x以应用残差连接
        out_H = torch.bmm(proj_value_H, att_H.permute(0, 2, 1)).view(m_batchsize, width, -1, height).permute(0, 2, 3, 1)
        out_W = torch.bmm(proj_value_W, att_W.permute(0, 2, 1)).view(m_batchsize, height, -1, width).permute(0, 2, 1, 3)

        return self.gamma * (out_H + out_W) + x


class Net(nn.Module):
    def __init__(self, input_size, hidden_size, num_classes):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(input_size, hidden_size)
        self.relu = nn.ReLU()
        self.fc2 = nn.Linear(hidden_size, num_classes)
        self.conv1 =nn.Conv2d(1,64,kernel_size=1)
        self.se = SEAttention(channel=1)
        self.cca = CrissCrossAttention(64)
        self.conv2 = nn.Conv2d(64,1,kernel_size=1)
    def forward(self, x):
        x = self.se(x)
        x = self.conv1(x)
        x = self.cca(x)
        x = self.conv2(x)

        out = self.fc1(x.view(-1, input_size))
        out = self.relu(out)
        out = self.fc2(out)
        return out


model = Net(input_size,hidden_size,num_classes)

model.to(device)

criterion = nn.CrossEntropyLoss().to(device)

optimizer = optim.Adam(model.parameters(),lr=learning_rate)
train_loss_list = []
test_loss_list = []

#训练
total_step = len(train_loader)
for epoch in range(num_epoch):
    for i,(images,labels) in enumerate(train_loader):

        images,labels = images.to(device),labels.to(device)

        outputs = model(images).to(device) #获取模型分类后的结果
        loss = criterion(outputs,labels).to(device) #计算损失
        optimizer.zero_grad() #反向传播前,梯度清零
        loss.backward() #反向传播

        optimizer.step() #更新参数
        train_loss_list.append(loss.item())

        if (i+1)%100 ==0:
            print('Epoch[{}/{}],Step[{}/{}],Train Loss:{:.4f}'
                  .format(epoch+1,num_epoch,i+1,total_step,loss.item()))


    model.eval()

    with torch.no_grad(): #禁止梯度计算
        test_loss = 0.0
        for images,labels in test_loader:

            images, labels = images.to(device), labels.to(device)

            outputs = model(images).to(device)
            loss = criterion(outputs,labels).to(device)

            test_loss +=loss.item()*images.size(0) #累加每个批次总损失得到总损失

        test_loss /=len(test_loader.dataset) #整个测试集的平均损失

        # 将计算得到的单个平均测试损失值扩展到一个列表中,长度为total_step
        # 这样做可能是为了在绘图时每个step都有一个对应的测试损失值,尽管实际测试损失在整个epoch内是恒定的
        test_loss_list.extend([test_loss]*total_step) #方便可视化

    model.train()
    print("Epoch[{}/{}],Test Loss:{:.4f}".format(epoch+1,num_epoch,test_loss))


plt.plot(train_loss_list,label='Train Loss')
plt.plot(test_loss_list,label='Test Loss')
plt.title('model loss')
plt.xlabel('iterations')
plt.ylabel('Loss')
plt.legend()
plt.show()




1.7 调参对比

可以看到,该模型原始状态下损失值已经非常小了。

现在我把隐藏层神经元数量从原来的128改为256,学习率进一步减小为0.0005,我们看一下效果:

效果略微提升,但是我们可以看到在后面测试集的表现产生了一些波动,没有之前的模型稳定。

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

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

相关文章

偶数位的数c++

题目描述 给你两个整数 l,r,求 l∼r 范围内有多少个位数为偶数的数。 输入 一行两个整数 l,r。 输出 输出位数为偶数的数的数量。 样例输入 5 15样例输出 6 提示 样例解释 10,11,12,13,14,15 位数为偶数,都是两位数。 数据规模与约定 对于 1…

过滤器、监听器、拦截器

目录 一、 主要内容 二、 过滤器 2.1 介绍 2.2 实现 MyFilter01 MyFilter02 MyServlet01 MyServlet02 2.3 说明 2.4 执行顺序 1. 使用 web.xml 2. 使用注解和Order 3. 使用FilterRegistrationBean 2.5字符乱码 三、监听器 3.1介绍 3.2实现 3.3在线人数统计 O…

克洛托光电再度合作福晶科技,高精度光学镜头装调仪正式交付

近日,苏州东方克洛托光电技术有限公司(下称“克洛托光电”)高精度光学镜头装调仪正式交付于福建福晶科技股份有限公司,研发人员在现场完成设备安装调试并介绍使用方法。据悉,这已是双方第二次展开合作。 前沿产品力助推…

企业知识库用不起来?试一下用HelpLook同步钉钉组织架构

提升企业管理和协同效率已成为增强竞争力的关键。企业通过知识管理,搭建内部知识库,将分散的经验和知识转化为系统化流程,减少重复解释,促进业务高效运作。这为企业提供了坚实的基础。 企业知识库面临的挑战 尽管传统知识库内容丰…

银河麒麟高级服务器操作系统V10加固操作指南

1:检查系统openssh安全配置: 2:检查是否设置口令过期前警告天数: 3:检查账户认证失败次数限制: 修改/etc/pam.d/system-auth文件中deny的参数即可 4:检查是否配置SSH方式账户认证失败次数限制:

github相关命令

如果我们要从 GitHub 上拉取一个项目到本地,进行修改并上传回去,通常需要以下步骤: 1. 克隆远程仓库到本地 使用 git clone 命令将 GitHub 上的项目克隆到本地: (网址示例如下所示) git clone https://github.com/你的…

多旋翼无人机挂载多功能抛投器技术详解

多旋翼无人机,作为一种具有高效、灵活、稳定等特性的无人驾驶飞行器,在现代社会的多个领域得到了广泛应用。其中,挂载多功能抛投器技术,使得无人机在物资投送、救援等任务中发挥出更加重要的作用。以下将详细介绍多旋翼无人机挂载…

正则表达式怎么控制匹配的字符串更近的一个

http((?!http).)*m3u8 正则表达式怎么控制匹配的字符串更近的一个 正则如何匹配最近的字符 正则如何匹配最近的两个字符 怎么控制只要离字符串b匹配更近一点的字符串a 解释 a.b,它将会匹配最长的以a开始,以b结束的字符串 a.?b匹配最短的&#xff…

测试开发面经总结(三)

TCP三次握手 TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手来进行的。 一开始,客户端和服务端都处于 CLOSE 状态。先是服务端主动监听某个端口,处于 LISTEN 状态 客户端会随机初始化序号&…

微信小程序密码 显示隐藏 真机兼容问题

之前使用type来控制&#xff0c;发现不行&#xff0c;修改为password属性即可 <van-fieldright-icon"{{passwordType password? closed-eye:eye-o}}"model:value"{{ password }}"password"{{passwordType password ? true: false}}"borde…

数仓工具—Hive语法之排除特定列

排除特定列 Apache Hive是一个基于Hadoop HDFS的数据仓库框架,用于存储和分析大量数据。Apache Hive支持大多数关系数据库功能,如对大型表进行分区和根据分区列存储值。 在本文中,我们将检查从SELECT查询中排除Hive分区列的方法。 这个在我们需要表中大量列的时候,例如一…

【python】OpenCV—European Article Number

参考学习来自&#xff1a;OpenCV基础&#xff08;25&#xff09;条码和二维码扫的生成与识别 1 条形码介绍 EAN-13是欧洲物品编码&#xff08;European Article Number&#xff09;的缩写&#xff0c;是一种广泛使用的条形码标准&#xff0c;特别是在超级市场和其它零售业中。…

第二周周日学习总结

题目总结 1. 给你一个仅由数字组成的字符串 s&#xff0c;在最多交换一次 相邻 且具有相同 奇偶性 的数字后&#xff0c;返回可以得到的 字典序最小的字符串 。 如果两个数字都是奇数或都是偶数&#xff0c;则它们具有相同的奇偶性。例如&#xff0c;5 和 9、2 和 4 奇偶性…

zookeeper基础知识学习

官网&#xff1a;Apache ZooKeeper 下载地址&#xff1a;Index of /dist/zookeeper/zookeeper-3.5.7Index of /dist/zookeeperIndex of /dist/zookeeper/zookeeper-3.5.7 ZK配置参数说明&#xff1a; 1、tickTime2000&#xff1a;通讯心跳时间&#xff0c;zookeeper服务器与客…

Reinforced Causal Explainer for GNN论文笔记

论文&#xff1a;TPAMI 2023 图神经网络的强化因果解释器 论文代码地址&#xff1a;代码 目录 Abstract Introduction PRELIMINARIES Causal Attribution of a Holistic Subgraph​ individual causal effect (ICE)​ *Causal Screening of an Edge Sequence Reinforc…

Three.js 对创建的物体进行位置旋转缩放修改。

1.在场景里面添加一个物体作为示例 // 创建一个物体&#xff08;形状&#xff09;const geometry new THREE.BoxGeometry(5, 5, 5);//创建材质&#xff08;外观&#xff09;const material2 new THREE.MeshLambertMaterial({color: 0xfff, //设置材质颜色side: THREE.DoubleS…

SpringBoot + vue 管理系统

SpringBoot vue 管理系统 文章目录 SpringBoot vue 管理系统1、成品效果展示2、项目准备3、项目开发3.1、部门管理3.1.1、前端核心代码3.1.2、后端代码实现 3.2、员工管理3.2.1、前端核心代码3.2.2、后端代码实现 3.3、班级管理3.3.1、前端核心代码3.3.2、后端代码实现 3.4、…

Matlab 计算一个平面与一条直线的交点

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这里使用一种很有趣的坐标:Plucker线坐标,它的定义如下所示: 这个坐标有个很有趣的性质,将直线 L L L与由其齐次坐标 V = (

STM32的定时器HAL库

目录 一&#xff0c;定时器的介绍 一&#xff0c;定时器的介绍 1. STM32F103C8T6微控制器内部集成了多种类型的定时器&#xff0c;这些定时器在嵌入式系统中扮演着重要角色&#xff0c;用于计时、延时、事件触发以及PWM波形生成、脉冲捕获等应用。 1.1 高级定时器&…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(六)-人工智能控制的自主无人机用例

引言 本文是3GPP TR 22.829 V17.1.0技术报告&#xff0c;专注于无人机&#xff08;UAV&#xff09;在3GPP系统中的增强支持。文章提出了多个无人机应用场景&#xff0c;分析了相应的能力要求&#xff0c;并建议了新的服务级别要求和关键性能指标&#xff08;KPIs&#xff09;。…