CVer从0入门NLP(一)———词向量与RNN模型

🍊作者简介:秃头小苏,致力于用最通俗的语言描述问题

🍊专栏推荐:深度学习网络原理与实战

🍊近期目标:写好专栏的每一篇文章

🍊支持小苏:点赞👍🏼、收藏⭐、留言📩

文章目录

  • CVer从0入门NLP(一)———词向量与RNN模型
    • 写在前面
    • 词向量
    • RNN模型
      • RNN模型结构
      • 手撸RNN
    • 参考连接

 

CVer从0入门NLP(一)———词向量与RNN模型

写在前面

Hello,大家好,我是小苏👦🏽👦🏽👦🏽

之前的博客中,我都为大家介绍的是计算机视觉的知识,今天准备和大家唠唠NLP的内容。其实呢,对于NLP,我也是初学者,之前只是有一个大概的了解,所以本系列会以一个初学者的视角带大家走进NLP的世界,如果博客中有解释不到位的地方,希望各位大佬指正。🍭🍭🍭

当然了,NLP的内容很多,你如果在网上搜NLP学习路线的话你会看的眼花缭乱,本系列主要会介绍一些重要的知识点,一些历史久远的模型就不介绍了,我个人觉得用处不大,我们的目标是像经典模型看齐,如GPT系列,BERT家族等等。🍡🍡🍡

本系列目前准备先分三节介绍,后面会慢慢补充新内容。第一节先从词向量为切入点,然后介绍RNN模型并手撸一个RNN;第二节会介绍RNN的改进LSTM及ELMO模型;第三节会详细介绍GPT和BERT,以及它们的相同点和不同点。🍬🍬🍬

 

词向量

我们知道,NLP任务中我们处理的对象是一个个的词,但是计算机根本不认识我们的词啊,需要将其转换为适合计算机处理的数据类型。一种常见的做法是独热编码(one-hot编码),假设我们现在要对“秃”、“头”,“小”,“苏”四个字进行独热编码,其结果如下:

​ 可以看出,上图可以用一串数字表示出“秃”、“头”,“小”,“苏”这四个汉字,如用1 0 0 0表示“秃”,用0 1 0 0表示“头”…

​ 但是这种表示方法是否存在缺陷呢?大家都可以思考思考,我给出两点如下:

  1. 这种编码方式对于我这个案例来说貌似是还蛮不错的,但是大家有没有想过,对于一个文本翻译任务来说,往往里面有大量大量的汉字,假设有10000个,那么一个单独的字,如“秃”就需要一个1×10000维的矩阵来表示,而且矩阵中有9999个0,这无疑是对空间的一种浪费。
  2. 这种编码方式无法表示两个相关单词的关系,如“秃”和“头”这两个单词明显是有某种内在的关系的,但是独热编码却无法表示这种关系【余弦相似度为0,后文对余弦相似度有介绍】。

基于以上的两点,我觉得我们的对词的编码应该符合以下几点要求:

  1. 我们可以将词表示为数字向量。
  2. 我们尽可能的节省空间的消耗。
  3. 我们可以轻松计算向量之间的相似程度。

我们先来看这样的一个例子,参考:The Illustrated Word2vec🎅🏽🎅🏽🎅🏽🍚🍚🍚

现在正值秋招大好时机,大家的工作都找的怎么样了腻,祝大家都能找到令自己满意的工作。在投简历的过程中,我们会发现很多公司都会有性格测试这一环节,这个测试会咨询你一系列的问题,然后从多个维度来对你的性格做全面分析。其中,测试测试者的内向或外向往往是测试中的一个维度,假设我(Jay)的内向/外向得分为38(满分100),则我们可以绘制下图:

为了更好的表示数据,我们将数据限制到-1~1范围内,如下:

img

这样我们就可以对Jay这个人是否外向做一个大致的评价,但是人是复杂的,仅仅从一个维度来分析一个人的性格肯定是不准确的,因此,我们再来添加一个维度来综合评价Jay这个人的性格特点:

img

可以看到,现在我们就可以从两个维度来描述Jay这个人了,在上图的坐标系中就是一个坐标为(-0.4,0.8)的点,或者说是从原点到(-0.4,0.8)的向量。当然了,如何还有别人有这样的两个维度,我就能通过比较他们的向量来表示他们的相似性。

image-20230913162620927

从上图可以和明显的看出,Person1和Jay更像,但是这是我们直观的感受,我们可不可以通过数值来反应他们之间的相似度呢,当然可以,一种常见的计算相似度的方法是余弦相似度cosine_similarity,结果如下:

img

🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷

不知道大家知不知道计算余弦相似度,这里简单介绍一下:

余弦相似度是一种用于衡量两个向量之间相似性的度量方法,通常在自然语言处理和信息检索等领域广泛使用。它计算两个向量之间的夹角余弦值,值越接近1表示两个向量越相似,值越接近-1表示两个向量越不相似,值接近0表示两个向量之间没有明显的相似性。

余弦相似度的计算公式如下:

余弦相似度= A ⋅ B ∣ ∣ A ∣ ∣ ∣ ∣ B ∣ ∣ \frac{A \cdot B}{||A||||B||} ∣∣A∣∣∣∣B∣∣AB

其中:

  • AB 是要比较的两个向量。
  • A ⋅ B A \cdot B AB 表示向量** A A A**与向量 ** B B B**的点积(内积)。
  • ** ∣ ∣ A ∣ ∣ ||A|| ∣∣A∣∣**和 ∣ ∣ B ∣ ∣ ||B|| ∣∣B∣∣ 分别表示向量 ** A A A**与向量 ** B B B**的范数(模)。

可以来简单举个例子:

假设有两个向量 A = [ 2 , 3 ] A=[2,3] A=[2,3] B = [ 1 , 4 ] B=[1,4] B=[1,4]。我们来计算它们之间的余弦相似度:

A ⋅ B = ( 2 × 1 ) + ( 3 × 4 ) = 14 A \cdot B=(2×1)+(3×4)=14 AB=(2×1)+(3×4)=14

∣ ∣ A ∣ ∣ = 2 2 + 3 2 = 13 ||A||=\sqrt{2^2+3^2}=\sqrt{13} ∣∣A∣∣=22+32 =13

∣ ∣ B ∣ ∣ = 1 2 + 4 2 = 17 ||B||=\sqrt{1^2+4^2}=\sqrt{17} ∣∣B∣∣=12+42 =17

则:余弦相似度= A ⋅ B ∣ ∣ A ∣ ∣ ∣ ∣ B ∣ ∣ = 14 13 17 ≈ 0.86 \frac{A \cdot B}{||A||||B||}=\frac{14}{\sqrt{13}\sqrt{17}}\approx0.86 ∣∣A∣∣∣∣B∣∣AB=13 17 140.86

🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷

上面展示的是从两个维度刻画一个人的性格,但是在实际中比两维更多,国外心理学家研究了五个主要人格,所以我们可以将上面的二维扩展到五维,如下图所示:

img

显然,现在我们有五个维度的数据,我们无法通过平面向量的形式来观察不同人物之前的相似性,但是我们仍然可以计算他们之前的相似度,如下:

img


通过上面的性格测评小例子,我想告诉大家的是我们可以把诸如"外向/内向"、“自卑/自负”等性格特征表述成向量的形式,并且每个人都可以用这些种向量形式表示,同时我们可以根据这种向量的表述来计算每个人之前的相似度。

同样的道理,人可以,那么词也可以,我们把一个个词表示成这样的向量形式,这种向量表示形式就是词向量。那么词向量到底长什么样呢?我们一起来看看“King”这个词的词向量(这是在维基百科上训练好的),如下:

[ 0.50451 , 0.68607 , -0.59517 , -0.022801, 0.60046 , -0.13498 , -0.08813 , 0.47377 , -0.61798 , -0.31012 , -0.076666, 1.493 , -0.034189, -0.98173 , 0.68229 , 0.81722 , -0.51874 , -0.31503 , -0.55809 , 0.66421 , 0.1961 , -0.13495 , -0.11476 , -0.30344 , 0.41177 , -2.223 , -1.0756 , -1.0783 , -0.34354 , 0.33505 , 1.9927 , -0.04234 , -0.64319 , 0.71125 , 0.49159 , 0.16754 , 0.34344 , -0.25663 , -0.8523 , 0.1661 , 0.40102 , 1.1685 , -1.0137 , -0.21585 , -0.15155 , 0.78321 , -0.91241 , -1.6106 , -0.64426 , -0.51042 ]

这一共有50个数字,即表示我们选择了50个维度的特征来表示“king”这个词,也即这个向量表示“king”这个词。同样的道理,别的单词也会有属于他们自己的向量表示,形式和上面的是一样的,都是50维,但是里面具体的值不同。为了方便展示不同词之间的联系,我们将表示“king”的词向量换一种方式展示,根据其值的不同标记成不同的颜色(若数值接近2,则为红色;接近0,则为白色;接近-2,则为蓝色),如下图:

image-20230913194932868

当然了,我们用同样的道理,会得到其它词的词向量表示,如下:

img

可以看到,“Man”和“Woman”之前的相似程度似乎比它们和“King”之前的相似程度高,这也是符合我们直觉的,即“Man”和“Woman”之前的联系似乎比较大。

这就说明,经过把词变成词向量之后,我们可以发现不同词之前的相关程度了。这里你可能会问了,怎么把词变成词向量呢?不急,我们马上解答。🧃🧃🧃

我们再拿我们一开始“秃”、“头”,“小”,“苏”四个字为例,我们使用独热编码编码这四个字后,它们之间的余弦相似度都为0,无法表示它们之间的相关程度,因此使用独热编码作为词向量效果不好。那么改使用什么呢,一种可能的方案是Word Embedding。我们先来说说通过Word Embedding可以达到什么样的效果,同样拿“秃”、“头”,“小”,“苏”四个字为例,使用Word Embedding后它们的分布是这样的:

即“秃”和“头”在某个空间中离的比较近,说明这两个词的相关性较大。即Word Embedding可以从较高的维度去考虑一些词,那么会发现一些词之前存在某种关联。

那么如何进行Word Embedding,如何得到我们的词向量呢?首先我需要让大家认识到一点,进行Word Embedding,其实重点就是寻找一个合适的矩阵Q。然后将我们之前的one hot编码乘上Q,,比如“秃”的one hot 编码是1 0 0 0,假设我们寻找到了一个矩阵Q,

image.png
那么我们将它们两个相乘,就得到了“秃”的词向量:

词向量“秃”:

image.png
同理,我们可以得到其它几个词的词向量:

image-20230913212503302

好了,到这里你或许明白了我们的目标就是寻找一个变化矩阵Q。那么这个Q又是怎么寻找的呢,其实呢,这个Q矩阵是训练出来的。一开始,有一种神经网络语言模型,叫做NNLM,它在完成它的任务的时候产生了一种副产物,这个副产物就是这个矩阵Q。【这里我们不细讲了,大家感兴趣的去了解一下,资料很多】后面人们发现这个副产物挺好用,因为可以进行Word Embedding,将词变成词向量嘛。于是科研人员就进一步研究,设计出了Word2Vec模型,这个模型是专门用来得到这个矩阵Q的。【后面我们也叫这个矩阵Q为Embedding矩阵】🥗🥗🥗

Word2Vec模型有两个结构,如下:

  • CBOW,这种模型类似于完型填空,核心思想是把一个句子中间的某个词挡住,然后用这个词的上下文单词去预测这个被挡住的词。🍚🍚🍚
  • Skip-gram,这个和CBOW结构刚好相反,它的核心思想是根据一个给定的词去预测这个词的上下文。🍚🍚🍚

它们的区别可以用下图表示:

Word2Vec

至于它们具体是怎么实现的我不打算讲,感兴趣的可以去搜搜。我简单说说它的思路:在它们训练时,首先会随机初始化一个Embedding表和Context表,然后我们会根据输入单词去查找两个表,并计算它们的点积,这个点击表示输入和上下文的相似程度,接着会根据这个相似程度来设计损失函数,最后根据损失不断的调整两个表。当训练完成后,我们就得到了我们的Embedding表,也就是Q矩阵。🍗🍗🍗

 

RNN模型

上一小节我们介绍了词向量,它解决的是我们NLP任务中输入问题。下面我们将一起来唠唠NLP任务中的常见模型。🍄🍄🍄

RNN模型结构

RNN(循环神经网络)我想大家多少都有所耳闻吧,它主要用于解决时序问题,例如时间序列、自然语言文本、音频信号等。

话不多说,我们直接来看RNN的模型图,如下:

img

啊,什么,这这点!!!?你或许感到震惊,RNN的模型结构就这么点儿???是的,没错,就这些。🥗🥗🥗首先,它有一个输入 X t X_t Xt,这是一个序列输入,比如某时刻的输入为 x i x_i xi x i x_i xi会输入到模块A中【注意:这里不止一个输入,还会有一个输入 h i − 1 h_{i-1} hi1一起送入模块A】,然后模块A输出一个值 h i h_i hi。接着会将输出 h i h_i hi和下一个输入 x i + 1 x_{i+1} xi+1送入模块A,得到输出 h i + 1 h_{i+1} hi+1。【注意:最基础的RNN的输出和 h t h_t ht是一样的】重复上面的过程,就是RNN啦。

上面的图用一个循环表示RNN,其实看起来还是比较不舒服,那么我们把这个循环展开,其结构就会比较清晰了,如下图所示:

img

知道了RNN的大体结构,我觉得你或与会对模块A的结构很敢兴趣,那我劝你不要太敢兴趣。🧃🧃🧃因为模块A真的很简单,就是一个tanh层,如下:

img

enmmmm,就是这么简单,如果你对此结构还存有疑惑的话,那么字写看看后文的代码手撸RNN部分,或许能解决你的大部分疑惑。

到这里,其实RNN的模型结构就讲完了,是不是很简单呢。🍭🍭🍭那么下面讲什么呢?自然是RNN存在什么问题,这样才能过渡到后面更加牛*的网络嘛。🍄🍄🍄

那么RNN存在什么问题呢?那就是长距离依赖问题,何为长距离依赖呢?他和短距离依赖是相对的概念,我们来举个例子来介绍什么是长距离依赖,什么是短距离依赖:

  • 对于这样一句话:“我爱在足球场上踢__”,我们是不是很容易得到空格里的答案,因为在空格前几个字有足球场,所以我们知道这里要填“足球”。这种能根据上下文附近就判断预测答案的就是短距离依赖。【短距离依赖的图示如下】

  • 对于这样一句话:“我爸爸从小就带我去足球场踢足球,我的爱好就是足球。我和爸爸关系非常好,经常带我一起玩耍,…,真是一个伟大的父亲。长大后,我的爱好一直没变,现在我就要去踢__”,大家感受到了嘛,这里空格中要填的词我们要往上文找很就才可以发现,这种预测答案需要看上文很远距离找到答案的就是长距离依赖。

也就是说,RNN网络对于长距离依赖的问题效果很不好,因此我们后面会对RNN网络进行改进,进而提高其对长距离依赖的能力。🥝🥝🥝

手撸RNN

想必大家通过上文的讲述,已经对RNN的代码结构有了一定的认识,下面我们就来使用Pytorch来实现一个RNN网络,让大家对其有一个更加清晰的认识。🥂🥂🥂

这部分的思路是这样的,我先给大家调用一下官方封装好的RNN模型,展示模型输入输出的结果;然后再手撸一个RNN函数,来验证其结果是否和官方一致。

好了,我们就先来使用官方定义好的RNN模型来实现,具体可以看这个连接:RNN🍵🍵🍵

import torch 
import torch.nn as nn
bs, T = 2, 3   #批大小,输入序列长度
input_size, hidden_size = 2, 3  # 输入特征大小,隐含层特征大小
input = torch.randn(bs, T, input_size) # 随机初始化一个输入特征序列
h_prev = torch.zeros(bs, hidden_size)  # 初始隐含状态

我们先来打印看一下inputh_prev以及它们的shape,如下:

我们来解释一下这些变量,input就是我们输入的数据,他的维度为(2, 3, 2),三个维度分别表示(bs, T, input_size),即(批大小,输入序列长度,输入特征大小)。我这样介绍大家可能还一头雾水,我结合input的打印结果给大家介绍,首先很明显这是一个维度为(2, 3, 2)的向量,这个大家都知道哈,不知道我就真没办法啦,去补补课吧。🍸🍸🍸那么这个向量的第一个维度是2,就代表我们1个batch有两条数据,每个都是(3, 2)维度的向量,如下:

这个和计算机视觉中的bs(batch_size)是一个意思啦,接下来我们来看每条数据,即这个(3,2)维的向量,以第一条为例:这个3表示输入序列长度,表示每条数据又有三个小部分构成,分别为[-0.0657, -0.9015]、[-0.0324, -0.5666]、[-0.2630, 2.4861]。这是什么意思呢,这表示我们的输入会分三次送入RNN网络中,分别是 x 0 、 x 1 、 x 2 x_0、x_1、x_2 x0x1x2,不知道这样大家能否理解,我画个图大家就知道了,如下:

image-20230915195447555

大家可能发现了,这个维度的3个数据就相当于3个词,分别一步步的送入RNN网络中,那么其实最后一个维度2,也就是输入特征大小也很好理解了,它就表示每个词的维度,就是我们前文所说的词向量,那么我们这里就是每个词向量有两个维度的特征。🍚🍚🍚

通过上文的介绍,我想大家了解input这个输入了,那么h_prev是什么呢,其是隐层的输出,也就是上图中的 h 0 、 h 1 、 h 2 h_0、h_1、h_2 h0h1h2

接着我们就来调用pytorch中RNN的API:

# 调用pytorch RNN API
rnn = nn.RNN(input_size, hidden_size, batch_first=True)
rnn_output, state_final = rnn(input, h_prev.unsqueeze(0))

batch_first=True这个参数是定义我们输入的格式为(bs, T, input_size)的,pytorch文档中都解释的很详细,大家自己去看一下就好。至于这个h_prev.unsqueeze(0)这里加了第一个维度,这是由于RNN API的输入要求是三维的向量,如下:

我们来看看输出的rnn_outputstate_final的值和shape吧,如下:

image-20230915200857983

rnn_output其实就是每个隐藏层的输出,而state_final则是最终的输出,在基础的RNN中,state_final的值就等于最后一个隐藏层的输出,我们从数值上也可以发现,如下:

image-20230915201239237

为了方便大家理解,再画一个图,如下:【注意:图都是以batch中一条数据为例表示的】

image-20230915202347081


那么上文就为大家介绍了如何使用pytorch官方API实现RNN,但是这样我们无法看到RNN内部是如何实现的,那么这样我们就来手动实现一个RNN。其实很简单,主要就是用到了一个公式,如下:

image-20230915203051193

这个公式可以在pytorch官方文档中看到,其实不知道大家发现没有,其实这个公式和卷积神经网络的公式是很像的,只不过RNN这里有两个输入而已。还有一点和大家说一下,上图公式中含有转置,实现起来转置来转置去的会很绕,上面的公式其实和下面是一样的【上下两个 x t x_t xt维度其实变了】:

image-20230915203513846

为了简便起见,我用不带转置的进行代码编写,大家先理解好这个,最后我也会把带转置的代码放出来,这时候理解带转置的可能更容易点。

# 手写一个rnn_forward函数,实现RNN的计算原理
def rnn_forward(input, weight_ih, weight_hh, bias_ih, bias_hh, h_prev):bs, T ,input_size = input.shapeh_dim = weight_ih.shape[0]h_out = torch.zeros(bs, T, h_dim)for t in range(T):x = input[:,t,:].unsqueeze(2)    w_ih_batch = weight_ih.unsqueeze(0).tile(bs, 1, 1)w_hh_batch = weight_hh.unsqueeze(0).tile(bs, 1, 1)w_times_x = torch.bmm(x.transpose(1, 2), w_ih_batch.transpose(1, 2)).transpose(1, 2).squeeze(-1)w_times_h = torch.bmm(h_prev.unsqueeze(2).transpose(1, 2), w_hh_batch.transpose(1, 2)).transpose(1, 2).squeeze(-1)h_prev = torch.tanh(w_times_x + bias_ih + w_times_h + bias_hh)h_out[:,t,:] = h_prevreturn h_out, h_prev.unsqueeze(0)

我们看到代码并不长,所以其实还是很简单的,最主要的是大家注意for t in range(T)这个循环,就是不断的取输入序列中的向量送入RNN网络,比如开始是 x 0 x_0 x0送入、接着是 x 1 x_1 x1送入…依次类推,后面的几行代码都是围绕 h t = tanh ⁡ ( W i h x t + b i h + W h h h ( t − 1 ) + b h h ) h_{t}=\tanh \left(W_{i h} x_{t}+b_{i h}+W_{h h} h_{(t-1)}+b_{h h}\right) ht=tanh(Wihxt+bih+Whhh(t1)+bhh)进行编写的,具体的细节大家慢慢调试吧,相信难不住你。因为设计到很多向量运算,所以特别要注意维度的变化。🍗🍗🍗

接下来我们要验证一下我们实现的RNN是否正确,但是我们需要传入 W i h 、 b i h 、 W h h 、 b h h W_{ih}、b_{ih}、W_{hh}、b_{hh} WihbihWhhbhh参数,这几个参数怎么得到呢,我们可以在rnn中看到这几个参数的值,我们也只有用这个才能保证我们最后的结果和官方的一致,我们可以来简单看看这几个值,如下:

image-20230915212318490

接着我们就可以将这里面的参数传入到rnn_forward函数中,如下:

custom_rnn_output, custom_state_final = rnn_forward(input, rnn.weight_ih_l0, rnn.weight_hh_l0, rnn.bias_ih_l0,  rnn.bias_hh_l0, h_prev)

同样,我们来打印一下custom_rnn_output和custom_state_final,如下:

image-20230915212531221

经过对比,你可以发现,使用官方API和使用我们自定义的函数实现的RNN的输出是一样,这就验证了我们方法的正确性。

下面给出带转置的,即 h t = tanh ⁡ ( x t W i h T + b i h + h t − 1 W h h T + b h h ) h_{t}=\tanh \left(x_{t} W_{i h}^{T}+b_{i h}+h_{t-1} W_{h h}^{T}+b_{h h}\right) ht=tanh(xtWihT+bih+ht1WhhT+bhh)这个表达式的代码供大家参考,如下:

# custom 手写一个rnn_forward函数,实现RNN的计算原理
def rnn_forward(input, weight_ih, weight_hh, bias_ih, bias_hh, h_prev):bs, T, input_size = input.shapeh_dim = weight_ih.shape[0]h_out = torch.zeros(bs, T, h_dim)for t in range(T):x = input[:, t, :].unsqueeze(2)w_ih_batch = weight_ih.unsqueeze(0).tile(bs, 1, 1)w_hh_batch = weight_hh.unsqueeze(0).tile(bs, 1, 1)w_times_x = torch.bmm(x.transpose(1, 2), w_ih_batch.transpose(1, 2)).transpose(1, 2).squeeze(-1)w_times_h = torch.bmm(h_prev.unsqueeze(2).transpose(1, 2), w_hh_batch.transpose(1, 2)).transpose(1, 2).squeeze(-1)h_prev = torch.tanh(w_times_x + bias_ih + w_times_h + bias_hh)h_out[:, t, :] = h_prevreturn h_out, h_prev.unsqueeze(0)

 

参考连接

1、The Illustrated Word2vec

2、理解 LSTM 网络

3、Transformer通俗笔记:从Word2Vec、Seq2Seq逐步理解到GPT、BERT

4、Understanding LSTM Networks

5、预训练语言模型的前世今生

6、PyTorch源码教程与前沿人工智能算法复现讲解

 
 

如若文章对你有所帮助,那就🛴🛴🛴

一键三连 (1).gif

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

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

相关文章

[C++随想录] 二叉搜索树

搜素二叉树 二叉搜索树的使用二叉搜索树的模拟实现(K)整体结构循环版本递归版本 二叉搜索树的应用源码(kv) 二叉搜索树的使用 二叉搜索树 相较于 普通的二叉树来说: 根节点的左子树的所有键值都 小于 根节点, 根节点的右子树的所有键值 大于 根节点根节点的 左右子树 都是 二…

2023年中国石英矿资源现状及行业市场供需分析[图]

石英矿为常见的非金属矿物质,具有储量大、分布广、易开采等特点,根据不同成矿特性和理化特性,石英矿物可分为岩浆岩型、变质型、热液型、沉积型,对应的石英岩分别为花岗伟晶岩、脉石英岩、石英岩和石英砂岩。 石英矿物类型和特点…

无人机遥控中应用的2.4GHz无线芯片

无人驾驶飞机简称“无人机”,英文缩写为“UAV”,是利用无线电遥控设备和自备的程序控制装置操纵的不载人飞机,或者由车载计算机完全地或间歇地自主地操作。是一种不需要人操控就能够自主飞行的飞行器,它可以执行多种任务&#xff…

大数据开发中的秘密武器:探索Hadoop纠删码的奇妙世界

随着大数据技术的发展,HDFS作为Hadoop的核心模块之一得到了广泛的应用。为了系统的可靠性,HDFS通过复制来实现这种机制。但在HDFS中每一份数据都有两个副本,这也使得存储利用率仅为1/3,每TB数据都需要占用3TB的存储空间。因此&…

【网络安全入门】学习网络安全必须知道的100 个网络基础知识

前言 先领取资料再阅读哦 【282G】网络安全&黑客技术零基础到进阶全套学习大礼包(附面试题答案),免费分享! 【282G】网络安全&黑客技术零基础到进阶全套学习大礼包(附面试题答案),免…

安装Docker

本安装教程参考Docker官方文档,地址如下:https://docs.docker.com/engine/install/centos/ 卸载旧版 首先如果系统中已经存在旧的Docker,则先卸载: yum remove docker \ docker-client \ docker-client-latest \ docker-common…

【计算机网络】TCP 协议的相关特性

TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的协议。以下是TCP协议的相关特性: 可靠性:TCP通过确认和重传机制保证数据的可靠传输。 面向连接:TCP在传输数据前需要先建立连接。连接的建立过程包括三次握手…

C++ 读MTK代码 综测校准 PSU读开关电源电压或电流 visa

1.C定义dll接口 // The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the PSU_DLL_EXPORTS // symbol defined on the command line. this symbol should not b…

Zookeeper 和 Kafka 工作原理及如何搭建 Zookeeper集群 + Kafka集群

目录 1 Zookeeper 1.1 Zookeeper 定义 1.2 Zookeeper 工作机制 1.3 Zookeeper 特点 1.4 Zookeeper 数据结构 1.5 Zookeeper 应用场景 1.6 Zookeeper 选举机制 2 部署 Zookeeper 集群 2.1 安装前准备 2.2 安装 Zookeeper 3 Kafka 3.1 为什么需要消息队列(…

防雷检测的项目和行业的等级区分

防雷检测是指对雷电防护装置的性能、质量和安全进行检测的活动,是保障人民生命财产和公共安全的重要措施。 地凯科技防雷检测的项目内容包括接闪器检测、引下线检测、接地装置检测、防雷区的划分、电磁屏蔽防雷检测、等电位连接检测、及电涌保护器 (SPD)性能检测。…

C#,数值计算——分类与推理Phylo_nj的计算方法与源程序

1 文本格式 using System; using System.Collections.Generic; namespace Legalsoft.Truffer { public class Phylo_nj : Phylagglom { public double[] u; public override void premin(double[,] d, int[] nextp) { i…

电商接口中API key 和 token 有什么区别?

API key 和 token 就有这种问题,它们都是作为一种身份验证机制。前几天我在一次讨论中,有人提到这两个词可以互换使用。大约两分钟后,我不得不停止谈话并说“你们应该知道它们是不同的,对吧?”‍,说完会上鸦…

idea的debug调试

目录 断点条件设置(condition) 断点表达式(evaluate expression) 断点回退(reset frame) 断点条件设置(condition) 条件断点,一般是满足我们设置的某个条件时,debug断点才会生效。这种条件断点设置,我们一般用在多重循环中。 这儿我们以li…

前端数据可视化之【series、series饼图配置】配置项

目录 🌟Echarts配置项🌟series🌟饼图 type:pie🌟写在最后 🌟Echarts配置项 ECharts开源来自百度商业前端数据可视化团队,基于html5 Canvas,是一个纯Javascript图表库,提供直观&…

预测宝可梦武力值、分类宝可梦

regression case 股票预测 无人车看到的各种sensor 影像镜头看到马路上的东西作为输入,输出就是方向盘角度等等的操纵策略 scalar 标量 这个是热力图,相当于你的XYZ但是Z用颜色表示了 closed-form solution 闭合解 learning rate事先定好的数值 在lin…

Inbound marketing | LTD入站营销是对Hubspot集客营销的升级

你如何理解Inbound marketing? 你如何理解Inbound marketing。 集客营销抑或是入站营销。 2006年,MIT的在校学生BrianHalligan和DharmeshShah(hubspot的创始人)首次提出Inbound marketing,有别于推广式营销的一种全…

Ethernet Protocol

以太网协议说明 1 以太网子层架构 1)MAC and MAC CONTROL Sublayer MAC 负责以太网数据格式中所述的以太网成帧协议以及这些帧的错误检测。MAC 独立于并可以连接到任何类型的物理层设备。这提供了 MAC 子层的实时流控制操作。 MAC CONTROL 和 MAC 子层均由内核在所有操作模式…

layui中页面切分

1.引入Split插件 2.切屏比例设置 pallet与material为标签的id 3.html内部标签上设置切分盒子 4参考网站 : 网站链接

PS001:PS2020及GeographicImager6.2安装

引言:Geographic ImagerV6.2是一款专业的PS地理成像插件,通过安装这款插件可实现在PS中加载4G以上的.bigtiff格式影像并对其进行修改与保存。并且这款软件拥有投影信息修改、基于地理坐标进行影像裁切等多种功能。 一、插件介绍 Geographic ImagerV6.2是…

如何正确维护实验室超声波清洗机

实验室一直被视作一个严谨且严肃的场所,在其中所做的试验都需要遵照一定流程,所用的设备也经过了细致化挑选,例如实验室超声波清洗机,其性能远强于普通类别的清洗机。专门负责采购的实验室人员,通常会对质量优服务好的…