GCN 代码解析(一) for pytorch

请添加图片描述

Graph Convolutional Networks 代码详解

  • 前言
  • 一、数据集介绍
  • 二、文件整体架构
  • 三、GCN代码详解
    • 3.1 utils 模块
    • 3.2 layers 模块
    • 3.3 models 模块
    • 3.4 模型的训练代码
  • 总结

前言

在前文中,已经对图卷积神经网络(Graph Convolutional Neural Networks, GCN)的理论基础进行了深入探讨。接下来的章节将会进入新的阶段——将借助PyTorch,这一强大的深度学习框架,通过实战讲解来展示如何构建和训练一个图卷积神经网络。这一过程不仅将帮助读者巩固理论知识,更重要的是,它将引导读者迈出理论到实践的关键一步,从而在处理具有图结构数据的问题上实现质的飞跃。

通过本章节的学习,希望读者能够掌握图神经网络在代码层面的具体实现方法,并通过实际编码练习来加深对图神经网络工作原理的理解。我们将从数据准备开始,逐步深入到模型构建、训练和评估等核心环节,最终实现一个功能完整的图卷积神经网络项目。

一、数据集介绍

在学习模型是如何工作之前要明确模型的任务是什么?本文使用的是使用论文引用数据集中从而完成论文的分类任务。

首先看下数据集的形态,这个目录包含了Cora数据集(www.research.whizbang.com/data)的一个部分选择。

Cora数据集由机器学习论文组成。这些论文被分类为以下七个类别之一:

  • 基于案例的(Case_Based)
  • 遗传算法(Genetic_Algorithms)
  • 神经网络(Neural_Networks)
  • 概率方法(Probabilistic_Methods)
  • 强化学习(Reinforcement_Learning)
  • 规则学习(Rule_Learning)
  • 理论(Theory)

选择论文的方式是,最终的语料库中每篇论文至少引用或被至少一篇其他论文引用。整个语料库中共有2708篇论文。

经过词干提取和去除停用词后,我们得到了一个包含1433个唯一词汇的词汇表。所有文档频率小于10的词汇都被移除。

目录包含两个文件:

在这里插入图片描述

.content文件包含论文的描述,格式如下:

<paper_id> <word_attributes>+ <class_label>

文件预览入下图:

请添加图片描述

每行的第一个条目包含论文的唯一字符串ID,后面是二进制值,指示词汇表中的每个单词是否出现在论文中(出现则表示为1,缺乏则表示为0)。最后,行中的最后一个条目包含论文的类别标签。

.cites文件包含语料库的引用图。每行以以下格式描述一个链接:

<ID of cited paper><ID of citing paper>

每行包含两个论文ID。第一个条目是被引用论文的ID,第二个ID代表包含引用的论文。链接的方向是从右向左。如果一行表示为“paper1 paper2”,则链接是“paper2->paper1”。

文件预览形式如下:

请添加图片描述

二、文件整体架构

为了深入学习图卷积神经网络(GCN)的编码实践,本章节将借助脑图形式,详细总结代码文件中的关键模块及其相互关联。这样做旨在将代码的各个组成部分串联起来,使得学习路径更加系统化。故此讲解的过程中也是按照脑图的顺序进行梳理,从而对代码具备一个全面正确的认识。

在这里插入图片描述
模型的训练启动于utils文件,它负责对原始数据执行预处理步骤,生成便于模型训练和操作的格式化数据。接着,在layers文件中,我们按照GCN论文的指导,精心构建了图卷积网络层。这些网络层随后在models文件中被整合起来,形成一个完整的图卷积神经网络架构。最后,在train脚本中,我们执行模型的训练和评估,完成了从数据预处理到模型应用的整个流程。

三、GCN代码详解

接下来,将根据之前提及的不同文件及其顺序,深入剖析整个图卷积神经网络(GCN)的代码实现。这一过程将揭示每个组件的功能及其在整个模型中所扮演的角色。

3.1 utils 模块

import numpy as np
import scipy.sparse as sp
import torch

在模型的初始阶段,首先导入三个关键的库来处理数据和构建模型:

  1. numpy:此库非常适合进行高效的**矩阵运算和数学处理。**通过导入为 np,调用NumPy库提供的各种数学功能,它是Python科学计算的基石。

  2. scipy.sparse:通常简称为 sp,这个模块专注于稀疏矩阵的操作。在处理图数据时,邻接矩阵往往是稀疏的,使用稀疏矩阵能够有效地提升存储和计算效率。

  3. torch:作为PyTorch框架的核心,它提供了一系列深度学习的基本工具和操作。使用PyTorch中的数据结构和函数,我们可以将数据转换为张量格式,并利用GPU加速计算过程。

通过这三个库的结合,能够高效地处理图数据,并将其转换为适用于PyTorch的格式,为图卷积神经网络的建模打下基础。

def encode_onehot(labels):classes = set(labels) #  a = set('abracadabra') 去除重复元素 >>> a                                  # {'a', 'r', 'b', 'c', 'd'}classes_dict = {c: np.identity(len(classes))[i, :] for i, c in enumerate(classes)} # 创建一个字典用来存放所有类别对应的独热编码'''import numpy as npa=np.identity(3)
print(a)# result[[1. 0. 0.][0. 1. 0.][0. 0. 1.]]'''labels_onehot = np.array(list(map(classes_dict.get, labels)), #  map() 会根据提供的函数对指定序列做映射。dtype=np.int32)return labels_onehot

以上代码展示了将标签转换成独热编码的过程。

def normalize(mx):"""Row-normalize sparse matrix"""rowsum = np.array(mx.sum(1)) # 按行求和r_inv = np.power(rowsum, -1).flatten() # 倒数拉长并且降维r_inv[np.isinf(r_inv)] = 0. # 将所有无穷∞大的量替换为0r_mat_inv = sp.diags(r_inv) 
'''diagonals = [[1, 2, 3, 4], [1, 2, 3], [1, 2]]  
# 使用diags函数,该函数的第二个变量为对角矩阵的偏移量,
0:代表不偏移,就是(0,0)(1,1)(2,2)(3,3)...这样的方式写
k:正数:代表像正对角线的斜上方偏移k个单位的那一列对角线上的元素。
-k:负数,代表向正对角线的斜下方便宜k个单位的那一列对角线上的元素,由此看下边输出diags(diagonals, [0, -1, 2]).toarray()
array([[1, 0, 1, 0],[1, 2, 0, 2],[0, 2, 3, 0],[0, 0, 3, 4]])'''mx = r_mat_inv.dot(mx) # 矩阵乘法运算return mx # 返回归一化后的数据
def sparse_mx_to_torch_sparse_tensor(sparse_mx):"""Convert a scipy sparse matrix to a torch sparse tensor."""sparse_mx = sparse_mx.tocoo().astype(np.float32) # 将数据变成稀疏矩阵np类型indices = torch.from_numpy( # 索引 np.vstack((sparse_mx.row, sparse_mx.col)).astype(np.int64))values = torch.from_numpy(sparse_mx.data)# 数值shape = torch.Size(sparse_mx.shape) # 形状return torch.sparse.FloatTensor(indices, values, shape) # 变成torch的稀疏矩阵
def load_data(path="../data/cora/", dataset="cora"):"""Load citation network dataset (cora only for now)"""print('Loading {} dataset...'.format(dataset))
# 下面的idx_features_labels 打开的文件之所以是索引特征和标签简明文件存放的内容idx_features_labels = np.genfromtxt("{}{}.content".format(path, dataset), # 指定文件路径dtype=np.dtype(str)) # 指定文件类型features = sp.csr_matrix(idx_features_labels[:, 1:-1], dtype=np.float32) # 0是索引-1是标签 # 使用索引取数值的时候左侧一定能取到右侧表示取不到的位置labels = encode_onehot(idx_features_labels[:, -1]) # 最后一列是标签# build graph '''重点构建图 #######################################################'''idx = np.array(idx_features_labels[:, 0], dtype=np.int32) # 取content文件中的第一列,就是找出有类别文件中的索引信息idx_map = {j: i for i, j in enumerate(idx)} # 对所有论文进行编码 存入字典中。输入论文编码就知道创建的索引信息----现阶段的目的是计算邻接矩阵的行列信息edges_unordered = np.genfromtxt("{}{}.cites".format(path, dataset), # 导入边信息dtype=np.int32)edges = np.array(list(map(idx_map.get, edges_unordered.flatten())),# 将引用信息文件中的论文编码全部换成了索引信息dtype=np.int32).reshape(edges_unordered.shape) # 一开始展开的目的是需要序列数据,现在再次reshapeadj = sp.coo_matrix((np.ones(edges.shape[0]), (edges[:, 0], edges[:, 1])),shape=(labels.shape[0], labels.shape[0]),dtype=np.float32) # 创建稀疏矩阵coo类型的adj,只需要给存在数据的行和列的数据以及数值,并且定义了类型和shape大小
# build symmetric adjacency matrix
adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj)

这行代码是在构建一个对称的邻接矩阵adj。在图卷积神经网络中,邻接矩阵用于表示图中节点之间的连接关系。对于无向图而言,其邻接矩阵是对称的,即如果节点i与节点j相连,则adj[i, j]adj[j, i]的值都应该为1。

然而,在创建初始邻接矩阵时,可能会存在一些不对称的情况,即adj[i, j]不等于adj[j, i]。为了纠正这种不对称性并确保邻接矩阵的一致性,需要进行以下操作:

  • adj + adj.T:首先,将邻接矩阵adj与其转置adj.T相加,确保所有的连接是双向的。

  • adj.T.multiply(adj.T > adj):计算adj的转置减去adj只在转置矩阵中的元素大于原矩阵时才计算,这样可以获取所有adj矩阵未能覆盖的对应连接。

  • - adj.multiply(adj.T > adj):从第一个步骤的结果中减去只有在adj的元素小于adj.T时才存在的元素,以避免重复计数任何连接。

最终结果是一个对称的邻接矩阵,完美地表示无向图的连接关系。这保证了当我们在图网络中传播信息时,连接的权重是相互的,并且流向节点i和节点j的信息是等价的。

features = normalize(features) # 特征归一化adj = normalize(adj + sp.eye(adj.shape[0])) # 邻接矩阵加上对角线idx_train = range(140) # 划分数据集idx_val = range(200, 500)idx_test = range(500, 1500)features = torch.FloatTensor(np.array(features.todense()))labels = torch.LongTensor(np.where(labels)[1]) # 取出数值为1的索引,就是真实labeladj = sparse_mx_to_torch_sparse_tensor(adj)idx_train = torch.LongTensor(idx_train)idx_val = torch.LongTensor(idx_val)idx_test = torch.LongTensor(idx_test)return adj, features, labels, idx_train, idx_val, idx_test
def accuracy(output, labels): # 准确率计算preds = output.max(1)[1].type_as(labels)correct = preds.eq(labels).double()correct = correct.sum()return correct / len(labels)

3.2 layers 模块

此模块定义了一个简单的图卷积网络层(GCN层),它实现了基本的图卷积操作,类似于在文献中所描述的原始GCN层。主要组件包括权重矩阵和可选偏置,其中权重矩阵通过一定的初始化策略进行参数初始化。在前向传递函数中,输入特征与权重矩阵相乘以获得支持(支持表示节点特征的转换),然后通过图的邻接矩阵进行传播,如果定义了偏置,将其添加到输出中。这样的层可以被堆叠使用来构建深层图神经网络。

import math #提供各种各样的数学擦欧总
import torch
from torch.nn.parameter import Parameter # 构建的参数可以求梯度
from torch.nn.modules.module import Module # 创建神经网络的基类
class GraphConvolution(Module):def __init__(self, in_features, out_features, bias=True): # 网络的输入和输出大小,是否引入偏置项super(GraphConvolution, self).__init__()self.in_features = in_featuresself.out_features = out_featuresself.weight = Parameter(torch.FloatTensor(in_features, out_features)) # 设置权重参数的维度if bias:self.bias = Parameter(torch.FloatTensor(out_features))else:self.register_parameter('bias', None)self.reset_parameters()def reset_parameters(self): # 控制权重随机的范围stdv = 1. / math.sqrt(self.weight.size(1))self.weight.data.uniform_(-stdv, stdv)if self.bias is not None:self.bias.data.uniform_(-stdv, stdv)def forward(self, input, adj):support = torch.mm(input, self.weight)output = torch.spmm(adj, support)if self.bias is not None:return output + self.biaselse:return outputdef __repr__(self): # 设置一个魔法方法,用于检测当前对象的输入输出大小,通过输出对象的方式return self.__class__.__name__ + ' (' \+ str(self.in_features) + ' -> ' \+ str(self.out_features) + ')'

def reset_parameters(self): # 控制权重随机的范围,现在解释下:

假设我们在构建一个图卷积网络层,其输入特征维度为100(即每个节点的特征向量长度为100),输出特征维度也设置为100,那么权重矩阵self.weight的大小将是(100, 100),表示从输入特征到输出特征的线性变换。

  1. 计算标准差 (stdv)

    • 首先,self.weight.size(1)得到的是权重矩阵的第二维大小,即100。
    • 然后,math.sqrt(self.weight.size(1))计算输入特征维度100的平方根,即10。
    • 最后,1. / math.sqrt(self.weight.size(1))计算了10的倒数,得到stdv = 0.1。这个值用作初始化权重和偏置参数的均匀分布的标准差。
  2. 初始化权重 (self.weight.data.uniform_(-stdv, stdv))

    • 使用上一步计算得到的stdv = 0.1,权重被初始化为在[-0.1, 0.1]之间的均匀分布。这意味着每个权重值都会随机地从这个区间中选取一个数值。
  3. 初始化偏置 (self.bias.data.uniform_(-stdv, stdv))

    • 如果偏置不为None,即模型选择使用偏置项,偏置也会被初始化为在[-0.1, 0.1]之间的均匀分布。这里的偏置是一个长度为输出特征维度,即100的向量。

通过这种方式初始化参数,保证了模型参数在一开始不会太大或太小,有利于优化算法更好、更快地找到误差的全局最小值,从而提高模型训练的效率和性能。‘

3.3 models 模块

该模块下的代码,定义了一个使用图卷积层构建的简单图卷积网络(GCN)架构,体现了GCN模型的典型结构和数据流动方式。

import torch.nn as nn
import torch.nn.functional as F # torch.nn 和nn.functional主要区别一个是类一个是函数,类需要实例化调用。
from pygcn.layers import GraphConvolution # 导入自建包class GCN(nn.Module):def __init__(self, nfeat, nhid, nclass, dropout):super(GCN, self).__init__()self.gc1 = GraphConvolution(nfeat, nhid)self.gc2 = GraphConvolution(nhid, nclass)self.dropout = dropoutdef forward(self, x, adj):x = F.relu(self.gc1(x, adj))x = F.dropout(x, self.dropout, training=self.training)x = self.gc2(x, adj)return F.log_softmax(x, dim=1)

3.4 模型的训练代码

from __future__ import division # __future__可以理解成一个先行版,在这里得到版本是先行版
from __future__ import print_functionimport time
import argparse # 用于参数调用
import numpy as npimport torch
import torch.nn.functional as F
import torch.optim as optim from pygcn.utils import load_data, accuracy # 两部的都是自己写的
from pygcn.models import GCN
# Training settings
parser = argparse.ArgumentParser() # 对类进行实例化,这个类的特殊在于能够处理命令行的输入
parser.add_argument('--no-cuda', action='store_true', default=False,help='Disables CUDA training.')
parser.add_argument('--fastmode', action='store_true', default=False,help='Validate during training pass.')
parser.add_argument('--seed', type=int, default=42, help='Random seed.')
parser.add_argument('--epochs', type=int, default=200,help='Number of epochs to train.')
parser.add_argument('--lr', type=float, default=0.01,help='Initial learning rate.')
parser.add_argument('--weight_decay', type=float, default=5e-4,help='Weight decay (L2 loss on parameters).')
parser.add_argument('--hidden', type=int, default=16,help='Number of hidden units.')
parser.add_argument('--dropout', type=float, default=0.5,help='Dropout rate (1 - keep probability).')args = parser.parse_args() #对参数进行分析
args.cuda = not args.no_cuda and torch.cuda.is_available()
np.random.seed(args.seed) # 随机数种子设置
torch.manual_seed(args.seed)
if args.cuda:torch.cuda.manual_seed(args.seed)
# Load data
adj, features, labels, idx_train, idx_val, idx_test = load_data() # 给地址# Model and optimizer 
model = GCN(nfeat=features.shape[1],# 实例化模型nhid=args.hidden,nclass=labels.max().item() + 1,dropout=args.dropout)
optimizer = optim.Adam(model.parameters(),# 实例化优化器lr=args.lr, weight_decay=args.weight_decay)if args.cuda:model.cuda()features = features.cuda()adj = adj.cuda()labels = labels.cuda()idx_train = idx_train.cuda()idx_val = idx_val.cuda()idx_test = idx_test.cuda()def train(epoch):t = time.time()model.train()optimizer.zero_grad()output = model(features, adj)loss_train = F.nll_loss(output[idx_train], labels[idx_train])acc_train = accuracy(output[idx_train], labels[idx_train])loss_train.backward()optimizer.step()if not args.fastmode:# Evaluate validation set performance separately,# deactivates dropout during validation run.model.eval()output = model(features, adj)loss_val = F.nll_loss(output[idx_val], labels[idx_val])acc_val = accuracy(output[idx_val], labels[idx_val])print('Epoch: {:04d}'.format(epoch+1),'loss_train: {:.4f}'.format(loss_train.item()),'acc_train: {:.4f}'.format(acc_train.item()),'loss_val: {:.4f}'.format(loss_val.item()),'acc_val: {:.4f}'.format(acc_val.item()),'time: {:.4f}s'.format(time.time() - t))def test():model.eval()output = model(features, adj)loss_test = F.nll_loss(output[idx_test], labels[idx_test])acc_test = accuracy(output[idx_test], labels[idx_test])print("Test set results:","loss= {:.4f}".format(loss_test.item()),"accuracy= {:.4f}".format(acc_test.item()))# Train model
t_total = time.time()
for epoch in range(args.epochs):train(epoch)
print("Optimization Finished!")
print("Total time elapsed: {:.4f}s".format(time.time() - t_total))# Testing
test()

上述部分和其他深度学习代码并无差异如果感兴趣可以参考pytorch模块下的作业代码深入理解。

总结

当前代码主要的工作量就是在数据的处理以及网络的构建,其他并无明显差异,在图卷积网络(GCN)和图神经网络(GNN)的构建与学习过程中,数据的处理和网络架构的设计无疑是占据主要工作量的两大核心领域。这些任务之所以充满挑战,很大程度上在于需要精巧地表征和处理具有图结构的数据,并创新性地构建能够捕捉其复杂模式的网络结构。为了更有效地提高模型性能,学习过程中应着重关注和深入探索网络搭建和数据预处理的相关知识和技术。通过对这些关键部分进行深刻理解和不断练习,可以实现模型效率的显著提升,并且更好地将理论应用于解决实际问题。

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

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

相关文章

小程序CI/CD之自动化打包预览并钉钉通知发布进程

小程序打包方式分为两种&#xff1a;手动打包、自动打包 那如何实现 自动打包 呐&#xff1f;我们今天就来聊一聊&#xff01; 首先&#xff0c;很重要&#xff0c;看 官方文档 这里提到今天我们要聊的“主角” miniprogram-ci miniprogram-ci 是从微信开发者工具中抽离的关于…

nacos开启鉴权

nacos版本1.4.3 1.nacos配置开启鉴权 application.properties 或 application.yaml 文件中 nacos.core.auth.enabled 设置为 true 2.修改JWT令牌 如果是Linux系统可以使用命令随机生成 echo -n ThisIsARandomlyGeneratedSecureKey32CharactersLong | base64 nacos.core.au…

【HarmonyOS-Stage应用模型-UIAbility生命周期】

概述 在应用开发过程中&#xff0c;组件的生命周期尤为重要&#xff0c;当用户打开、切换和返回到对应应用时&#xff0c;应用中的UIAbility实例会在其生命周期的不同状态之间转换。我们可以通过生命周期来对应用的状态进行监控并执行特定的操作。比如在创建时进行应用初始化、…

网络摄像头项目

1.OV2640 简介 OV2640 是 OV&#xff08;OmniVision&#xff09;公司生产的一颗 1/4 寸的 CMOS UXGA&#xff08;1632*1232&#xff09;图像 传感器。该传感器体积小、工作电压低&#xff0c;提供单片 UXGA 摄像头和影像处理器的所有功能。通 过 SCCB 总线控制&#xff0c;可以…

【机器学习】LoRA:大语言模型中低秩自适应分析

LoRA&#xff1a;大型语言模型中的低秩自适应调优策略 一、LoRA的原理与优势二、LoRA在编程和数学任务中的性能表现四、总结与展望 随着人工智能技术的飞速发展&#xff0c;大型语言模型已成为自然语言处理领域的明星技术。然而&#xff0c;这些模型通常拥有数以亿计的参数&…

做好产线工控安全的关键

在现代化工业生产中&#xff0c;产线工控安全是确保生产顺利进行、产品质量稳定、员工生命安全的重要一环。随着信息技术的飞速发展&#xff0c;工控系统面临着越来越多的安全威胁&#xff0c;因此&#xff0c;如何做好产线工控安全成为了摆在我们面前的重要课题。 首先&#x…

使用Python进行高并发压测:技术指南与实战案例

目录 一、引言 二、压测基础知识 压测的目的与类型 压测工具的选择 三、使用Python进行压测 Python压测框架的选择 压测脚本的编写 压测的执行与监控 四、实战案例分析 案例背景介绍 压测计划制定 压测实施过程 结果分析与优化建议 五、常见问题与解决方案 六、…

centos7下卸载MySQL,Oracle数据库

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 操作系统版本为CentOS 7 使⽤ MySQ…

JVM 运行流程

JVM 是 Java 运行的基础&#xff0c;也是实现一次编译到处执行的关键&#xff0c;那么 JVM 是如何执行的呢&#xff1f; JVM 执行流程 程序在执行之前先要把java代码转换成字节码&#xff08;class 文件&#xff09;&#xff0c; JVM 首先需要把字节码通过一定的 方式 类加…

文件怎么加密?文件加密软件哪个好用?

在数字化生活和工作中&#xff0c;文件安全已成为不容忽视的话题。 为了保护个人隐私和企业敏感数据不被非法访问或泄露&#xff0c;文件加密成为了不可或缺的手段。 本文将介绍文件加密的基本概念、加密方法以及推荐几款好用的文件加密软件&#xff0c;帮助您为重要文件穿上“…

捋一捋C++中的逻辑运算(一)——表达式逻辑运算

注意&#xff0c;今天要谈的逻辑运算是C语言编程中的“与或非”逻辑运算&#xff0c;不是数学集合中的“交并补”逻辑运算。而编程中的逻辑运算又包括表达式逻辑运算和位逻辑运算&#xff0c;本章介绍表达式逻辑运算&#xff0c;下一章介绍位逻辑运算。 目录 一、几个基本的概…

视频号上怎么卖货?需要直播,还有粉丝吗?一篇文章带你了解!

大家好&#xff0c;我是电商糖果 关于在视频号上卖货&#xff0c;这是大家最常提起的话题。 大家之所以对视频号卖货感兴趣&#xff0c;主要原因还是抖音卖货火起来了。 而视频号是和抖音处于同一个赛道&#xff0c;这两年也在往电商方向发力。 所以大家对视频号推出电商平…

Window11端口开放防火墙

&#xff08;1&#xff09;打开控制面板&#xff0c;进入【控制面板\系统和安全\Windows Defender 防火墙】 &#xff08;2&#xff09;点击左侧菜单【高级设置】&#xff0c;进入防火墙设置页面 &#xff08;3&#xff09;根据需要选择【入站规则】或者【出站规则】&#xff…

ubtun三节点安装k8s

文章目录 修改Ubuntu配置关闭swap&#xff1a;关闭防火墙 安装docker 修改Ubuntu配置 关闭swap&#xff1a; vim /etc/fstab /dev/disk/by-uuid/a1ce2ecf-91f4-4f53-9984-b2af1e9713c5 /boot ext4 defaults 0 1 /swap.img none swap sw 0 0修改/dev/dis…

nestjs 全栈进阶--拦截器

视频教程 23_nestjs中的拦截器_哔哩哔哩_bilibili 1. rxjs 介绍 RxJS&#xff08;Reactive Extensions for JavaScript&#xff09;是一款专为JavaScript和TypeScript设计的响应式编程库&#xff0c;它遵循ReactiveX规范&#xff0c;提供了一套强大的工具和API&#xff0c;用…

Mac 使用Docker安装Elasticsearch、Kibana

安装ElasticSearch 通过docker安装es docker pull elasticsearch:8.6.2 在本地创建elasticsearch.yml文件 mkdir /Users/ky/Documents/learn/es/elasticsearch.yml 编辑yml文件内容 http: host: 0.0.0.0 xpack.security.enabled: false xpack.security.enrollment.enabled: t…

Scala 练习一 将Mysql表数据导入HBase

Scala 练习一 将Mysql表数据导入HBase 续第一篇&#xff1a;Java代码将Mysql表数据导入HBase表 源码仓库地址&#xff1a;https://gitee.com/leaf-domain/data-to-hbase 一、整体介绍 HBase特质 连接HBase, 创建HBase执行对象 初始化配置信息&#xff1a;多条(hbase.zookeeper.…

ARM学习(28)NXP 双coreMCU IMX1160学习

笔者最近接触到一块IMXRT1160的双core板子&#xff0c;特依次来记录学习一下 1、IMXRT1160 板子介绍 介绍一下NXP的Demo板子&#xff0c;是一个双core的板子&#xff0c;Cortex-M7和Cortex-M4&#xff0c;总计1MB的RAM空间&#xff0c;256KB的ROM空间&#xff0c;提供了丰富的…

Window10磁盘的分盘和合并

注意&#xff1a; 当我们c盘不够大需要扩大磁盘空间时&#xff0c;当c盘后面没有未划分的磁盘时候&#xff0c;我们是无法进行扩充c盘的&#xff0c;此时&#xff0c;我们可以先删除后面一个磁盘&#xff0c;再进行扩大。 如下&#xff1a;c盘后没有未分配的空间&#xff0c;…

【项目管理常见问题大揭秘】每个管理者都要Get的「五维思维」~

走上管理岗☸要懂得五维思维 &#x1f4bc;自我管理——做自己的CEO 严于律己&#xff1a;严格要求自己&#xff0c;注重个人品牌建设 宽以待人&#xff1a;接纳不同观点&#xff0c;提升团队凝聚力 尊重事实&#xff1a;鼓励团队成员发挥优势&#xff0c;避免负面评价 坚守诚…