pytorch文本分类(三)模型框架(DNNtextCNN)

news2024/11/25 14:47:07

pytorch文本分类(三)模型框架(DNN&textCNN)

原任务链接

目录

  • pytorch文本分类(三)模型框架(DNN&textCNN)
    • 1. 背景知识
      • 深度学习
    • 2. DNN
      • 2.1 从感知器到神经网络
      • 2.2 DNN的基本结构
        • 2.2.1 前向传播算法
          • 激活函数
        • 2.2.2 反向传播算法
          • 损失函数
          • 梯度下降
          • 优化器
    • 3.CNN
      • 3.1CM
        • 卷积层
        • 池化层
        • 全连接层(输出层)
      • 3.2 TextCNN
    • 4. 作业

1. 背景知识

该训练营主要讲解深度学习的自然语言处理,在讲解模型框架之前,先补充一下深度学习的背景知识。

深度学习

深度学习是机器学习的一个分支。许多传统机器学习算法学习能力有限,数据量的增加并不能持续增加学到的知识总量,而深度学习系统可以通过访问更多数据来提升性能,即“更多经验”的机器代名词。机器通过深度学习获得足够经验后,即可用于特定的任务,如驾驶汽车、识别田地作物间的杂草、确诊疾病、检测机器故障等。

深度结构有着强大的非线性拟合能力,可以任意精度逼近任何非线性连续函数,来进行高纬度数据处理,同时配合着强大的特征提取能力,可以通过自动学习出数据中的“合理规则”。同时缺点在于模型过于黑盒,隐藏了许多可解释性,并且计算量高,需要高性能硬件,寻找的一般是数据间的相关性,模型无法检测出数据对背后的因果逻辑,因此对新鲜数据的适应性差。

2. DNN

深度神经网络(Deep Neural Networks, 以下简称DNN)是深度学习的基础。需要理解DNN,必需要知道DNN背后的模型。

2.1 从感知器到神经网络

抽象模拟脑电波在脑神经间的传递过程,以获得机器学习中最简单的神经网络——感知器。感知器的模型是有若干输入和一个输出的模型,然后探究输出和输入之间学习到一个线性关系,y = Σwx + b。因为脑神经中有个机制是抑制和激活状态,在线性关系之后可以加入一个激活参数,决定感知器的激活状态,使输出在 -1~1之间。单个感知器只能处理二元分类问题,而神经网络会在感知器上进行拓展,以完成更加复杂的任务。
Image Name如上图所示,x为输入,y为输出,w、b为线性参数,f为激活函数。

神经网络在横向和纵向维度对感知器进行拓展,比如添加隐藏层以纵向拓展其深度,增加输出结果以横向拓展宽度,丰富激活函数的种类以加强其非线性变换能力,增强神经网络的表达能力。在下面的图中,每一个圆圈表示一个感知器,有输入有输出也有激活函数,颜色深浅表示激活程度。
Image Name

2.2 DNN的基本结构

神经网络层可以分为三类,输入层,隐藏层和输出层,如上图示例。一般来说第一层是输入层,最后一层是输出层,而中间的层数都是隐藏层(注意输入层是没有w参数的)。

2.2.1 前向传播算法

假设选择的激活函数是Sigmoid函数,隐藏层和输出层的输出值为a ,则对于下图的三层DNN,利用和感知机一样的思路,我们可以利用上一层的输出计算下一层的输出,也就是所谓的DNN前向传播算法。使用代数法一个个的表示输出比较复杂,而如果使用矩阵法则比较的简洁。比如输入层有m个输入,后面接着的隐藏层有n个输出,使用一个w的矩阵[m×n],即可把m个输入转化为n个输出。然后利用若干个权重系数矩阵W,偏倚向量b来和输入值向量x进行一系列线性运算和激活运算,从输入层开始,一层层的向后计算,一直到运算到输出层,得到输出结果为值。

激活函数

激活函数是非线性函数,通过加入激活函数,使得感知器可以处理一些最基本的异或问题,甚至是更复杂的非线性问题。
常见的激活函数
sigmoid函数:
Image Name
其缺点如下:

  1. 当输入很大或很小,饱和的神经元会带来梯度消失(Gradient Vanishing);
  2. 函数的输出不是以0为对称的(zero-centered);
  3. 使用指数函数,计算代价有点高。

tanh函数
Image Name
与sigmoid函数相比,其解决了zero-centered的问题。但是,梯度消失与指数函数计算代价高的问题,仍然存在。

relu函数
Image Name
优点:

  1. 在输入空间的一半都不存在饱和问题;
  2. 收敛速度快;
    缺点:
  3. 输出不是以0为中心;
  4. Dead Relu Problem,指的是某些神经元可能永远不会被激活,导致相应的参数永远不会被更新(参数初始化问题或者参数更新太大);
  5. 在输入空间的另一半会存在梯度消失的问题。
2.2.2 反向传播算法

如果我们采用DNN的模型,即输入层m个神经元,输出层有n个神经元。再加上一些含有若干神经元的隐藏层。此时需要找到合适的所有隐藏层和输出层对应的线性系数矩阵W,偏倚向量b,让所有的训练样本输入计算出的输出尽可能的等于或很接近样本输出。怎么找到合适的参数呢?

可以用一个合适的损失函数来度量训练样本的输出损失,接着对这个损失函数进行优化求最小化的极值,对应的一系列线性系数矩阵W,偏倚向量b即为我们的最终结果。在DNN中,损失函数优化极值求解的过程最常见的一般是通过梯度下降法来一步步迭代完成的。

损失函数

损失函数用来评价模型的预测值和真实值的残差,损失函数越好,通常模型的性能越好。不同的模型用的损失函数一般也不一样。这里将常用的损失函数分为了两大类:回归和分类问题。然后又分别对这两类进行了细分和讲解,其中回归中包含了一种不太常见的损失函数:平均偏差误差,可以用来确定模型中存在正偏差还是负偏差。

回归问题处理的则是连续值的预测问题,例如给定房屋面积、房间数量以及房间大小,预测房屋价格。在分类任务中,我们要从类别值有限的数据集中预测输出,比如给定一个手写数字图像的大数据集,将其分为 0~9 中的一个。

在本次训练营中,我们关注的是文本分类问题,分类问题常用的损失函数是交叉熵(cross-entropy)。
在二分类场景下,模型最后需要预测的结果只有两种情况,对于每个类别我们的预测得到的概率为p和1-p,此时表达式为(log 的底数是 e):
Image Name
其中:
yi 表示样本 i 的label,正类为 1 ,负类为 0
pi 表示样本 i 预测为正类的概率

多分类的情况实际上就是对二分类的扩展:
Image Name
M类别的数量
yic 符号函数( 0 或 1 ),如果样本 i 的真实类别等于 c 取 1 ,否则取 0
pic 观测样本 i 属于类别 c 的预测概率

🌰例子:我们希望根据文本的特征,来预测情感的类别,有三种可预测类别:高兴、悲伤、愤怒。假设我们当前有一个模型,是通过softmax的方式得到对于每个预测结果的概率:

Image Name

通过刚刚的多分类计算公式得到loss值:
Image Name

梯度下降

在机器学习算法中,在最小化损失函数时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数,和模型参数值。
梯度下降法的思路很简单,想象在山顶放了一个球,一松手它就会顺着山坡最陡峭的地方滚落到谷底:

Image Name

从上面的解释可以看出,梯度下降不一定能够找到全局的最优解,有可能是一个局部最优解。当然,如果损失函数是凸函数,梯度下降法得到的解就一定是全局最优解。

而用数学公式来解释,首先要了解步长和导数对梯度下降的作用。拿一个凸函数f(x) = xˆ2举例,在这里斜率就是对损失函数的 x0 求的导数,具体的x0 的纵坐标是目前模型的loss值,步长是横坐标变化量。

Image Name

在凸函数上,随着一步步的迭代,斜率不断减小并趋近于0,因此被称为梯度下降法,并且当斜率趋近为0是,得到的loss值也是最小值。

优化器

优化器就是在深度学习反向传播过程中,指引损失函数(目标函数)的各个参数往正确的方向更新合适的大小,使得更新后的各个参数让损失函数(目标函数)值不断逼近全局最小。
常见的优化器有随机梯度下降法(Stochastic Gradient Descent,SGD)、Adam(自适应学习率算法)等。

随机梯度下降算法每次从训练集中随机选择一个样本来进行学习

#DNN样例代码
import torch.nn as nn
import torch
max_fid = 123

class Net(torch.nn.Module):
    def __init__(self, n_embed, n_feature, n_hidden, n_output):
        super(Net, self).__init__()
        self.embedding = nn.Embedding(max_fid + 1, n_feature)
        self.hidden = torch.nn.Linear(n_feature, n_hidden)   # hidden layer
        self.out = torch.nn.Linear(n_hidden, n_output)   # output layer

    def forward(self, fea_ids, fea_weights):
        embeds = self.embedding(fea_ids)
        embeds = emb_sum(embeds, fea_weights)
        embeds = nn.functional.tanh(embeds)
        hidden = self.hidden(embeds)
        output = self.out(hidden)

        return output


net = Net(n_embed = 32, n_feature= 32, n_hidden=10, n_output=2)     # define the network
print(net)
optimizer = torch.optim.SGD(net.parameters(), lr=0.02)
loss_func = nn.CrossEntropyLoss()  # the target label is NOT an one-hotted
Net(
  (embedding): Embedding(124, 32)
  (hidden): Linear(in_features=32, out_features=10, bias=True)
  (out): Linear(in_features=10, out_features=2, bias=True)
)


C:\Users\chengyuanting\.conda\envs\pytorch_cpu\lib\site-packages\tqdm\auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm

3.CNN

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习的代表算法之一。CNN有很强的表征学习能力,去学习结构化特征,一般应用于图像处理。想要了解卷积神经在计算机视觉中的应用请点击CNN教程进行进一步了解。

CNN和DNN的差别在于CNN的隐藏层还包括了卷积层和池化层,以及输出层改成了全连接FC层,在卷积层中使用局部感受野和权值共享的技术,这些技术都可以帮助降低模型复杂度,减少参数数量。

3.1CM

卷积层

卷积层对输入图像进行转换,以从中提取特征。 在这种转换中,图像与卷积核(或过滤器)卷积。

卷积计算
卷积核是一个小的矩阵,其高度和宽度小于要卷积的图像。 它也被称为卷积矩阵或卷积掩码。 该核在图像输入的高度和宽度上滑动,并且卷积核的点积和图像在每个空间位置处进行计算。 卷积核滑动的长度称为步幅长度。 在下面的图像中,输入图像的大小为5X5,卷积核的大小为3X3,步幅为1。输出图像也称为卷积特征。在下图中绿色部分为图像,黄色部分为卷积核,粉色部分为卷积特征。
Image Name
当我们想使用卷积从一个图像中提取多个特征时,我们可以使用多个卷积核而不是仅使用一个。 在这种情况下,所有卷积核的大小必须相同。 输入图像和输出图像的卷积特征一个接一个地堆叠在一起以创建输出,因此通道数等于使用的滤镜数。在下图中,通道数为3个。

激活层是卷积层的最后一个组成部分,可增加输出中的非线性。 通常,在卷积层中将ReLu函数或Tanh函数用作激活函数(在本次训练营,建议使用Tanh函数,因为Tanh函数在文本和音频处理有比较好的效果。)。 这是一个简单卷积层的图像,其中将6X6X3输入图像与大小为4X4X3的两个卷积核卷积以得到大小为3X3X2的卷积特征,对其应用激活函数以获取输出,这也称为特征地图。
Image Name

专有名词解释
针对CNN有一些专有名词,比如通道,卷积核大小,步长,填充和输入输出通道数进行解释。

通道,对于图像数据来说,一张彩色图片有R,G,B红绿蓝三通道,那么这里就可以说输入图像的通道数为3,假设这张图片为黑白照片,则通道数为2。

卷积核大小,在网络中代表感受野的大小,二维卷积核最常见的就是 3X3 的卷积核,也可以根据网络设计5X5或者7X7,甚至1X1等不同size的卷积核,来提取不同尺度的特征。在卷积神经网络中,一般情况下,卷积核越大,感受野(receptive field)越大,看到的图片信息越多,所获得的全局特征越好。虽说如此,但是大的卷积核会导致计算量的暴增,不利于模型深度的增加,计算性能也会降低。如上图中卷积核的size为3X3.

步长,即为卷积核每次计算时移动的距离。步长小,提取的特征更全面,不会遗漏太多信息,但计算量大,容易产生过拟合问题;步长大,计算量下降,但可能错失一些有用特征。

填充,卷积核与图像尺寸不匹配,往往填充图像缺失区域,如果原始图片尺寸为5X5,卷积核的大小为3X3,如果不进行填充,步长为1的话,当卷积核沿着图片滑动后只能滑动出一个3X3的图片出来,这就造成了卷积后的图片和卷积前的图片尺寸不一致,这显然不是我们想要的结果,所以为了避免这种情况,需要先对原始图片做边界填充处理。

输入和输出通道数(Input & Output Channels):卷积核的输入通道数(in depth)由输入矩阵的通道数所决定;输出矩阵的通道数(out depth)由卷积核的输出通道数所决定。每一层卷积有多少channel数,以及一共有多少层卷积,这些暂时没有理论支撑,一般都是靠感觉去设置几组候选值,然后通过实验挑选出其中的最佳值。这也是现在深度卷积神经网络虽然效果拔群,但是一直为人诟病的原因之一。

池化层

池化层也称为下采样,主要用于特征降维,压缩数据和参数数量,减小过拟合,提升模型容错率。 在卷积神经网络中,通常在卷积层,激活层之后是池化层。 通常添加池层以加快计算速度,并使某些检测到的功能更健壮。
池操作也使用卷积核和跨步。 在下面的示例图像中,使用2X2过滤器合并大小为4,跨度为2的4X4输入图像。
有不同类型的池。 最大池和平均池是卷积神经网络中最常用的池方法。
Image Name
最大池化:在最大池化中,从要素图的每个面片中选择最大值以创建缩小图,最大池化效果更好一点。
平均池化:在平均池化中,从要素图的每个面片中选择平均值以创建缩小图。

全连接层(输出层)

完全连接的层位于卷积神经网络的末端。 由较早层产生的特征图将展平为矢量。 然后,此向量被馈送到完全连接的层,以便它捕获高级要素之间的复杂关系。 该层的外面是一维特征向量,经由softmax函数得到最终的输出,整个模型训练完毕。

3.2 TextCNN

Yoon Kim在论文(2014 EMNLP) Convolutional Neural Networks for Sentence Classification提出TextCNN。将卷积神经网络CNN应用到文本分类任务,利用多个不同size的kernel来提取句子中的关键信息(类似于多窗口大小的n-gram),从而能够更好地捕捉局部相关性。

在下图的输入层“I like this movie very much ! ”的feature map长是7个单词(包括符号),宽是embedding的维度d=5,如果有两张feature map,可以理解为有两句话,也就是batch_size = 2。

然后通过长宽不等的卷积核,宽分别为[2, 3, 4]的卷积核映射不同size的卷积特征(见下图第二列),通过激活(第二列到第三列),池化(第三列到第四列)和全连接操作,最后进行分类预测。

由于每个单词的embedding dim(词向量长度)是固定的,每个卷积核的宽度也必须和单词的embedding dim 保持一致,只能改变卷积核的高度,卷积核的通道可以理解为用不同的词向量表示。

输入句子的长度不一样,但是卷积核的个数一样,由于每个卷积核抽取单词的个数不一样,卷积核高度低的形成的feature maps 长度就长,卷积核高度高的形成的feature maps长度就短。

Image Name

#TextCNN的样例代码 将上图模型用pytorch表示出来
import torch
import torch.nn as nn
import torch.nn.functional as F

class textCNN(nn.Module):
    def __init__(self,Vocab, class_num,kernel_sizes):
        super(textCNN, self).__init__()

        Dim = 5 #每个词向量长度
        Cla = class_num #类别数
        Ci = 1 #输入的channel数
        Ks = kernel_sizes # 卷积核list,形如[2,3,4]

        self.embed = nn.Embedding(Vocab,Dim) # 词向量,这里直接随机

        self.convs = nn.ModuleList([nn.Conv2d(Ci,100,(K,Dim)) for K in Ks]) # 卷积层
        self.dropout = nn.Dropout(p=0.5) 
        self.fc = nn.Linear(len(Ks)*100,Cla) #全连接层

    def forward(self,x):
        x = torch.tensor(x).to(torch.int64)
        x = self.embed(x) #(N,W,D)

        x = x.unsqueeze(1) #(N,Ci,W,D)
        x = [F.relu(conv(x)).squeeze(3) for conv in self.convs] # len(Ks)*(N,Knum,W)
        x = [F.max_pool1d(line,line.size(2)).squeeze(2) for line in x]  # len(Ks)*(N,Knum)

        x = torch.cat(x,1) #(N,Knum*len(Ks))

        x = self.dropout(x)
        logit = self.fc(x)
        return logit
net = textCNN(Vocab = 1000, class_num = 2, kernel_sizes =[2,3,4])
print(net)
textCNN(
  (embed): Embedding(1000, 5)
  (convs): ModuleList(
    (0): Conv2d(1, 100, kernel_size=(2, 5), stride=(1, 1))
    (1): Conv2d(1, 100, kernel_size=(3, 5), stride=(1, 1))
    (2): Conv2d(1, 100, kernel_size=(4, 5), stride=(1, 1))
  )
  (dropout): Dropout(p=0.5, inplace=False)
  (fc): Linear(in_features=300, out_features=2, bias=True)
)
!pip install torchinfo
import torchinfo
torchinfo.__version__
Defaulting to user installation because normal site-packages is not writeable
Requirement already satisfied: torchinfo in c:\users\chengyuanting\appdata\roaming\python\python39\site-packages (1.8.0)





'1.8.0'
from torchinfo import summary
batch_size = 64
summary(net, input_size=(batch_size, 1000))
C:\Users\chengyuanting\AppData\Local\Temp\ipykernel_17196\1359358780.py:22: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).
  x = torch.tensor(x).to(torch.int64)





==========================================================================================
Layer (type:depth-idx)                   Output Shape              Param #
==========================================================================================
textCNN                                  [64, 2]                   --
├─Embedding: 1-1                         [64, 1000, 5]             5,000
├─ModuleList: 1-2                        --                        --
│    └─Conv2d: 2-1                       [64, 100, 999, 1]         1,100
│    └─Conv2d: 2-2                       [64, 100, 998, 1]         1,600
│    └─Conv2d: 2-3                       [64, 100, 997, 1]         2,100
├─Dropout: 1-3                           [64, 300]                 --
├─Linear: 1-4                            [64, 2]                   602
==========================================================================================
Total params: 10,402
Trainable params: 10,402
Non-trainable params: 0
Total mult-adds (M): 306.88
==========================================================================================
Input size (MB): 0.26
Forward/backward pass size (MB): 155.85
Params size (MB): 0.04
Estimated Total Size (MB): 156.15
==========================================================================================

4. 作业

  1. 在DNN样例代码中,激活函数,优化器和损失函数分别是什么?(不需要加括号)
answer_1 = 'tanh'     #激活函数放入引号内
answer_2 = 'SGD'     #优化器放入引号内
answer_3 = 'CrossEntropyLoss'     #损失函数放入引号内
  1. 使用textCNN的样例代码,输入数据维度为[batch_size = 64, token_size=2228],问Conv2d(1, 100, kernel_size=(3, 5), stride=(1, 1))的输出数据维度?(需要以数组表示方式呈现,例如[w, x, y, z])
    提示:因为答案是用string进行匹配,需要使用英文逗号进行分隔,并且中间无空格
answer_4 = '[64,100,2226,1]'     #答案放入引号内

可以利用提供的代码来确定Conv2d(1, 100, kernel_size=(3, 5), stride=(1, 1))输出的维度。

这段代码定义了一个文本分类的卷积神经网络模型,它使用了嵌入层将输入的文本词汇转换为固定长度的词向量,然后通过一系列的卷积层来提取文本特征,并最终通过一个全连接层进行分类。

这里的关键部分是卷积层:

self.convs = nn.ModuleList([nn.Conv2d(Ci,100,(K,Dim)) for K in Ks])  

这表示网络将使用多个卷积核大小,但每个核大小的卷积层都将有100个输出通道,并且每个卷积核都将覆盖Dim个词嵌入维度。由于词嵌入的维度是5,所以卷积核的大小将是(K, 5)

接下来,我们看一下前向传播函数:

x = self.embed(x) # (N,W,D)  
x = x.unsqueeze(1) # (N,Ci,W,D)  
x = [F.relu(conv(x)).squeeze(3) for conv in self.convs] # len(Ks)*(N,Knum,W)  

这里,输入x首先被转换成了词嵌入,维度是(N, W, D),其中:

  • N是batch_size
  • W是token_size,即句子长度
  • D是每个词向量的长度,这里是5

卷积操作应用于扩展了一个维度的x,也就是(N, Ci, W, D)。在这个情况下,Ci是输入通道数,这里是1。每个卷积层的输出是(N, Knum, W, 1),其中Knum是输出通道数,这里是100。

根据卷积操作的定义,输出宽度(即句子长度维度)是通过以下公式计算的:

KaTeX parse error: Expected 'EOF', got '_' at position 14: [\text{output_̲width} = \frac{…

在我们的例子中,input_width是token_size(句子长度),kernel_width是卷积核的高度(我们的例子中是3),stride_width是1。因此:

KaTeX parse error: Expected 'EOF', got '_' at position 14: [\text{output_̲width} = \frac{…

所以,对于每个卷积层,输出的维度将是(N, 100, 2226, 1)。然后我们应用1-max pooling,这将会减少每个卷积层的输出到(N, 100)。因为我们有len(Ks)组这样的输出,每组输出都是(N, 100),最后这些输出会被拼接起来,所以全连接层的输入维度将是(N, 100 * len(Ks))

请注意,这里的输出宽度计算假设了句子长度(token_size)是连续的词嵌入维度,这在实际中可能不是这样。在实际应用中,token_size应该是句子长度(即单词数量),而不是单词数量乘以词嵌入维度。如果句子长度和词嵌入维度在实际应用中是分开的,那么上述维度计算需要相应调整。

# Define the parameters as provided in the problem statement and the code
batch_size = 64  # given batch size
token_size = 2228  # total number of tokens
embedding_dim = 5  # embedding dimension from the code
kernel_size = (3, embedding_dim)  # kernel size as per the Conv2d definition in the code
stride = (1, 1)  # stride for the convolution

# Calculate the output dimensions after the convolution layer
# Note that the input width is considered to be the 'token_size' here, which might need clarification.
# However, for the purpose of this calculation, we assume 'token_size' is the effective width after embedding.

# Output width calculation for convolution
output_width = ((token_size - kernel_size[0]) // stride[0]) + 1
output_height = 1  # Since the embedding dimension is completely covered by the kernel, the output height is 1

# The number of output channels is given as 100
output_channels = 100

# Output dimension after convolution
output_dimension = [batch_size, output_channels, output_width, output_height]
output_dimension
[64, 100, 2226, 1]
  1. 在textCNN的样例代码中,从输入层到输出层,一共有几层?
answer_5 = '6'     #答案放入引号内

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

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

相关文章

避坑指南:uni-forms表单在uni-app中的实践经验

​🌈个人主页:前端青山 🔥系列专栏:uni-app篇 🔖人终将被年少不可得之物困其一生 依旧青山,本期给大家带来JavaScript篇专栏内容:uni-app中forms表单的避坑指南篇 该篇章已被前端圈子收录,点此处进入即可查看更多优质内…

Pytorch nn.Linear()的基本用法与原理详解及全连接层简介

主要引用参考: https://blog.csdn.net/zhaohongfei_358/article/details/122797190 https://blog.csdn.net/weixin_43135178/article/details/118735850 nn.Linear的基本定义 nn.Linear定义一个神经网络的线性层,方法签名如下: torch.nn.Li…

AT32F403如何扩大SRAM

配置方法 使用雅特力的ICP 进行配置(可在官网下载) (1)当连接上芯片后,点击设备操作->选择字节 (2)选择224KB SRAM (3)然后点击应用到设备,(可以点击从设备加载,来看当前的配置) (4)打开keil5魔术棒图标 ,将Target中的IRAM1第二个选项从0x10000改为0x3800。…

虚拟电厂 能源物联新方向

今年有多热?据上海市气象局官微消息,5月29日13时09分,徐家汇站气温达36.1℃,打破了百年来的当地5月份气温*高纪录。不仅如此,北京、四川、江西、湖南、广东、广西等地也频频发布高温预警。 伴随着居民用电急剧攀升&am…

4.1 媒资管理模块 - Nacos与Gateway搭建

文章目录 媒资管理模块 - 媒资项目搭建一、需求分析1.1 介绍1.2 数据模型1.3 分析网关 二、 搭建Nacos2.1 服务发现中心2.2.1 Maven2.2.2 配置Nacos 2.2 配置中心2.2.1 介绍2.2.2 Maven 坐标2.2.3 配置 content-api 工程2.2.4 配置 content-service 工程2.2.5 配置 system-api …

基础算法(5):滑动窗口

1.何为滑动窗口? 滑动窗口其实也是一种算法,主要有两类:一类是固定窗口,一类是可变窗口。固定的窗口只需要一个变量记录,而可变窗口需要两个变量。 2.固定窗口 就像上面这个图一样。两个相邻的长度为4的红色窗口&…

HTML---CSS美化网页元素

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一.div 标签&#xff1a; <div>是HTML中的一个常用标签&#xff0c;用于定义HTML文档中的一个区块&#xff08;或一个容器&#xff09;。它可以包含其他HTML元素&#xff0c;如文本、图像…

探秘 AJAX:让网页变得更智能的异步技术(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

如何编写好的测试用例?

对于软件测试工程师来说&#xff0c;设计测试用例和提交缺陷报告是最基本的职业技能。是非常重要的部分。一个好的测试用例能够指示测试人员如何对软件进行测试。在这篇文章中&#xff0c;我们将介绍测试用例设计常用的几种方法&#xff0c;以及如何编写高效的测试用例。 一、…

iPhone 17Pro/Max或升级4800万像素长焦镜头,配备自研Wi-Fi 7芯片。

iPhone 16未至&#xff0c;关于iPhone 17系列的相关消息就已经放出&#xff0c;到底是谁走漏了风声。 海通国际证券技术分析师Jeff Pu近日发布报告称&#xff0c;苹果将为2025年推出的iPhone 17ProMax配备4800万像素的长焦镜头。经调查&#xff0c;该分析师认为提升iPhone拍摄方…

如何在华为云上购买ECS及以镜像的方式部署华为云欧拉操作系统 (HCE OS)

写在前面 工作中遇到&#xff0c;简单整理博文内容为 华为云开发者认证 实验笔记https://edu.huaweicloud.com/certificationindex/developer/9bf91efb086a448ab4331a2f53a4d3a1理解不足小伙伴帮忙指正 对每个人而言&#xff0c;真正的职责只有一个&#xff1a;找到自我。然后在…

Nginx快速入门:Nginx应用场景、安装与部署(一)

1. Nginx简介 Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;也是一个非常流行的开源 Web 服务器软件。它是由俄罗斯程序员 Igor Sysoev 开发的&#xff0c;最初是为了解决在高并发场景下的C10k 问题&#xff08;即一个服务器进程只能处理 10,000 个并发连接&#x…

早期的OCR是怎么识别图片上的文字的?

现在的OCR技术融合了人工智能技术&#xff0c;通过深度学习&#xff0c;无论是识别的准确率还是效果都非常不错&#xff0c;那您知道在早期的OCR是通过什么技术来实现的吗&#xff1f;如果您不知道&#xff0c;那么&#xff0c;就让我来告诉您&#xff1a;它主要是基于字符的几…

DiffUtil + RecyclerView 在 Kotlin中的使用

很惭愧, 做了多年的Android开发还没有使用过DiffUtil这样解放双手的工具。 文章目录 1 DiffUtil 用来解决什么问题?2 DiffUtil 是什么?3 DiffUtil的使用4 参考文章 1 DiffUtil 用来解决什么问题? 先举几个实际开发中的例子帮助我们感受下: 加载内容流时,第一次加载了ABC,…

数据分析思维导图

参考&#xff1a; https://zhuanlan.zhihu.com/p/567761684?utm_id0 1、数据分析步骤地图 2、数据分析基础知识地图 3、数据分析技术知识地图 4、数据分析业务流程 5、数据分析师能力体系 6、数据分析思路体系 7、电商数据分析核心主题 8、数据科学技能书知识地图 9、数据挖掘…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《基于碳捕集-电转气的矿区综合能源系统协同优化调度》

这个标题涉及到碳捕集、电力转化为气体&#xff08;可能是指电力转化为氢气等&#xff09;、矿区综合能源系统以及协同优化调度等概念。让我们逐步解读&#xff1a; 碳捕集&#xff08;Carbon Capture&#xff09;&#xff1a; 这指的是通过不同技术手段捕获和隔离工业过程中产…

输电线路定位:精确导航,确保电力传输安全

在现代社会中&#xff0c;电力作为生活的基石&#xff0c;其安全稳定运行至关重要。而输电线路作为电力传输的重要通道&#xff0c;其故障定位和修复显得尤为重要。恒峰智慧科技将为您介绍一种采用分布式行波测量技术的输电线路定位方法&#xff0c;以提高故障定位精度&#xf…

新版Android Studio Logcat 筛选日志

下载了新版的Android Studio&#xff0c;android-studio-2022.3.1.21-mac_arm&#xff0c;记录一下新版本AS的logcat过滤日志条件 1. 按照包名过滤 1.1 过滤当前包名的日志 package:mine 1.2 过滤其他包名日志 package:com.example.firstemptyapplication 2. 按照日志等级过滤…

STM32与Freertos入门(三)任务的创建、删除

1、串口配置 首先将串口进行配置&#xff0c;后续经常会应用&#xff0c;具体步骤点击&#xff1a;串口配置。 2、任务 创建一个任务&#xff0c;就是开辟一个空间、每个任务中都会有while&#xff08;1&#xff09;死循环。 2.1相关函数 动态创建&#xff1a;xTaskCreate…

Github 2023-12-19开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2023-12-19统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目4Rust项目2非开发语言项目2C#项目1TypeScript项目1 Avalonia: 跨平台UI框架和Avalonia XPF 创建周…