图神经网络实战——基于DeepWalk创建节点表示

news2024/9/30 13:22:45

图神经网络实战——基于DeepWalk创建节点表示

    • 0. 前言
    • 1. Word2Vec
      • 1.1 CBOW 与 skip-gram
      • 1.2 构建 skip-gram 模型
      • 1.3 skip-gram 模型
      • 1.4 实现 Word2Vec 模型
    • 2. DeepWalk 和随机行走
    • 3. 实现 DeepWalk
    • 小结
    • 系列链接

0. 前言

DeepWalk 是机器学习 (machine learning, ML) 技术在图数据中的成功应用之一,其引入了嵌入等重要概念,这些概念是图神经网络 (Graph Neural Network, GNN) 的核心。与传统的神经网络不同,这种架构的目标是产生表示 (representations),然后将其传递给其他模型执行下游任务(例如节点分类)时使用。
在本节中,我们将了解 DeepWalk 架构及其两个主要组件: Word2Vec 和随机游走 (random walks)。首先介绍 Word2Vec 架构的工作原理,并重点介绍 skip-gram 模型,并在自然语言处理 (natural language processing, NLP) 任务中使用 gensim 库实现 skip-gram 模型,以了解其使用方法。然后,我们将重点研究 DeepWalk 算法,学习如何使用分层 softmax (hierarchical softmax, H-Softmax) 提高性能。然后在图上实现随机游走,最后使用 “Zachary’s Karate Club” 数据集实现一个端到端的监督节点分类模型。

1. Word2Vec

理解 DeepWalk 算法的第一步是了解其主要组成部分: Word2VecWord2VecNLP 领域最具影响力的深度学习技术之一,该技术由 Tomas Mikolov 等人于 2013 年提出,是一种利用大规模文本数据集将单词转化为向量( vectors,也称为嵌入,embeddings )表示的技术,这种单词表示可用于情感分类等下游任务。
使用 Word2Vec 将单词转化为向量的示例如下:
v e c ( k i n g ) = [ − 2.0 , 4.2 , 0.5 ] v e c ( q u e e n ) = [ − 1.8 , 2.7 , 1.4 ] v e c ( m a n ) = [ 2.9 , − 1.0 , − 1.9 ] v e c ( w o m a n ) = [ 2.8 , − 2.6 , − 1.0 ] vec(king) = [−2.0, 4.2, 0.5]\\ vec(queen) = [−1.8, 2.7, 1.4]\\ vec(man) = [2.9,−1.0, −1.9]\\ vec(woman) = [2.8,−2.6,−1.0]\\ vec(king)=[2.0,4.2,0.5]vec(queen)=[1.8,2.7,1.4]vec(man)=[2.9,1.0,1.9]vec(woman)=[2.8,2.6,1.0]

在以上例子中,就欧氏距离而言,kingqueen 的词向量比 kingwoman 的词向量更接近。在实践中,我们通常会使用其他更精确的度量方法来衡量这些词的相似度,例如常用的余弦相似度 (cosine similarity)。余弦相似度关注的是向量之间的角度,而不考虑它们的大小(长度):
c o s i n e   s i m i l a r i t y ( A ⃗ , B ⃗ ) = c o s ( θ ) = A ⃗ ⋅ B ⃗ ∣ ∣ A ⃗ ∣ ∣ ⋅ ∣ ∣ B ⃗ ∣ ∣ cosine\ similarity(\vec A,\vec B)=cos(\theta)=\frac {\vec A \cdot \vec B} {||\vec A||\cdot ||\vec B||} cosine similarity(A ,B )=cos(θ)=∣∣A ∣∣∣∣B ∣∣A B
Word2Vec 能够解决类比问题,最著名的例子是,它可以回答 "man is to woman, what king is to ___?"的问题。计算方法如下:
v e c ( k i n g ) − v e c ( m a n ) + v e c ( w o m a n ) ≈ v e c ( q u e e n ) vec(king)-vec(man)+vec(woman)≈vec(queen) vec(king)vec(man)+vec(woman)vec(queen)
当然这种性质并不适用于所有类比问题,但这一特性可以为嵌入算术运算带来有趣的应用。

1.1 CBOW 与 skip-gram

为了生成这些向量,模型必须在一个前置任务上进行训练。任务本身并不需要有实际意义,其唯一目标就是生成高质量的嵌入向量。在实践中,这个任务通常与根据特定上下文预测单词相关。通常,可以使用两种具有类似任务的架构:

  • 连续词袋 (continuous bag-of-words, CBOW) 模型: 模型的训练目标是利用周围上下文(目标单词前后的单词)预测一个单词。上下文单词的顺序并不重要,因为它们的嵌入向量会在模型中求和。实践表明,使用预测单词前后的四个单词进行预测时,可以获得更好的结果
  • 连续 skip-gram (continuous skip-gram, skip-gram)模型: 模型的训练目标是根据一个输入单词预测其上下文单词。增加上下文单词的范围可以获得更好的嵌入向量,但也会增加训练时间

两种模型的输入和输出如下所示:

模型对比

通常,CBOW 模型的训练速度更快,但是由于 skip-gram 模型具有学习不常见单词的能力,因此更加准确。

1.2 构建 skip-gram 模型

由于 DeepWalk 采用的是 skip-gram 架构,因此我们现在将重点学习 skip-gram 模型。skip-gram 使用具有以下结构的单词对:(target word, context word),其中 target word 是输入词,context word 是要预测的词。同一目标词的 skip-gram 数量取决于参数上下文大小 (context size),如下图所示:

Skip-gram

这一单词对结构可以从单个句子扩展至整个文本语料库。为了节省内存,我们将同一目标词的所有上下文词存储在一个列表中。接下来,我们以整个段落为例构建单词对,为存储在 text 变量中的整个段落创建 skip-gram 单词对。将 CONTEXT_SIZE 变量设置为 2,即查看目标单词前后的两个单词。

(1) 导入所需库:

import numpy as np

(2)CONTEXT_SIZE 变量设置为 2,并导入要分析的文本 text

CONTEXT_SIZE = 2
text = """Tears came to my eyes as I realized what I had been a fool to judge Al as a failure. He had not left any material possessions behind. But he had been a kind loving father, and left behind his best love.""".split()

(3) 通过一个简单的 for 循环创建 skip-gram 单词对,以考虑 text 中的每个单词。使用列表推导式生成上下文单词,并存储在 skipgrams 列表中:

# Create skipgrams
skipgrams = []
for i in range(CONTEXT_SIZE, len(text) - CONTEXT_SIZE):
    array = [text[j] for j in np.arange(i - CONTEXT_SIZE, i + CONTEXT_SIZE + 1) if j != i]
    skipgrams.append((text[i], array))

(4) 使用 print() 函数查看生成的 skipgrams

print(skipgrams[0:2])

输出结果如下,观察这两个目标单词及其相应的上下文可以了解 Word2Vec 的输入-输出形式:

[('to', ['Tears', 'came', 'my', 'eyes']), ('my', ['came', 'to', 'eyes', 'as'])]

1.3 skip-gram 模型

Word2Vec 的目标是生成高质量的单词嵌入。为了学习这些嵌入,skip-gram 模型的训练目标是根据目标词预测正确的上下文单词。
假设,我们有一个由 N N N 个单词组成的序列 w 1 , w 2 , . . . , w N w_1, w_2 ,..., w_N w1,w2,...,wN。在给定单词 w 2 w_2 w2 的情况下,得到单词 w 2 w_2 w2 的概率为 p ( w 2 ∣ w 1 ) p(w_2|w_1) p(w2w1)。我们的目标是最大化整个文本中给定目标单词时得到每个上下文单词的概率之和:
1 N ∑ n = 1 N ∑ − c ≤ j ≤ c , j ≠ 0 log ⁡ p ( w n + j ∣ w n ) \frac 1 N\sum_{n=1}^N\sum_{-c≤j≤c,j≠0}\log p(w_{n+j}|w_n) N1n=1Ncjc,j=0logp(wn+jwn)
其中 c c c 是上下文向量的大小。那么,为什么我们要在以上等式中使用对数概率?将概率转换为对数概率是机器学习中的常用技术,主要有两个原因:

  • 乘法的计算成本比加法高,而使用对数可以将乘法转换为加法(除法转换为减法),因此计算对数概率更快:
    log ⁡ ( A × B ) = log ⁡ ( A ) + log ⁡ ( B ) \log (A\times B)=\log(A)+\log(B) log(A×B)=log(A)+log(B)
  • 计算机存储非常小的数字(如 3.14e-128 )的方式并不完全准确,当事件发生的可能性极小时,这些微小的误差就会累积起来,使最终结果产生偏差。而使用对数则不同,当结果同样为 3.14e-128 时,使用对数后结果为 -127.5 (log3.14e-128=-127.5)

总的来说,将概率转换为对数概率可以在不改变初始目标的情况下提高速度和准确性。

原始 skip-gram 模型使用 softmax 函数来计算给定目标单词嵌入 h t h_t ht 的情况下,上下文单词嵌入 h c h_c hc 的概率:
p ( w c ∣ w t ) = exp ⁡ ( h c h t T ) ∑ i = 1 ∣ V ∣ exp ⁡ ( h i h t T ) p(w_c|w_t)=\frac {\exp(h_ch_t^T)}{\sum_{i=1}^{|V|}\exp(h_ih_t^T)} p(wcwt)=i=1Vexp(hihtT)exp(hchtT)
其中, V V V 是大小为 ∣ V ∣ |V| V 的词汇表,词汇表 (vocabulary) 是指在一个文本语料库中出现的所有单词的集合。可以使用集合数据结构去除重复的单词,获得词汇表:

vocab = set(text)
VOCAB_SIZE = len(vocab)
print(f"Length of vocabulary = {VOCAB_SIZE}")
# Length of vocabulary = 33

得到词汇表大小后,还需要定义参数 N N N,用于表示单词向量的维度。通常情况下,这个值设置在 1001000 之间。在本节中,由于数据集的规模有限,将其设置为 10
skip-gram 模型仅由两层组成:

  • 权重为 W e m b e d W_{embed} Wembed 的投影层 (projection layer),将独热 (one-hot) 编码词向量作为输入,并返回相应的 N N N 维词嵌入。它就像一个简单的查找表,存储预定维度的嵌入
  • 权重为 W o u t p u t W_{output} Woutput 的全连接层 (fully connected layer),将词嵌入作为输入,并输出 ∣ V ∣ |V| Vlogits。对预测结果应用 softmax 函数,将 logits 转换为概率

skip-gram 中没有激活函数:Word2Vec 是一种线性分类器,可以模拟单词之间的线性关系。
将独热编码的单词向量称为输入 x x x,相应的单词嵌入可以通过简单的投影计算得出:
h = W e m b e d T ⋅ x h=W_{embed}^T\cdot x h=WembedTx
利用 skip-gram 模型,可以将以上概率改写如下:
p ( w c ∣ w t ) = exp ⁡ ( W o u t p u t T ⋅ x ) ∑ i = 1 ∣ V ∣ exp ⁡ ( W o u t p u t ( i ) ⋅ h ) p(w_c|w_t)=\frac {\exp(W_{output}^T\cdot x)} {\sum_{i=1}^{|V|}\exp(W_{output_{(i)}}\cdot h)} p(wcwt)=i=1Vexp(Woutput(i)h)exp(WoutputTx)
skip-gram 模型会输出一个 ∣ V ∣ |V| V 维向量,它是词汇表中每个单词的条件概率:
w o r d 2 v e c ( w t ) = [ p ( w 1 ∣ w t ) p ( w 2 ∣ w t ) ⋮ p ( w ∣ v ∣ ∣ w t ) ] word2vec(w_t)=\begin{bmatrix} p(w_1|w_t)\\ p(w_2|w_t)\\ \vdots \\ p(w_{|v|}|w_t) \end{bmatrix} word2vec(wt)= p(w1wt)p(w2wt)p(wvwt)
在训练过程中,这些概率会与正确的独热编码目标单词向量进行比较。这些值之间的差异(由损失函数计算,如交叉熵损失)通过网络反向传播,以更新权重并获得更好的预测结果。

1.4 实现 Word2Vec 模型

Word2Vec 的整体架构如下所示,包括两个权重矩阵(包括 W e m b e d W_{embed} Wembed 和 $W_{output} )和最后的 softmax 层:

Word2Vec 架构

接下来,使用 gensim 库实现 Word2Vec 模型,然后根据上一小节的文本构建词汇表并训练模型。gensim 库的安装和其他第三方库一样,可以在 shell 中执行以下命令进行安装:

pip install gensim

(1) 导入 Word2Vec 类:

from gensim.models.word2vec import Word2Vec

(2) 使用对象 Word2Vec 和参数 sg=1 (skip-gram = 1) 初始化 skip-gram 模型:

model = Word2Vec([text],
                 sg=1,   # Skip-gram
                 vector_size=10,
                 min_count=0,
                 window=2,
                 workers=1)

(3) 检查权重矩阵 W_embed 的形状,其应该与词汇量大小和词嵌入维度相对应:

print(f'Shape of W_embed: {model.wv.vectors.shape}')
# Shape of W_embed: (33, 10)

(4) 对模型训练 10epoch

model.train([text], total_examples=model.corpus_count, epochs=10)

(5) 最后,打印一个单词嵌入,观察训练结果:

print('\nWord embedding =')
print(model.wv[0])

输出结果如下:

Word embedding =
[-0.00495417 -0.00025058  0.05408746  0.08913884 -0.09218638 -0.07153394
  0.06835324  0.09274287 -0.05681597 -0.04169786]

虽然这种方法在处理小词汇量时效果很好,但在大多数情况下,对数百万个单词(词汇量)应用完整 softmax 函数的计算成本太高,这一直是开发精确语言模型的限制因素之一,但我们可以通过其他方法来解决这个问题。
Word2VecDeepWalk 通过实现 H-Softmax 技术解决此问题。与直接计算每个单词的概率的 softmax 不同,H-Softmax 技术采用二叉树结构,其中叶子节点是单词。此外,还可以使用哈夫曼树,将不常见的单词存储在比常见单词更深的层次上。在大多数情况下,这种方法可以将单词预测速度提高至少 50 倍。在 gensim 中,可以通过指定 hs=1 使用 H-Softmax

2. DeepWalk 和随机行走

DeepWalk2014 年由 Perozzi 等人提出,并很快在图学习中大受欢迎,它在多个数据集上的表现始终优于其他方法。虽然之后研究人员又提出了其他性能更高的架构,但 DeepWalk 作为一种简单可靠的基准方法,能够快速实现并解决大量问题。
DeepWalk 的目标是以无监督的方式生成高质量的节点特征表示。这一架构在很大程度上受到了 NLPWord2Vec 的启发。但 DeepWalk 所用的数据集由节点组成,而不是单词,因此我们想要使用随机游走来生成类似句子的有意义的节点序列。句子和图之间的联系如下所示:

句子和图

随机游走是通过在每一步随机选择一个相邻节点而生成的节点序列。因此,节点可以在同一序列中出现多次。
即使节点是随机选择的,但它们经常一起出现在一个序列中,就意味着它们彼此接近。根据网络同质性 ( network homophily) 假说,相互接近的节点是相似的。这在社交网络中尤为明显,因为在社交网络中,人们会倾向于与朋友和家人建立联系。
DeepWalk 算法的核心理念在于:当节点彼此接近时,我们希望相似度得分较高;相反,当节点之间距离较远时,我们希望相似度得分较低。接下来,我们使用 networkx 库实现随机游走函数。

(1) 导入所需的库:

import networkx as nx
import matplotlib.pyplot as plt
import random

(2) 利用 erdos_renyi_graph 函数生成一个随机图,图中节点数量固定 (10),节点之间建立边的概率为 0.3

G = nx.erdos_renyi_graph(10, 0.3, seed=1, directed=False)

(3) 绘制所生成的随机图:

nx.draw_networkx(G, pos=nx.spring_layout(G))
plt.axis('off')
plt.show()

随即图

(4) 实现随机游走函数,函数使用两个参数:起始节点 (start) 和游走长度 (length)。每走一步,我们都会使用 np.random.choice 随机选择一个相邻节点,直到游走完成:

def random_walk(start, length):
    walk = [str(start)]  # starting node
    
    for i in range(length):
        neighbors = [node for node in G.neighbors(start)]
        next_node = np.random.choice(neighbors, 1)[0]
        walk.append(str(next_node))
        start = next_node
    
    return walk

(5) 打印函数执行结果,起始节点为 0,长度为 10

print(random_walk(0, 10))

输出结果如下:

['0', '9', '0', '4', '3', '4', '3', '6', '2', '5', '6']

可以看到某些节点,如 09 经常出现在一起。考虑到这是一个同构图,这意味着它们是相似的,这正是 DeepWalk 试图捕捉的关系类型。

3. 实现 DeepWalk

了解了 DeepWalk 架构中的每个组件后,实现 DeepWalk 解决一个实际的机器学习问题。我们使用 Zachary’s Karate Club 数据集,它简单地表示了 Wayne W. Zachary 研究的一个空手道俱乐部内部的关系。这是一种社交网络,其中的每个节点都是一个成员,而在俱乐部之外进行互动的成员则被连接在一起。
在本例中,俱乐部被分为两组:我们希望通过查看每个成员的连接,将每个成员分配到正确的组中(即节点分类,node classification)。

(1) 使用 nx.karate_club_graph() 导入数据集:

G = nx.karate_club_graph()

(2) 将字符串类标签转换成数值 (Mr. Hi = 0Officer = 1):

labels = []
for node in G.nodes:
    label = G.nodes[node]['club']
    labels.append(1 if label == 'Officer' else 0)

(3) 使用新标签绘制图:

plt.axis('off')
nx.draw_networkx(G, pos=nx.spring_layout(G, seed=0), node_color=labels)
plt.show()

标签图

(4) 接下来,生成随机游走数据集,为图中的每个节点创建 80 个长度为 10 的随机游走序列:

walks = []
for node in G.nodes:
    for _ in range(80):
        walks.append(random_walk(node, 10))

(5) 打印一个随机游走序列,验证其正确性:

print(walks[0])
# ['0', '1', '30', '1', '3', '12', '3', '7', '3', '0', '17']

(6) 实现 Word2Vec,使用 skip-gram 模型,可以调整其他参数,以提高嵌入质量:

model = Word2Vec(walks,
                 hs=1,   # Hierarchical softmax
                 sg=1,   # Skip-gram
                 vector_size=100,
                 window=10,
                 workers=1)

(7) 在生成的随机游走序列上对模型进行简单的训练:

# Build vocabulary
model.build_vocab(walks)
# Train model
model.train(walks, total_examples=model.corpus_count, epochs=30, report_delay=1)

(8) 模型训练完成后,可以将其应用在不同任务中。例如,查找与给定节点最相似的节点(根据余弦相似度):

print('Nodes that are the most similar to node 0:')
for similarity in model.wv.most_similar(positive=['0']):
    print(f'   {similarity}')

输出结果如下所示:

输出

另一个重要应用是计算两个节点之间的相似度得分:

print(f"\nSimilarity between node 0 and 4: {model.wv.similarity('0', '4')}")
# Similarity between node 0 and 4: 0.6553224921226501

可以使用 t-distributed stochastic neighbor embedding (t-SNE) 绘制嵌入结果,从而将这些高维向量可视化为二维图像:

(1)sklearn 中导入 TSNE 类:

from sklearn.manifold import TSNE

(2) 创建两个数组:一个用于存储单词嵌入,另一个用于存储标签:

nodes_wv = np.array([model.wv.get_vector(str(i)) for i in range(len(model.wv))])
labels = np.array(labels)

(3) 在嵌入上训练 2 维 (n_components=2) t-SNE 模型:

tsne = TSNE(n_components=2,
            learning_rate='auto',
            init='pca',
            random_state=0).fit_transform(nodes_wv)

(4) 将训练好的 t-SNE 模型生成的二维向量与相应的标签绘制成二维图像:

plt.figure(figsize=(6, 6))
plt.scatter(tsne[:, 0], tsne[:, 1], s=100, c=labels)
plt.show()

分类结果

可以看到使用一条简单的线就能够将两个类别区分开来。只要有足够的训练数据,简单的机器学习算法就能对这些节点进行分类。接下来,我们实现一个分类器,并对节点嵌入进行训练。

(1)sklearn 中导入随机森林 (Random Forest) 模型,使用准确率作为模型评估的指标:

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

(2) 将嵌入数据分成两组:训练数据和测试数据。一个简单的方法是创建如下掩码:

train_mask = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]
test_mask = [0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 26, 27, 28, 29, 30, 31, 32, 33]

(3) 在训练数据上训练随机森林分类器:

clf = RandomForestClassifier(random_state=0)
clf.fit(nodes_wv[train_mask], labels[train_mask])

(4) 在测试数据上根据准确率评估训练好的模型:

y_pred = clf.predict(nodes_wv[test_mask])
acc = accuracy_score(y_pred, labels[test_mask])
print(f'Accuracy = {acc*100:.2f}%')
# Accuracy = 95.45%

可以看到,模型准确率为 95.45%,虽然仍有改进的余地,但本例展示了 DeepWalk 的两个应用:

  • 使用嵌入和余弦相似性发现节点之间的相似性(无监督学习)
  • 将嵌入数据集用作节点分类等监督任务

学习节点表示可以为设计更深入、更复杂的架构提供了更大的灵活性。

小结

在本节中,我们了解了 DeepWalk 架构及其主要组件。然后,使用随机游走将图数据转化为序列,并应用了 Word2Vec 算法,使用图的拓扑信息创建节点嵌入,得到的嵌入结果可用于发现节点间的相似性,或作为其他算法的输入。最后,我们使用监督方法解决了节点分类问题。

系列链接

图神经网络实战——图神经网络(Graph Neural Networks, GNN)基础
图神经网络实战——图论基础

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

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

相关文章

Java虚拟机(JVM)从入门到实战【上】

Java虚拟机(JVM)从入门到实战【上】,涵盖类加载,双亲委派机制,垃圾回收器及算法等知识点,全系列6万字。 一、基础篇 P1 Java虚拟机导学课程 P2 初识JVM 什么是JVM Java Virtual Machine 是Java虚拟机。…

2024.03.01作业

1. 基于UDP的TFTP文件传输 #include "test.h"#define SER_IP "192.168.1.104" #define SER_PORT 69 #define IP "192.168.191.128" #define PORT 9999enum mode {TFTP_READ 1,TFTP_WRITE 2,TFTP_DATA 3,TFTP_ACK 4,TFTP_ERR 5 };void get_…

javaWebssh在线授课辅导系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh在线授课辅导系统是一套完善的web设计系统(系统采用ssh框架进行设计开发),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用 B/S模式开发。开发环境为TOMCAT7.…

ESP-01S烧录AT指令

一、准备工具 硬件工具 1、ESP32-01S 2、USB转TTL线(也可以用USB转TTL模块,我这里是没有,所以没有用) 红线5V黑线GND白线RXD绿线TXD 3、单片机(用途后面说) 软件工具 4、首先打开->安信可官网下载E…

开源模型Mistral 7B+Amazon SageMaker部署指南

一、Mistral 7B简述 Mistral AI 是一家总部位于法国的 AI 公司,其使命是将公开可用的模型提升至最先进的性能水平。他们专注于构建快速而安全的大型语言模型(LLM),此类模型可用于从聊天机器人到代码生成等各种任务。不久前其发布…

洛谷p1225 c++(使用高精度)

题解: 一开始我这个代码想到的是使用递归来求解 int digui(int n){int sum=0;if(n==1)sum=1;if(n==2)sum=2;if(n==1||n==2)return sum;if(n>2){return sum+=digui(n-1)+digui(n-2);} } 但是后面发现明显超时,我试图用记忆化搜索来抢救一下,所以就有了下面代码 int di…

Benchmark学习笔记

小记一篇Benchmark的学习笔记 1.什么是benchmark 在维基百科中,是这样子讲的 “As computer architecture advanced, it became more difficult to compare the performance of various computer systems simply by looking at their specifications.Therefore, te…

实战:Oracle Weblogic 11g 安装部署(10.3.6.0)

导读 本文介绍在redhat linux 6.6上安装Oracle weblogic 11g(10.3.6.0)版本 环境:redhat6.6 jdk 1.7 1、下载webLogic10.3.6 http://www.oracle.com/technetwork/cn/middleware/weblogic/downloads/wls-main-091116-zhs.html2 、在linux的ro…

win11系统中nginx简单的代理配置

一.背景 为了公司安排的师带徒任务。 操作系统版本:win11家庭版 nginx版本:1.24.0 二.配置代理 之前文章已经说明了nginx简单的安装,要看阅读这个文章哈。web服务器nginx下载及在win11的安装-CSDN博客 1.配置需求识别 前端服务nginx(80…

Java进阶-IO(3)

话接上回,继续java IO的学习。上一次说完了字符流的读写数据,这次将基础部分剩余的一点内容看完。 一、流按功能分类 1、系统流 1.1 概述 系统流的类为 java.lang.System。Sytem 类封装了 Java 程序运行时的 3 个系统流。 System.in:标…

Vue3快速上手(十六)Vue3路由传参大全

Vue3路由传参 一、传参的多种方式 1.1 拼接方式 这种方式适合传递单个参数的情况&#xff0c;比如点击查看详情&#xff0c;传个id这样的场景 传参&#xff1a; <RouterLink to"/person?id1" active-class"active">person</RouterLink> …

类与对象(一)

目录 1 什么是面向过程和面向对象 1.1举例 2类的引入 3类的定义 3.1类的两种定义方式&#xff1a; 4.类的访问限定符及封装 4.1访问限定符 4.1.1为什么要有访问限定符 4.1.2有哪些访问限定符呢&#xff1f; 4.1.3简单举例理解 4.1.4C中的class与struct的区别(面试问题…

使用pyannote-audio实现声纹分割聚类

使用pyannote-audio实现声纹分割聚类 # GitHub地址 https://github.com/MasonYyp/audio1 简单介绍 pyannote.audio是用Python编写的用于声纹分割聚类的开源工具包。在PyTorch机器学习基础上&#xff0c;不仅可以借助性能优越的预训练模型和管道实现声纹分割聚类&#xff0c;还…

图解Vivado工程的目录结构

一、目录结构 ​在使用Vivado进行工程设计时&#xff0c;创建工程以及运行工程的过程中都会生成大量的目录和文件&#xff0c;下面图将对目录和文件结构及功能进行一个简单说明。 工程示例图 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 二、参考资料…

windows下安装cnpm

cnpm是淘宝团队开发的一个针对中国用户的npm镜像源&#xff0c;它是npm的一个定制版本。由于国外的npm源在国内访问速度较慢&#xff0c;所以cnpm镜像源可以提供更快的下载速度。cnpm的使用方式与npm基本相同&#xff0c;只需将npm替换为cnpm即可。 要想使用cnpm等先安装node.…

面试准备:排序算法大汇总 C++

排序算法总结 直接插入排序 取出未排序部分的第一个元素&#xff0c;与已排序的部分从后往前比较&#xff0c;找到合适的位置。将大于它的已排序的元素向后移动&#xff0c;将该元素插入到合适的位置。 //1. 直接插入排序 void InsertionSort(vector<int>& nums){f…

如何确保JDK版本与操作系统架构匹配?

1. 序言 最近的工作中&#xff0c;需要升级JDK版本到17.0.7&#xff0c;以解决一个JDK bug&#xff1a;JDK-8299626该bug的core dump关键字如下&#xff1a;SIGSEGV in PhaseIdealLoop::build_loop_late_post_work公司JDK团队提供的、包含JDK的基础镜像&#xff0c;有aarch64和…

深入了解Java虚拟机(JVM)

Java虚拟机&#xff08;JVM&#xff09;是Java程序运行的核心组件&#xff0c;它负责解释执行Java字节码&#xff0c;并在各种平台上执行。JVM的设计使得Java具有跨平台性&#xff0c;开发人员只需编写一次代码&#xff0c;就可以在任何支持Java的系统上运行。我们刚开始学习Ja…

Launch学习

参考博客&#xff1a; (1) 史上最全的launch的解析来啦&#xff0c;木有之一欧 1 ROS工作空间简介 2 元功能包 src目录下可以包含多个功能包&#xff0c;假设需要使用机器人导航模块&#xff0c;但是这个模块中包含着地图、定位、路径规划等不同的功能包&#xff0c;它们的逻…

【Python】1. 背景知识

认识 Python 计算机基础概念 什么是计算机? 很多老一辈的人, 管下面这个叫做计算机. 然鹅, 它只是 “计算器”, 和计算机是有很大区别的. 现在我们所说的计算机, 不光能进行算术运算, 还能进行逻辑判断, 数据存储, 网络通信等等功能,。 以至于可以自动的完成非常复杂的工作…