NLP深度学习 DAY4:Word2Vec详解:两种模式(CBOW与Skip-gram)
用稀疏向量表示文本,即所谓的词袋模型在 NLP 有着悠久的历史。正如上文中介绍的,早在 2001年就开始使用密集向量表示词或词嵌入。Mikolov等人在2013年提出的创新技术是通过去除隐藏层,逼近目标,进而使这些单词嵌入的训练更加高效。虽然这些技术变更本质上很简单,但它们与高效的word2vec配合使用,便能使大规模的词嵌入训练成为可能。
0 前言:词袋模型
首先解释一下什么是词袋模型:
词袋模型(Bag-of-Words, BOW) 是最早、最经典的文本表示方法之一(1940左右出现,甚至比n-gram还要早,我愿称之为原始祖师爷)。它将一段文本看作一个「袋子」:里面盛放了这个文本所含的所有单词,但忽略了单词的顺序、句法结构等信息,只关注单词是否出现以及出现次数(或频率)。这就好比把句子里的单词都抓出来扔进一个袋子,摇匀后再数一数这些单词都有什么、各出现几次。
1.1 典型示例
假设我们的词表是 "I","like","apples","banana",大小 V=4(指的就是一共有4个词)。
有两句话:
- “I like apples”
- “I like banana apples”
那么在词袋表示下:
-
对于 “I like apples”:
- "I" 出现 1 次
- "like" 出现 1 次
- "apples"出现 1 次
- "banana"出现 0 次
向量表示可写作[1, 1, 1, 0]
-
对于 “I like banana apples”:
- "I" 出现 1 次
- "like" 出现 1 次
- "apples"出现 1 次
- "banana"出现 1 次
向量表示可写作[1, 1, 1, 1]
可以看到,这种表示只管词的出现情况,不会去记录 “banana”是在“apples”前还是后出现,也不会记录它们之间的距离。这样就得到最纯粹的词袋表示。
一、词向量引入
先来考虑一个问题:如何能将文本向量化呢?听起来比较抽象,我们可以先从人的角度来思考。
如何用一个数值向量描述一个人呢?只用身高或者体重,还是综合其各项指标呢?当然是综合各项指标能更加准确的描述一个人啦,具体什么指标还得看你能收集到什么指标。比如除了常规的身高、体重外,我们还可以用人的性格,从内向到外向设置为从-1到+1,人的性格让“专家”去打分,从而获取人性格的数值化数据。
只要有了向量,就可以用不同方法(欧氏距离、曼哈顿距离、切比雪夫距离、余弦相似度等)来计算两个向量之间的相似度了!
通常来说,向量的维度越高,能提供的信息也就越多,从而计算结果的可靠性就更值得信赖
现在回到正题,如何描述词的特征?通常都是在词的层面上来构建特征。Word2Vec就是要把词转化为向量。
下图展示了一个50维的词向量:
假设现在已经拿到了一份训练好的词向量,其中每一个词都表示为50维的向量,如下图所示:
如果将它们在热度图中显示,结果如下:
在结果中可以发现,相似的词在特征表达中比较相似,也就是说明词的特征是有实际意义的!
二、词向量模型
在词向量模型中输入和输出是什么?中间这个黑盒又是什么?
如下图所示,在词向量模型中,输入可以是多个词。例如下面所示的,输入是 Thou 和 shalt,模型的任务是预测它们的下一个词是什么。
早期的神经网络的词嵌入方法(word2vec出现之前使用n-gram去训练原始词表里面的300维向量 差不多2001年)
最后一层连接了 SoftMax,所以网络的输出是所有词可能是下一个词的概率。
那么有人就会问了,输入是文字,文字怎么输入到神经网络中啊 ?这个问题很好,我们通常会用一个 Embedding 层来解决这个问题。如下图所示,在神经网络初始化的时候,我们会随机初始化一个 N×K 的矩阵,其中 N 是 词典的大小,K 是词向量的维数(一个自行设定的超参数)。然后,我们会用一个 N×N 的矩阵和 N×K 的矩阵相乘,得到一个新的 N×K的矩阵向下进行前向传播。其中,N×N 的矩阵会在输入的文字的对应对角线上设置为1,其余位置均为0。N×K 的矩阵是随机初始化的,通过反向传播进行更新调整。
下面展示了一个例子(假设输入的两个词在词典中的位置是2和3处):
三、训练数据构建(还是早期的n-gram模型)
问:我们的训练数据应该从哪找呢?
答:一切具有正常逻辑的语句都可以作为训练数据。如小说、论文等。
如果我们有一个句子,那么我们可以按照下面你的方式构建数据集,选出前三个词,用前两个作为词模型的输入,最后一个词作为词模型输出的目标,继而进行训练。如下图所示:
然后,我们还可以将”窗口“往右平移一个词,如下图所示,构造一个新的训练数据
当然,这个”窗口“的宽度也是可以自己设置的,在上例中,窗口宽度设置为 3,也可以设置为 4、5、6 等等
四、Word2vec(2013年)不同模型对比
4.1 CBOW
CBOW的全称是continuous bag of words(连续词袋模型)。其本质也是通过context word(背景词)来预测target word(目标词)。
CBOW之所以叫连续词袋模型,是因为在每个窗口内它也不考虑词序信息,因为它是直接把上下文的词向量相加了,自然就损失了词序信息。CBOW抛弃了词序信息,指的就是在每个窗口内部上下文直接相加而没有考虑词序。
用 CBOW 构造数据集的例子1如下图所示:
例子2:
假设我们有一个简单的句子:
“The cat sits on the mat”
-
选择“sits”作为目标词(w_t ),窗口大小设置为 2,意味着它的上下文是:
- 左边两个词: “The”, “cat”
- 右边两个词: “on”, “the” (如果只算到 “on the” 可能这样)
-
构建训练样本时,就会出现:
- 输入:上下文词“[The, cat, on, the]”各自的向量,合并/平均后得到 vcontext。
- 输出:目标词“sits”在词表上的概率。
对于句子中的其他位置,也会类似地滑动窗口,把每个词当作目标词,然后获取它的上下文词,构建训练样本。例如,把“cat”当目标词时,上下文就是 [The], [sits, on]
(在超出边界时,窗口不够可特殊处理)。
最大缺点:为什么说 “CBOW 不考虑词序”(之所以叫连续词袋模型)
- 在同一个窗口里,CBOW 只是把上下文词向量进行相加/平均。
- 这样做后,我们无法区分“cat sits on the mat” 和 “on the cat sits the mat” 这样的词序变化,因为最终得到的上下文向量是一样的。
- 这就是“Bag of Words”的含义:视上下文词为一个无序的集合。
尽管 CBOW 在窗口内部抛弃了词序信息,但它仍然是“连续”地按照窗口来遍历整篇文本(不会跨句子或任意地远距离取词),所以叫 “Continuous Bag of Words”。
4.2 Skip-gram 模型
Skip-gram 模型和 CBOW 相反,Skip-gram 模型的输入是一个词汇,输出则是该词汇的上下文。如下图所示:
下面举一个例子,设”窗口“宽度为5,每次用”窗口“的第三个也就是中的词汇作为输入,其余上下文作为输出,分别构建数据集,如下图所示:
然后用构建好的数据集丢给词模型进行训练,如下图所示:
如果一个语料库稍微大一点,可能的结果就太多了,最后一层 SoftMax 的计算就会很耗时,有什么办法来解决吗?
下面提出了一个初始解决方案:假设,传统模型中,我们输入 not ,希望输出是 thou,但是由于语料库庞大,最后一层 SoftMax 太过耗时,所以我们可以改为:将 not 和 thou 同时作为输入,做一个二分类问题,类别 1 表示 not 和 thou 是邻居,类别 0 表示它们不是邻居。
上面提到的解决方案出发点非常好,但是由于训练集本来就是用上下文构建出来的,所以训练集构建出来的标签全为 1 ,无法较好的进行训练,如下图所示:
改进方案:加入一些负样本(负采样模型),一般负采样个数为 5 个就好,负采样示意图如下图所示:
最大缺点:和上面的CBOW一样无法考虑词序
-
Skip-gram输入是目标词,输出是预测其上下文词。与 CBOW 类似,上下文词也被视为独立的个体,不关心它们的顺序或位置。
-
例如,对于目标词 "sat",模型会尝试预测周围的词(如 "The", "cat", "on", "the"),但预测过程中这些词的顺序无关紧要。
4.3 CBOW 和 Skip-gram 对比
五、词向量训练过程
5.1 初始化词向量矩阵
5.2 训练模型
通过神经网络反向传播来计算更新,此时不光更新权重参数矩阵W,也会更新输入数据
训练完成后,我们就得到了比较准确的 Word Embeddings,从而得到了每个词的向量表示!!!
六、Python 代码实战
6.1 Model
from torch import nnclass DNN(nn.Module):def __init__(self, vocabulary_size, embedding_dim):super(DNN, self).__init__()self.embedding = nn.Linear(vocabulary_size, embedding_dim, bias=False)print("embedding_size:", list(self.embedding.weight.size()))self.layers = nn.Sequential(nn.Linear(vocabulary_size * embedding_dim, embedding_dim // 2),nn.LeakyReLU(),nn.Linear(embedding_dim // 2, 4),nn.LeakyReLU(),nn.Linear(4, 1),)# Mean squared error lossself.criterion = nn.MSELoss()# self.criterion = nn.CrossEntropyLoss()def forward(self, x):x = self.embedding(x)x = x.view(x.size()[0], -1)x = self.layers(x)x = x.squeeze(1)return xdef cal_loss(self, pred, target):""" Calculate loss """return self.criterion(pred, target)
6.2 DataSet
import randomimport numpy as np
from torch.utils.data import Datasetclass MyDataSet(Dataset):def __init__(self, features, labels):self.features = featuresself.labels = labelsdef __getitem__(self, index):return self.features[index], self.labels[index]def __len__(self):return len(self.features)def get_data_set(data_path, window_width, window_step, negative_sample_num):with open(data_path, 'r', encoding='utf-8') as file:document = file.read()document = document.replace(",", "").replace("?", "").replace(".", "").replace('"', '')data = document.split(" ")print(f"数据中共有 {len(data)} 个单词")# 构造词典vocabulary = set()for word in data:vocabulary.add(word)vocabulary = list(vocabulary)print(f"词典大小为 {len(vocabulary)}")# index_dictindex_dict = dict()for index, word in enumerate(vocabulary):index_dict[word] = index# 开始滑动窗口,构造数据features = []labels = []neighbor_dict = dict()for start_index in range(0, len(data), window_step):if start_index + window_width - 1 < len(data):mid_index = int((start_index + start_index + window_width - 1) / 2)for index in range(start_index, start_index + window_width):if index != mid_index:feature = np.zeros((len(vocabulary), len(vocabulary)))feature[index_dict[data[index]]][index_dict[data[index]]] = 1feature[index_dict[data[mid_index]]][index_dict[data[mid_index]]] = 1features.append(feature)labels.append(1)if data[mid_index] in neighbor_dict.keys():neighbor_dict[data[mid_index]].add(data[index])else:neighbor_dict[data[mid_index]] = {data[index]}# 负采样for _ in range(negative_sample_num):random_word = vocabulary[random.randint(0, len(vocabulary))]for word in vocabulary:if random_word not in neighbor_dict.keys() or word not in neighbor_dict[random_word]:feature = np.zeros((len(vocabulary), len(vocabulary)))feature[index_dict[random_word]][index_dict[random_word]] = 1feature[index_dict[word]][index_dict[word]] = 1features.append(feature)labels.append(0)break# 返回dataset和词典return MyDataSet(features, labels), vocabulary, index_dict
6.3 Main
import random
from math import sqrtimport numpy as np
import torch
from torch.utils.data import DataLoaderfrom Python.DataSet import get_data_set
from Python.Model import DNNdef same_seed(seed):"""Fixes random number generator seeds for reproducibility固定时间种子。由于cuDNN会自动从几种算法中寻找最适合当前配置的算法,为了使选择的算法固定,所以固定时间种子:param seed: 时间种子:return: None"""torch.backends.cudnn.deterministic = True # 解决算法本身的不确定性,设置为True 保证每次结果是一致的torch.backends.cudnn.benchmark = False # 解决了算法选择的不确定性,方便复现,提升训练速度np.random.seed(seed) # 按顺序产生固定的数组,如果使用相同的seed,则生成的随机数相同, 注意每次生成都要调用一次torch.manual_seed(seed) # 手动设置torch的随机种子,使每次运行的随机数都一致random.seed(seed)if torch.cuda.is_available():# 为GPU设置唯一的时间种子torch.cuda.manual_seed(seed)torch.cuda.manual_seed_all(seed)def train(model, train_loader, config):# Setup optimizeroptimizer = getattr(torch.optim, config['optimizer'])(model.parameters(), **config['optim_hyper_paras'])device = config['device']epoch = 0while epoch < config['n_epochs']:model.train() # set model to training modeloss_arr = []for x, y in train_loader: # iterate through the dataloaderoptimizer.zero_grad() # set gradient to zerox, y = x.to(device).to(torch.float32), y.to(device).to(torch.float32) # move data to device (cpu/cuda)pred = model(x) # forward pass (compute output)mse_loss = model.cal_loss(pred, y) # compute lossmse_loss.backward() # compute gradient (backpropagation)optimizer.step() # update model with optimizerloss_arr.append(mse_loss.item())print(f"epoch: {epoch}/{config['n_epochs']} , loss: {np.mean(loss_arr)}")epoch += 1print('Finished training after {} epochs'.format(epoch))def find_min_distance_word_vector(cur_i, vector, embeddings, vocabulary):def calc_distance(v1, v2):# 计算欧式距离distance = 0for i in range(len(v1)):distance += sqrt(pow(v1[i] - v2[i], 2))return distancemin_distance = Nonemin_i = -1for i, word in enumerate(vocabulary):if cur_i != i:distance = calc_distance(vector, embeddings[i].tolist())if min_distance is None or min_distance > distance:min_distance = distancemin_i = ireturn min_iif __name__ == '__main__':data_path = './data/data.txt'config = {'seed': 3407, # Your seed number, you can pick your lucky number. :)'device': 'cuda' if torch.cuda.is_available() else 'cpu','n_epochs': 20, # Number of epochs.'batch_size': 64,'optimizer': 'Adam','optim_hyper_paras': { # hyper-parameters for the optimizer (depends on which optimizer you are using)'lr': 0.001, # learning rate of optimizer},'embedding_dim': 6, # 词向量长度'window_width': 5, # 窗口的宽度'window_step': 2, # 窗口滑动的步长'negative_sample_num': 10 # 要增加的负样本个数}same_seed(config['seed'])data_set, vocabulary, index_dict = get_data_set(data_path, config['window_width'], config['window_step'],config['negative_sample_num'])train_loader = DataLoader(data_set, config['batch_size'], shuffle=True, drop_last=False, pin_memory=True)model = DNN(len(vocabulary), config['embedding_dim']).to(config['device'])train(model, train_loader, config)# 训练完,看看embeddings,展示部分词的词向量,并找到离它最近的词的词向量embeddings = torch.t(model.embedding.weight)for i in range(10):print('%-50s%s' % (f"{vocabulary[i]} 的词向量为 :", str(embeddings[i].tolist())))min_i = find_min_distance_word_vector(i, embeddings[i].tolist(), embeddings, vocabulary)print('%-45s%s' % (f"离 {vocabulary[i]} 最近的词为 {vocabulary[min_i]} , 它的词向量为 :", str(embeddings[min_i].tolist())))print('-' * 200)
七、根据上面的代码举个例子
一、数据处理流程(以示例文本说明)
假设输入文件 data.txt
内容为:
I love machine learning because it is interesting.
1. 文本预处理
-
清洗:移除标点(
, ? . "
),处理后得到:I love machine learning because it is interesting
-
分词:按空格切分为单词列表:
data = ["I", "love", "machine", "learning", "because", "it", "is", "interesting"]
2. 构建词汇表
-
去重后得到词汇表(假设顺序固定):
vocabulary = ["I", "love", "machine", "learning", "because", "it", "is", "interesting"]
-
索引映射
index_dict
:{"I":0, "love":1, "machine":2, "learning":3, "because":4, "it":5, "is":6, "interesting":7}
3. 滑动窗口生成正样本
假设窗口宽度 window_width=5
,步长 window_step=2
:
-
窗口划分:
-
窗口1:
["I", "love", "machine", "learning", "because"]
,中心词是第2个(machine
,索引2)。 -
窗口内上下文词:
I
(索引0)、love
(索引1)、learning
(索引3)、because
(索引4)。 -
每个上下文词与中心词生成一个正样本。
-
-
特征矩阵示例(中心词
machine
和上下文词love
):# 特征矩阵形状 [8,8](词汇表大小=8) feature = np.zeros((8,8)) feature[1][1] = 1 # 上下文词 "love" 的对角线置1 feature[2][2] = 1 # 中心词 "machine" 的对角线置1
该样本标签为
1
。
4. 负采样生成负样本
随机选择不共现的词对(例如 machine
和 it
):
feature = np.zeros((8,8)) feature[2][2] = 1 # "machine" feature[5][5] = 1 # "it"
标签为 0
。
二、模型架构详解(DNN 类)
1. Embedding 层
-
定义:
nn.Linear(vocab_size, embed_dim, bias=False)
-
作用:将输入矩阵的每个词索引转换为嵌入向量。
-
输入形状:
[batch_size, vocab_size, vocab_size]
-
输出形状:
[batch_size, vocab_size, embed_dim]
-
矩阵乘法等价于对每个词进行线性变换。
-
2. 全连接层
-
结构:
nn.Sequential(nn.Linear(vocab_size * embed_dim, embed_dim//2), # 展平后输入nn.LeakyReLU(),nn.Linear(embed_dim//2, 4),nn.LeakyReLU(),nn.Linear(4, 1) )
-
作用:将展平后的嵌入向量映射到标量输出。
3. 前向传播流程
以单个样本 [8,8]
(词汇表大小=8)为例:
-
输入矩阵:
[1, 8, 8]
(batch_size=1) -
Embedding 层:与
[8, embed_dim]
权重矩阵相乘,得到[1, 8, embed_dim]
。 -
Reshape:展平为
[1, 8*embed_dim]
。 -
全连接层:逐步降维到标量输出。
三、训练过程(以示例说明)
1. 数据加载
-
Dataset:包含特征矩阵和标签。
-
DataLoader:按批次加载数据(
batch_size=64
)。
2. 损失函数与优化器
-
损失函数:
MSELoss
,优化目标使正样本输出接近1,负样本接近0。 -
优化器:
Adam
,学习率0.001
。
3. 训练循环
-
前向传播:输入特征矩阵,计算预测值。
-
反向传播:根据 MSE 损失更新参数。
四、词向量可视化与最近邻查找
1. 提取词向量
-
权重矩阵:
embeddings = torch.t(model.embedding.weight)
,形状[vocab_size, embed_dim]
。 -
示例输出:
"machine" 的词向量为 : [0.12, -0.45, 0.78, ...]
2. 计算最近邻
-
欧式距离:遍历所有词向量,找到距离最小的非自身词。
-
示例结果:
离 "machine" 最近的词为 "learning" ,距离 0.89
相关文章:
NLP深度学习 DAY4:Word2Vec详解:两种模式(CBOW与Skip-gram)
用稀疏向量表示文本,即所谓的词袋模型在 NLP 有着悠久的历史。正如上文中介绍的,早在 2001年就开始使用密集向量表示词或词嵌入。Mikolov等人在2013年提出的创新技术是通过去除隐藏层,逼近目标,进而使这些单词嵌入的训练更加高效。…...
SQL注入漏洞之基础数据类型注入 字符 数字 搜索 XX 以及靶场实例哟
目录 基础数据类型SQL注入 字符类型注入 单引号双引号解释 案例练习: 数字类型注入 案例 搜索性注入: 案例 XX性注入: 语句 案例 基础SQL注入类型分类 基础数据类型SQL注入 字符类型注入 xxx or 11 # select id,email from member where usernamexx or 11 # --…...
苹果AR眼镜:产品规划与战略路线深度解析
随着增强现实(AR)技术的不断发展,苹果公司正逐步推进其AR智能眼镜项目。尽管Vision Pro作为一款高端混合现实设备已经面世,但苹果真正的目标是开发出一款轻便、全天候佩戴且能够取代智能手机功能的AR眼镜。本文将梳理苹果在AR领域的探索历程,并分析其当前的产品状态及未来…...
HashMap讲解
在Java开发中,HashMap 是最常用的数据结构之一,它不仅提供了键值对的快速存储和检索功能,还具备较高的性能和较低的空间占用。但很多开发者对其底层原理并不清楚,今天我们将详细解析HashMap的内部结构,并用通俗的方式解…...
MySQL的复制
一、概述 1.复制解决的问题是让一台服务器的数据与其他服务器保持同步,即主库的数据可以同步到多台备库上,备库也可以配置成另外一台服务器的主库。这种操作一般不会增加主库的开销,主要是启用二进制日志带来的开销。 2.两种复制方式…...
Android View 的事件分发机制解析
前言:当一个事件发生时(例如触摸屏幕),事件会从根View(通常是Activity的布局中的最顶层View)开始,通过一个特定的路径传递到具体的View,这个过程涉及到三个关键的阶段:事…...
240. 搜索二维矩阵||
参考题解:https://leetcode.cn/problems/search-a-2d-matrix-ii/solutions/2361487/240-sou-suo-er-wei-ju-zhen-iitan-xin-qin-7mtf 将矩阵旋转45度,可以看作一个二叉搜索树。 假设以左下角元素为根结点, 当target比root大的时候ÿ…...
Linux C++
一、引言 冯诺依曼架构是现代计算机系统的基础,它的提出为计算机的发展奠定了理论基础。在学习 C 和 Linux 系统时,理解冯诺依曼架构有助于我们更好地理解程序是如何在计算机中运行的,包括程序的存储、执行和资源管理。这对于编写高效、可靠的…...
docker安装emqx
emqx安装 拉取emqx镜像 docker pull emqx/emqx:v4.1.0 运行docker容器 docker run -tid --name emqx -p 1883:1883 -p 8083:8083 -p 8081:8081 -p 8883:8883 -p 8084:8084 -p 18083:18083 emqx/emqx:v4.1.0 放行端口 1、如果要是自己的虚拟机,并且关闭了防火墙&a…...
Docker 仓库管理
Docker 仓库管理 引言 随着容器技术的兴起,Docker 已成为最流行的容器化平台之一。在Docker的生态系统中,仓库(Repository)是至关重要的组成部分。一个有效的仓库管理策略可以帮助开发者更高效地构建、测试、部署和管理容器应用。本文将深入探讨Docker仓库管理的相关知识…...
预测不规则离散运动的下一个结构
有一个点在19*19的平面上运动,运动轨迹为 一共移动了90步,顺序为 y x y x y x 0 17 16 30 10 8 60 15 15 1 3 6 31 10 7 61 14 15 2 12 17 32 9 9 62 16 15 3 4 12 33 10 9 63 18 15 4 3 18 34 15 12 6…...
DVC - 数据版本和机器学习实验的命令行工具和 VS Code 扩展
文章目录 一、关于 DVC二、快速启动三、DVC的工作原理四、VS代码扩展五、安装Snapcraft(Linux)Chocolatey (Windows)Brew (mac OS)Anaconda (Any platform)PyPI(Python)Package (Platform-specific)Ubuntu / Debian (deb)Fedora /…...
[C语言日寄] <stdio.h> 头文件功能介绍
在C语言的世界里,<stdio.h> 是一个极其重要的头文件,它提供了标准输入输出功能,是C语言程序与用户交互的核心工具。今天,我们就来深入探讨 <stdio.h> 的功能、使用注意事项以及它的拓展应用。 功能介绍 <stdio.h…...
c语言中mysql_query的概念和使用案例
在 C 语言中,使用 MySQL 数据库需要用到 MySQL C API。mysql_query() 函数是 MySQL C API 中的一个函数,用于执行 SQL 语句。 概念 mysql_query() 函数的原型如下: int mysql_query(MYSQL *mysql, const char *stmt_str)mysql:…...
「 机器人 」扑翼飞行器的数据驱动建模核心方法
前言 数据驱动建模可充分利用扑翼飞行器的已有运行数据,改进动力学模型与控制策略,并对未建模动态做出更精确的预测。在复杂的非线性飞行环境中,该方法能有效弥补传统解析建模的不足,具有较高的研究与应用价值。以下针对主要研究方向和实现步骤进行整理与阐述。 1. 数据驱动…...
C++ queue
队列用vector<int>好不好 不好 为什么? 因为队列是先进先出 vector没有提供头删(效率太低) 要强制适配也可以 就得用erase函数和begin函数了 库里面的队列是不支持vector<int>的 queue实现 #pragma once #include<vector…...
SpringBoot 配置文件
目录 一. 配置文件相关概念 二. 配置文件快速上手 1. 配置文件的格式 2. properties 配置文件 (1) properties 基本语法 (2) 读取配置文件内容 (3) properties 缺点分析 3. yml配置文件 (1) yml 基本语法 (2) 读取配置文件内容 (3) yml 配置对象 (4) yml 配置集合 …...
【Leetcode 每日一题】119. 杨辉三角 II
问题背景 给定一个非负索引 r o w I n d e x rowIndex rowIndex,返回「杨辉三角」的第 r o w I n d e x rowIndex rowIndex 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 数据约束 0 ≤ r o w I n d e x ≤ 33 0 \le rowIndex \le 33 …...
推荐七节来自NVIDIA、Google、斯坦福的AI课程
英伟达 (1)在 10 分钟内构建大脑 • 探索神经网络如何使用数据进行学习。 • 了解神经元背后的数学原理。 链接:https://learn.nvidia.com/courses/course-detail?course_idcourse-v1:DLIT-FX-01V1 (2)构建视频 A…...
HTML<kbd>标签
例子 在文档中将一些文本定义为键盘输入: <p>Press <kbd>Ctrl</kbd> <kbd>C</kbd> to copy text (Windows).</p> <p>Press <kbd>Cmd</kbd> <kbd>C</kbd> to copy text (Mac OS).</p>…...
HTML5+SVG+CSS3实现雪中点亮的圣诞树动画效果源码
源码介绍 这是一款基于HTML5SVGCSS3实现雪中点亮的圣诞树动画效果源码。画面中的圣诞树矗立在雪地中,天上飘落着雪花。当鼠标滑过圣诞树时,可见到圣诞树上的灯光闪烁,同时左下角探出雪怪模样的半个脑袋,四处张望着。整体画面栩栩…...
Android开发入门
文章目录 JetBrains历史沿革主营业务 KotlinSDKAndroid Studio特点功能 gradle9 Patch图片1. 作用和用途2. 创建9 Patch图片3. 在布局文件中使用9 Patch图片4. 注意事项 mipmap子目录AVD JetBrains JetBrains是一家成立于2000年的捷克软件开发公司,总部位于布拉格&…...
深度学习在金融风控中的应用:突破传统模型的瓶颈
深度学习在金融风控中的应用:突破传统模型的瓶颈 金融风险控制(简称“风控”)是现代金融体系中至关重要的一环,关系到金融机构的稳定性、客户的安全以及整体经济的健康运行。近年来,随着深度学习的迅猛发展,传统的风控模型正面临被颠覆的挑战,新的技术手段和思维方式正…...
Vim安装与配置教程(解决软件包Vim没有安装可候选)
Vim安装与配置教程(解决软件包Vim没有安装可候选)_软件包 vim 没有可安装候选-CSDN博客文章浏览阅读4.4k次,点赞70次,收藏47次。在Linux系统中,当我们使用apt-get install vim命令安装Vim 编辑器时,如果系统…...
探索AI(chatgpt、文心一言、kimi等)提示词的奥秘
大家好,我是老六哥,我正在共享使用AI提高工作效率的技巧。欢迎关注我,共同提高使用AI的技能,让AI成功你的个人助理。 "AI提示词究竟是什么?" 这是许多初学者在接触AI时的共同疑问。 "我阅读了大量关于…...
深入MapReduce——从MRv1到Yarn
引入 我们前面篇章有提到,和MapReduce的论文不太一样。在Hadoop1.0实现里,每一个MapReduce的任务并没有一个独立的master进程,而是直接让调度系统承担了所有的worker 的master 的角色,这就是Hadoop1.0里的 JobTracker。在Hadoop1…...
线段树 算法
文章目录 基础知识适用场景小结 题目概述题目详解300.最长递增子序列2407.最长递增子序列 II 基础知识 线段树和树状数组都只是一个工具来的,题目并不会一下子就告诉你这个题目用到线段树和树状数组,这个取决于你想使用的数据结构以及所要优化的方向 线…...
Redis实战(黑马点评)——redis存储地理信息、位图、HyperLogLog 用法
Redis存储geo数据类型基本介绍 geo 就是 geolocation 的简写形式,代表地理坐标。redis 在 3.2 版本中加入了对 geo 的支持,允许存储地理坐标信息,帮助我们根据经纬度来检索数据。常见的命令有: geoadd:添加一个地理空…...
Flutter_学习记录_基本组件的使用记录
1.TextWidge的常用属性 1.1TextAlign: 文本对齐属性 常用的样式有: TextAlign.center 居中TextAlign.left 左对齐TextAlign.right 有对齐 使用案例: body: Center(child: Text(开启 TextWidget 的旅程吧,珠珠, 开启 TextWidget 的旅程吧&a…...
C语言实现统计数组正负元素相关数据
在编程的世界里,对数组中元素的统计分析是常见的需求。今天,我们就来探讨一段用C语言实现的代码,它能统计数组中负数的个数以及正数的平均值。 代码功能概述 这段C语言代码的主要功能是:首先从用户处获取一个整数 n ,用…...
AJAX RSS Reader:技术解析与应用场景
AJAX RSS Reader:技术解析与应用场景 引言 随着互联网的快速发展,信息量呈爆炸式增长。为了方便用户快速获取感兴趣的信息,RSS(Really Simple Syndication)技术应运而生。AJAX RSS Reader作为一种基于AJAX技术的信息读取工具,在用户体验和信息获取方面具有显著优势。本…...
使用openwrt搭建ipsec隧道
背景:最近同事遇到了个ipsec问题,做的ipsec特性,ftp下载ipv6性能只有100kb, 正面定位该问题也蛮久了,项目没有用openwrt, 不过用了开源组件strongswan, 加密算法这些也是内核自带的,想着开源的不太可能有问题ÿ…...
将5分钟安装Thingsboard 脚本升级到 3.9
稍微花了一点时间,将5分钟安装Thingsboard 脚本升级到最新版本 3.9。 [rootlab5 work]# cat one-thingsboard.shell echo "test on RHEL 8.10 " source /work/java/install-java.shell source /work/thingsboard/thingsboard-rpm.shell source /work/po…...
Linux---架构概览
一、Linux 架构分层的深度解析 1. 用户空间(User Space) 用户空间是应用程序运行的环境,与内核空间隔离,确保系统稳定性。 应用程序层: 用户程序:如 edge、vim,通过调用标准库(如 …...
dnf妖气追踪找门方案
第一种 跟之前一样还是确定boss的 位置,但是妖气追踪有几个boss位置重复的思路就是分两大类第一类就是boss位置不一样的,第二类在boss位置一样的大类 下面再分一一个小类, 这个小类就是boss位置重复的下面判断 第一个门蓝色人的位置 来确定后面门的路线还有一种情况就是在选择…...
【C语言练习题】整数和实数在计算机中的二进制表示
1. 请写出下列十进制整数在计算机中的二进制存储形式(假设为16位整数): 32767: -1: 32768: -2: 答案: 0111111111111111 1111111111111111 1000000000000000 1111111111111110 解…...
OSCP:Windows 服务提权详解
在Windows操作系统中,服务是一种特殊的后台进程,它们通常以较高的权限(如 SYSTEM 或 Administrator)运行。攻击者可以通过控制服务的创建、配置或运行过程实现权限提升(提权)。本文将详细分析Windows服务提…...
寻找两个正序数组的中位数:分治法与二分查找的结合
寻找两个正序数组的中位数:分治法与二分查找的结合 在算法领域,“寻找两个正序数组的中位数” 是一道经典的高频面试题(LeetCode 第 4 题)。它不仅考察基本的数组操作,还涉及二分查找与分治思想的结合。今天ÿ…...
Python-基于PyQt5,json和playsound的通用闹钟
前言:刚刚结束2024年秋季学期的学习,接下来我们继续来学习PyQt5。由于之前我们已经学习了PyQt5以及PyUIC,Pyrcc和QtDesigner的安装,配置。所以接下来我们一起深入PyQt5,学习如何利用PyQt5进行实际开发-基于PyQt5,json和…...
51单片机开发:定时器中断
目标:利用定时器中断,每隔1s开启/熄灭LED1灯。 外部中断结构图如下图所示,要使用定时器中断T0,须开启TE0、ET0。: 系统中断号如下图所示:定时器0的中断号为1。 定时器0的工作方式1原理图如下图所示&#x…...
循序渐进kubernetes-RBAC(Role-Based Access Control)
文章目录 概要Kubernetes API了解 Kubernetes 中的 RBACRoles and Role Bindings:ClusterRoles and ClusterRoleBindings检查访问权限:外部用户结论 概要 Kubernetes 是容器化应用的强大引擎,但仅仅关注部署和扩展远远不够,集群的安全同样至…...
在Scene里面绘制编辑工具
功能要求 策划要在scene模式下编辑棋子摆放。用handle.GUI绘制来解决了。 问题 在scene模式下编辑产生的数据,进入游戏模式后就全不见了。改为executeAlways也没用。我的解决办法是把编辑数据序列化保存到本地。在OnEnable的时候再读取。但是我忽然想到ÿ…...
深入探索 Vue 3 Markdown 编辑器:高级功能与实现
目录 1. 为什么选择 Markdown 编辑器?2. 选择合适的 Markdown 编辑器3. 安装与基本配置安装 配置 Markdown 编辑器代码说明 4. 高级功能实现4.1 实时预览与双向绑定4.2 插入图片和图像上传安装图像上传插件配置图像上传插件 4.3 数学公式支持安装 KaTeX配置 KaTeX 插…...
动手学图神经网络(3):利用图神经网络进行节点分类 从理论到实践
利用图神经网络进行节点分类:从理论到实践 前言 在之前的学习中,大家对图神经网络有了初步的了解。本次教程将深入探讨如何运用图神经网络(GNNs)来解决节点分类问题。在节点分类任务里,大家往往仅掌握少量节点的真实标签,却要推断出其余所有节点的标签,这属于归纳式学…...
具身智能研究报告
参考: (1)GTC大会&Figure:“具身智能”奇点已至 (2)2024中国具身智能创投报告 (3)2024年具身智能产业发展研究报告 (4)具身智能行业深度:发展…...
LabVIEW春节快乐
尊敬的LabVIEW开发者与用户朋友们: 灵蛇舞动辞旧岁,春风送暖贺新年!值此癸巳蛇年新春佳节来临之际,向每一位深耕LabVIEW开发领域的伙伴致以最诚挚的祝福:愿您与家人在新的一年里平安顺遂、阖家幸福,事业如…...
MybatisX插件快速创建项目
一、安装插件 二、创建一个数据表测试 三、IDEA连接Mysql数据库 四、选择MybatiX构造器 五、配置参数 六、项目结构...
技术周总结 01.13~01.19 周日(Spring Visual Studio git)
文章目录 一、01.14 周二1.1)问题01:Spring的org.springframework.statemachine.StateMachine 是什么,怎么使用?:如何使用StateMachine: 1.2)问题02:Spring StateMachine 提供了一系列高级特性 …...
【C++】List的模拟实现
文章目录 1.ListNode 结构体2.List成员变量与typedef3.迭代器iterator4.begin()、end()、size()、empty()、构造函数5. insert()、erase()6.push_back()、pop_back()、push_front()、pop_front()7.拷贝构造、赋值、析构8.总代码 以后有时间会更新其它成员函数 1.ListNode 结构…...
剑指 Offer II 002. 二进制加法
comments: true edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20002.%20%E4%BA%8C%E8%BF%9B%E5%88%B6%E5%8A%A0%E6%B3%95/README.md 剑指 Offer II 002. 二进制加法 题目描述 给定两个 01 字符串 a 和 b ,请计算…...