【图神经网络】从0到1使用PyG手把手创建异构图

2023-05-16

从0到1用PyG创建异构图

  • 异构图
  • 创建异构图
    • 电影评分数据集MovieLens
    • 建立二分图数据集
    • 转换为可训练的数据集
  • 建立异构图神经网络
    • 以OGB数据集为例
    • HeteroData中常用的函数
    • 将简单图神经网络转换为异质图神经网络
  • GraphGym的使用
  • PyG中常用的卷积层
  • 参考资料

在现实中需要对 多种类型的节点以及这些 节点之间多种类型的边进行处理,这就需要 异构图的概念,在异构图中, 不同类型的边描述不同类型节点之间 不同的关系异构图神经网络的任务就是在这种图结构上学习出节点或者整个异构图的特征表示

异构图

异构图的准确定义如下:异构图(Heterogeneous Graphs):一个异构图 G G G有一组节点 V = v 1 , v 2 , . . . , v n V=v_1,v_2,...,v_n V=v1,v2,...,vn和一组边 E = e 1 , e 2 , . . . , e m E=e_1,e_2,...,e_m E=e1,e2,...,em组成,其中每个节点和每条边都对应着一种类型,用 T v T_v Tv表示节点类型的集合, T e T_e Te表示边类型的集合,一个异构图有两个映射函数,分别将每个节点映射到其对应的类型 ϕ v : V → T v \phi_v:V\rightarrow T_v ϕv:VTv,每条边映射到其对应的类型: ϕ e : E → T e \phi_e:E\rightarrow T_e ϕe:ETe

创建异构图

电影评分数据集MovieLens

这里以一个电影评分数据集MovieLens为例,逐行示例如何创建异构图。MovieLens包含了600个用户对于电影的评分,利用这个数据集构建一个二分图,包含电影用户两种类型的节点,一种类型的边(含有多种类型节点,所以可以看作一个异质图)。

  • MovieLens中的movies.csv文件描述了电影的信息,包括电影在数据集中唯一的ID电影名电影所属的类型
    movies.csv
  • MovieLens中的ratings.csv包含了用户对于电影的评分:
    ratings.csv

建立二分图数据集

首先下载一个Python库:sentence_transformersSentenceTransformers 是一个可以用于句子、文本和图像嵌入的Python库。 可以为 100 多种语言计算文本的嵌入并且可以轻松地将它们用于语义文本相似性、语义搜索和同义词挖掘等常见任务。该框架基于 PyTorch 和 Transformers,并提供了大量针对各种任务的预训练模型。 还可以很容易根据自己的模型进行微调。

pip install -U sentence-transformers

首先,导入依赖库:

import os.path as osp

import torch
import pandas as pd
from sentence_transformers import SentenceTransformer

from torch_geometric.data import HeteroData, download_url, extract_zip
from torch_geometric.transforms import ToUndirected, RandomLinkSplit

然后,设定数据集:
数据集下载
利用Pandas查看数据集
查看数据集
(1)利用嵌入模型将每个电影名用向量表示(Embedding)

# 将电影名那列用嵌入模型将每个电影名用向量表示(Embedding)
class SequenceEncoder(object):
  # 初始化,指定使用的embedding module和设备
  def __init__(self, model_name='all-MiniLM-L6-v2', device=None):
    # 使用的设备
    self.device = device
    # 使用的嵌入模型名
    self.model = SentenceTransformer(model_name, device=device)
  # 嵌入模型不参与后续图神经网络的训练
  @torch.no_grad()
  def __call__(self, df):
    x = self.model.encode(
        # 要进行嵌入的值
        df.values,
        # 显示处理进度
        show_progress_bar=True,
        # 转换为Pytorch的张量
        convert_to_tensor=True,
        # 使用的设备
        device=self.device
    )
    return x.cpu()

(2)将电影类型也进行嵌入表示

# 将电影类型那列也进行嵌入表示
class GenresEncoder(object):
  # 默认分隔符为"|"
  def __init__(self, sep="|"):
    self.sep = sep
  def __call__(self, df):
    genres = set(g for col in df.values for g in col.split(self.sep))
    # 将电影类型用数字表示
    mapping = {genre: i for i, genre in enumerate(genres)}
    # 用multi-hot形式表示电影的类型
    x = torch.zeros(len(df), len(mapping))
    for i, col in enumerate(df.values):
      for genre in col.split(self.sep):
        x[i, mapping[genre]]=1
    return x

(3)从CSV文件中读取信息,建立二分图中的节点信息

# 从csv中读取信息,建立二分图中节点的信息
def load_node_csv(path, index_col, encoders=None, **kwargs):
  """
  :param path: CSV文件路径
  :param index_col: 文件中的索引列,也就是节点所在的列
  :param encoders: 节点嵌入器
  :param kwargs
  :return:
  """
  df = pd.read_csv(path, index_col=index_col, **kwargs)
  # 将索引用数字表示
  mapping = {index: i for i, index in enumerate(df.index.unique())}
  # 节点属性向量矩阵
  x = None
  # 如果嵌入器非空
  if encoders is not None:
    # 对相应的列进行嵌入,获取嵌入向量表示
    xs = [encoder(df[col]) for col, encoder in encoders.items()]
    x = torch.cat(xs, dim=-1)
  return x, mapping

(4)获取节点信息

# 处理movies.csv表,将"电影名","电影类型"列转换为嵌入向量的表示形式
movie_x, movie_mapping = load_node_csv(movie_path, index_col = 'movieId', encoders = {'title':SequenceEncoder(),'genres':GenresEncoder()})
# 处理rating.csv表,将用户ID用PyTorch中的张量表示
user_x, user_mapping = load_node_csv(rating_path, index_col='userId')
# 建立异质图,这里是一个二分图
data = HeteroData() # HeteroData()是PyG中内置的一个表示异质图的数据结构
# 加入不同类型节点的信息
# 加入用户信息,用户没有属性信息, 只需要告诉PyG有多少个用户节点就可以
data['user'].num_nodes = len(user_mapping) 
# 告诉PyG 电影的属性向量矩阵,PyG会根据x推断出电影节点的个数
data['movie'].x = movie_x  
print(data)

输出结果
(5)建立用户和电影之间的边的信息

# 将用户对电影的评分转换为PyTorch的张量
class IdentityEncoder(object):
  def __init__(self, dtype=None):
    self.dtype = dtype
  def __call__(self, df):
    return torch.from_numpy(df.values).view(-1, 1).to(self.dtype)

(6)建立二分图边的连接信息

# 建立二分图边的链接信息
def load_edge_csv(path, src_index_col, src_mapping, dst_index_col, dst_mapping, encoders=None, **kwargs):
  """
  :param path: CSV表的路径
  :param src_index_col: 二分图左边节点来源于CSV表的哪一列,比如'user_id'这列
  :param src_mapping:将user_id映射为节点编号,我们前面定义的user_mapping
  :param dst_index_col:同理,二分图右边电影节点
  :param dst_mapping:
  :param encoders:边的嵌入器
  :param kwargs:
  :return:
  """
  df = pd.read_csv(path, **kwargs)
  # 建立连接信息
  src = [src_mapping[index] for index in df[src_index_col]]
  dst = [dst_mapping[index] for index in df[dst_index_col]]
  # 注意这里edge_index维度为[2, 边数]
  edge_index = torch.tensor([src, dst])
  # 边的属性信息
  edge_attr = None
  # 如果嵌入器非空
  if encoders is not None:
      edge_attrs = [encoder(df[col]) for col, encoder in encoders.items()]
      edge_attr = torch.cat(edge_attrs, dim=-1)

  return edge_index, edge_attr

(7)获取二分图边的信息

# 获取二分图边的信息
edge_index, edge_label = load_edge_csv(
    rating_path,
    # 二分图左边是用户
    src_index_col='userId',
    src_mapping=user_mapping,
    # 右边是电影
    dst_index_col='movieId',
    dst_mapping=movie_mapping,
    encoders={'rating': IdentityEncoder(dtype=torch.long)}
    )

(8)将二分图中的边命名为(‘user’, ‘rates’, ‘movie’)
将二分图中的边命名为
到此,我们的异构图数据集,实际上是一个二分图,就构建完毕了。下面还要将其转换为一个可以进行训练的数据集

转换为可训练的数据集

这里,我们将构建的异构图数据集转换为一个可训练的无向图数据集。
(1)转换为无向图,同时删除相反方向边的属性信息

data = ToUndirected()(data)
# 删除相反方向边的属性信息,因为没有电影对用户的评分数据
del data['movie', 'rev_rates', 'user'].edge_label

(2)按照比例分割数据集为训练集、测试集、验证集

# 按照一定比例分割数据集为训练集、测试集和验证集
transform = RandomLinkSplit(
    num_val=0.05, 
    num_test=0.1,
    # 负采样比率
    # 不用负采样,全部输入进行训练
    neg_sampling_ratio = 0.0,
    # 告诉PyG边的连接关系
    edge_types=[('user', 'rates', 'movie')],
    rev_edge_types=[('movie', 'rev_rates', 'user')],
    )
# 分割数据集
train_data, val_data, test_data = transform(data)
print(train_data)
print(val_data)
print(test_data)

分割后的数据集
至此,一个可训练的数据集已经构建完毕。

建立异构图神经网络

以OGB数据集为例

在OGB数据集中包含4种类型的节点:author、paper、institution、field of study;4种类型的边:

  • writes:author和paper之间的连接关系
  • affiliated with:author和institution之间的连接关系
  • cites:paper和paper之间的关系
  • has topic:paper和field of study之间的关系

OGB数据集上的任务是预测论文在整个关系网中所属的位置。下面代码示例如何表示这个异质图:

from torch_geometric.data import HeteroData

# HeteroData是PyG自带的一个异质图数据结构
data = HeteroData()

# 添加节点的信息
data['paper'].x = ... # [num_papers, num_features_paper]
data['author'].x = ... # [num_authors, num_features_author]
data['institution'].x = ... # [num_institutions, num_features_institution]
data['field_of_study'].x = ... # [num_field, num_features_field]

# 添加边的连接信息
data['paper', 'cites', 'paper'].edge_index = ... # [2, num_edges_cites]
data['author', 'writes', 'paper'].edge_index = ... # [2, num_edges_writes]
data['author', 'affiliated_with', 'institution'].edge_index = ... # [2, num_edges_affiliated]
data['paper', 'has_topic', 'field_of_study'].edge_index = ... # [2, num_edges_topic]

# 添加边的属性信息
data['paper', 'cites', 'paper'].edge_attr = ... # [num_edges_cites, num_features_cites]
data['author', 'writes', 'paper'].edge_attr = ... # [num_edges_writes, num_features_writes]
data['author', 'affiliated_with', 'institution'].edge_attr = ... # [num_edges_affiliated, num_features_affiliated]
data['paper', 'has_topic', 'field_of_study'].edge_attr = ... # [num_edges_topic, num_features_topic]

这样上面的异质图就建立完成了,我们可以将它输入到一个异质图神经网络中:

# 异质图神经网络
model = HeteroGNN(...)
# 获取异构图神经网络的输出
# 注意异质图神经网络的输入是 ..._dict
output = model(data.x_dict, data.edge_index_dict, data.edge_attr_dict)

如果PyG中包含你想用的异质图,可以直接这样导入:

from torch_geometric.datasets import OGB_MAG

# 导入数据集
dataset = OGB_MAG(root='./data', preprocess='metapath2vec')
data = dataset[0]

这样上面的异质图就建立完成了,我们可以将它输入到一个异质图神经网络中

HeteroData中常用的函数

下面介绍一下HeteroData中常用的函数:

  • 获取异质图中的某种节点或边
paper_node_data=data['paper']
cites_edge_data=data['paper','cites','paper']
  • 如果边的连接节点集合或者边的命名是唯一的,还可以这样写
#使用连接端点获取边
cites_edge_data=data['paper','paper']
#使用边的名字获取
cites_edge_data=data['cites']
  • 给节点添加新属性
data['paper'].year=...
  • 删除节点的某些属性
def data['field_of_study']
  • 通过metadata获取异质图中所有类型的信息
node_types,edge_types=data.metadata()
  • 所有类型的节点
print(node_types)
  • 所有类型的边
print(edge_types)
  • 判断异质图自身的一些属性
print(data.has_isolated_nodes())
  • 如果不同类型信息之间维度匹配,还可以将异质图融合为一个简单图
homogeneous_data=data.to_homogeneous()
  • 对异质图进行变换
import torch_geometric.transforms as T

#变为无向图
data=T.ToUndirected()(data)
#添加到自身的环
data=T.AddSelfLoops()(data)

将简单图神经网络转换为异质图神经网络

PyG可以通过torch_geometric.nn.to_hetero(),或者torch_geometric.nn.to_hetero_with_bases()将一个简单图神经网络转换成异质图的形式。

import torch_geometric.transforms as T
from torch_geometric.datasets import OGB_MAG
from torch_geometric.nn import SAGEConv, to_hetero

# 导入数据集
dataset = OGB_MAG(root='./data', preprocess='metapath2vec', transform=T.ToUndirected())
data = dataset[0]

# 定义一个普通的图神经网络
class GNN(torch.nn.Module):
    def __init__(self, hidden_channels, out_channels):
        super().__init__()
        self.conv1 = SAGEConv((-1, -1), hidden_channels)
        self.conv2 = SAGEConv((-1, -1), out_channels)

    def forward(self, x, edge_index):
        x = self.conv1(x, edge_index).relu()
        x = self.conv2(x, edge_index)
        return x

# 实例化我们定义的图神经网络
model = GNN(hidden_channels=64, out_channels=dataset.num_classes)
# 将其转换为异质图形式
model = to_hetero(model, data.metadata(), aggr='sum')

PyG的to_hetero具体工作方式是这样的:
to_hetero
它根据我们的异质图数据结构,自动将我们定义的简单图神经网络结构中的层结构进行了复制,并添加了信息传递路径
然后,创建的模型可以像往常一样进行训练:

def train():
    model.train()
    optimizer.zero_grad()
    out = model(data.x_dict, data.edge_index_dict)
    mask = data['paper'].train_mask
    loss = F.cross_entropy(out['paper'][mask], data['paper'].y[mask])
    loss.backward()
    optimizer.step()
    return float(loss)

异构卷积包装器torch_geometry.nn.conv.HeteroConv允许定义自定义异构消息和更新函数,以从头开始为异构图构建任意MP-GNN。虽然to_hetero()的自动转换器对所有边类型使用相同的运算符,但包装器允许为不同的边类型定义不同的运算符。在这里,HeteroConv将子模块的字典作为输入,图数据中的每个边缘类型都有一个子模块。以下示例显示了如何应用它。

import torch_geometric.transforms as T
from torch_geometric.datasets import OGB_MAG
from torch_geometric.nn import HeteroConv, GCNConv, SAGEConv, GATConv, Linear


dataset = OGB_MAG(root='./data', preprocess='metapath2vec', transform=T.ToUndirected())
data = dataset[0]

class HeteroGNN(torch.nn.Module):
    def __init__(self, hidden_channels, out_channels, num_layers):
        super().__init__()

        self.convs = torch.nn.ModuleList()
        for _ in range(num_layers):
            conv = HeteroConv({
                ('paper', 'cites', 'paper'): GCNConv(-1, hidden_channels),
                ('author', 'writes', 'paper'): SAGEConv((-1, -1), hidden_channels),
                ('paper', 'rev_writes', 'author'): GATConv((-1, -1), hidden_channels,add_self_loops=False),
            }, aggr='sum')
            self.convs.append(conv)

        self.lin = Linear(hidden_channels, out_channels)

    def forward(self, x_dict, edge_index_dict):
        for conv in self.convs:
            x_dict = conv(x_dict, edge_index_dict)
            x_dict = {key: x.relu() for key, x in x_dict.items()}
        return self.lin(x_dict['author'])

model = HeteroGNN(hidden_channels=64, out_channels=dataset.num_classes,
                  num_layers=2)

我们可以通过调用一次来初始化模型(有关延迟初始化的更多详细信息,请参阅此处)

with torch.no_grad():  # Initialize lazy modules.
     out = model(data.x_dict, data.edge_index_dict)

GraphGym的使用

PyG 2.0 现在通过 torch_geometric.graphgym 正式支持 GraphGym。总的来说,GraphGym 是一个平台,用于通过高度模块化的 pipeline 从配置文件中设计和评估图神经网络

  • GraphGym 是开始学习标准化 GNN 实现和评估的最佳平台
  • GraphGym 提供了一个简单的接口来并行尝试数千个 GNN 架构,以找到适合特定任务的最佳设计;
  • GraphGym 可轻松进行超参数搜索并可视化哪些设计选择更好。

GraphGym
对于GraphGym更多资料,参考https://pytorch-geometric.readthedocs.io/en/latest/modules/graphgym.html

PyG中常用的卷积层

PyG中的卷积层
PyG卷积层2
卷积层3
卷积层4卷积层5

参考资料

  1. PyG创建自定义异构图Heterogeneous Graphs数据集
  2. Pytorch图神经网络库——PyG创建自己的数据集
  3. Pytorch图神经网络库——PyG异构图学习
  4. 异质图的建立
  5. 《图深度学习》 马耀、汤继良著
  6. SentenceTransformers 库介绍
  7. GraphGym
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【图神经网络】从0到1使用PyG手把手创建异构图 的相关文章

  • n个人围成一圈,第一个开始报数(1-3),凡报数3退出。问最后留下的人是原来第几号?

    include lt stdio h gt int main int i 61 0 j 61 0 k 61 0 n x int a 100 printf 34 please input a nu 34 scanf 34 d 34 amp n
  • 使用sea-orm执行migrate

    源码github地址 seaormdemo 一 下载工具链 sea orm cli 是sea orm 提供的工具链 xff0c 可通过cargo下载 cargo span class token function install span
  • PVE安装更新源错误

    pve系统ping 网络不通且不能进行apt install 描述 root 64 xuyuquan span class token comment apt get update span Err 1 http ftp debian or
  • failed to run command ‘java’: No such file or directory

    failed to run command java No such file or directory 程序里远程执行shell命令 xff08 nohup java jar xff09 的执行 xff0c 后台日志报错如下 xff1a
  • vue3中的setup函数

    原文 xff1a vue3中的setup函数 落雪小轩韩的博客 CSDN博客 vue3setup 一 概念 xff1a setup是vue3中的一个新的配置项 xff0c 值为一个函数 xff0c 我们在组件中用到的数据 方法等等 xff0
  • vue同步请求

    原文地址 xff1a vue 同步请求 Aa duidui的博客 CSDN博客 vue同步请求 同步请求执行的顺序 async await 挂上的才是同步 没挂上的还是异步 async 方法名 await 请求方法 参数 then res
  • Anaconda上设置虚拟环境,并在jupyter notebook中切换。

    个人记录 xff0c 但欢迎阅读和赐教 我之前在Anaconda Navigator中建立虚拟环境 xff0c 然后在jupyter notebook的terminal中增加对应环境的ipykernel xff0c 这样可行 xff0c 但
  • 字符,字节和编码

    级别 xff1a 初级 摘要 xff1a 本文介绍了字符与编码的发展过程 xff0c 相关概念的正确理解 举例说明了一些实际应用中 xff0c 编码的实现方法 然后 xff0c 本文讲述了通常对字符与编码的几种误解 xff0c 由于这些误解
  • http协议原理

    HTTP工作原理 HTTP协议定义Web客户端如何从Web服务器请求Web页面 xff0c 以及服务器如何把Web页面传送给客户端 HTTP协议采用了请求 响应模型 客户端向服务器发送一个请求报文 xff0c 请求报文包含请求的方法 URL
  • TLS协议/SSL协议

    历史背景 SSL Secure Socket Layer 安全套接层 是基于HTTPS下的一个协议加密层 xff0c 最初是由网景公司 xff08 Netscape xff09 研发 xff0c 后被IETF xff08 The Inter
  • TCP协议

    TCP 基础 https www jianshu com p ef892323e68f TCP 使用固定的连接 TCP 用于应用程序之间的通信 当应用程序希望通过 TCP 与另一个应用程序通信时 xff0c 它会发送一个通信请求 这个请求必
  • UDP协议

    UDP 概述 xff08 User Datagram Protocol xff0c 用户数据报协议 xff09 用户数据报协议 UDP 只在 IP 的数据报服务之上增加了很少一点的功能 xff0c 这就是复用和分用的功能以及查错检测的功能
  • TCP和UDP的区别

    TCP协议与UDP协议的区别 首先咱们弄清楚 xff0c TCP协议和UDP协议与TCP IP协议的联系 xff0c 很多人犯糊涂了 xff0c 一直都是说TCP协议与UDP协议的区别 xff0c 我觉得这是没有从本质上弄清楚网络通信 xf
  • 网络协议概述

    互联网协议介绍 互联网的核心是一系列协议 xff0c 总称为 互联网协议 xff08 Internet Protocol Suite xff09 xff0c 正是这一些协议规定了电脑如何连接和组网 我们理解了这些协议 xff0c 就理解了互
  • go 编写tcp和udp服务端和客户端

    TCP协议 TCP IP Transmission Control Protocol Internet Protocol 即传输控制协议 网间协议 xff0c 是一种面向连接 xff08 连接导向 xff09 的 可靠的 基于字节流的传输层
  • tcp黏包问题

    服务端代码如下 xff1a span class token keyword package span main span class token keyword import span span class token punctuati
  • go sync.Pool 深入

    new函数的调用时机和pool的内存释放规则 以下代码调用了四次Get函数 xff0c 但是并不是每次都会new 第一次 xff0c 是a 61 pool Get byte xff0c 首次Get xff0c 在pool的private私有
  • 【AI理论学习】深入理解扩散模型:Diffusion Models(DDPM)(理论篇)

    深入理解扩散模型 xff1a Diffusion Models 引言扩散模型的原理扩散过程反向过程优化目标 模型设计代码实现Stable Diffusion DALL E Imagen背后共同的套路Stable DiffusionDALL
  • gin 框架原理

    Gin的路由原理 Gin的路由基于Trie树和压缩字典树算法 xff0c 什么是Trie树 xff1f 其实很好理解 xff0c 看下图 xff1a 单词at xff0c bee xff0c ben xff0c bt xff0c q组成的T
  • PowerDesigner导入sql脚本

    1 依次点击File gt Reverse Engineer gt Database 2 弹出弹窗对模型进行命名 xff0c 同时在DBMS下拉选择框中需要选择自己对应的数据库类型 xff0c 点击确定 新的弹窗 xff0c 选中Using

随机推荐

  • Gin路由算法模拟

    概述 Gin的路由算法是采用压缩字典树实现的 xff0c 基数树 xff08 Radix Tree xff09 又称为PAT位树 xff08 Patricia Trie or crit bit tree xff09 xff0c 是一种更节省
  • 使用gomail发送邮件

    概述 为了实现一个邮件验证码功能 xff0c 特意了解了一下go如何发送邮件 本来以为会很麻烦 xff0c 没想到其实很简单 工具类 实现的工具类如下 xff1a span class token keyword package span
  • redis实现消息队列的几种方式及其优劣

    概述 常用的消息队列有 xff0c rabbitMq kafka RocketMq ActiveMq等 这些消息队列需要独立安装部署 xff0c 作为一个中间件来提供服务 xff0c 虽然有着高性能 高可靠的优点 xff0c 但是额外部署这
  • linux系统或者windows WSL安装redis最新版本

    概述 因为windows的最新版本redis已经在16年就停止更新了 xff0c 目前最新的版本只到redis3 xff0c 很多redis新增的特性都无法使用 例如redis5的stream xff0c windows版本就没有 这篇文章
  • 在面对一些亿级流量场景,消息队列届的排头兵kafka是如何保证高性能的呢?

    在面对一些亿级流量场景 xff0c 消息队列届的大哥kafka是如何保证高性能的呢 xff1f Kafka Reactor模型架构 Kafka客户端和服务端通信采取的是NIO的reactor模式 xff0c 它是一种事件驱动模式 react
  • Redis是如何实现高性能的?

    Redis作为应对高并发场景的利器 xff0c 它是如何实现高性能的呢 xff1f IO多路复用 传统对于并发情况 xff0c 假如一个进程不行 xff0c 那搞多个进程不就可以同时处理多个客户端连接了么 xff1f 多进程是可以解决一些并
  • go更新最新版本

    最近go1 18出了泛型 xff0c 趁着周末有时间 xff0c 赶不及要尝尝鲜呢 那如何更新我本地go到最新版本到1 18呢 1 下载安装包 https go dev dl 2 执行安装 点击打开安装程序 xff0c 点击next 选择卸
  • idea、goland泛型语法报错解决|go1.18泛型初体验

    go在1 18正式推出了泛型 xff0c 你是否和博主一样好奇其语法呢 xff1f 快啊来看看吧 1 版本更新 amp 插件更新 go如何更新到最新版本 xff0c 可以查看https www hengyumo cn momoblog de
  • 【统计学习】5分钟了解假设检验中的第一类错误和第二类错误

    5分钟了解假设检验中的第一类错误和第二类错误 假设检验假设检验 xff1a 可能性Type I 第一类错误Type II 第二类错误举个例子总结参考资料 在假设检验中 xff0c 第一类错误和第二类错误是两种可能的错误类型 第一类错误 xf
  • godis 运行原生redis命令

    我们可能会遇到需要运行的某些命令在godis中不存在的情况 xff0c 这个时候我们可以使用其原生的方式运行命令 xff0c 为了方便使用 xff0c 封装了一个方法 xff0c 用于简化这个过程 需要注意的是 xff0c 执行命令的返回结
  • Beego项目打包部署到Linux服务器

    1 打包beego项目 xff0c 项目目录下执行 bee pack be GOOS 61 linux 2 将压缩包传到服务器gopath目录下 xff0c 进行解压 xff0c tar zxvf filename tar gz 3 给执行
  • Python 获取目录及子目录下所有文件 (不包括文件夹),极简

    其实就是想记一下这个华丽的大推导式 xff0c 一行解决 xff1a span class token comment path 是要遍历的根目录 xff0c 34 34 是当前目录 span path span class token o
  • K8S问题-kubectl exec命令无法进入pod环境,处于卡住状态

    问题现象 xff1a kubectl exec it podname n ns bash 命令超时 定位思路 xff1a bash 换成sh检查是否正常 不正常 检查node是否正常 正常 试一下问题pod所在的node上的别的pod是否也
  • 深入理解java虚拟机(JVM)------一篇过

    JVM 一篇过 发展史 xff08 不知道历史的程序员不是一个好秃子 xff09 前身 xff1a Oak语言 xff08 91年开发消费性电子产品 xff09 java me java se java ee java me xff1a 移
  • 运行shell脚本出现Bad Substitution错误

    通过sh xxx sh运行某个shell脚本 xff0c 发现出现Bad Substitution错误 最终发现是shell脚本解释器的问题 xff0c 我采用sh这个命令执行的脚本 xff0c 对sh这个命令 xff0c 查看其属性发现
  • python比较操作的内幕

    今天看了序列类型相关的比较操作 在python核心编程 2nd 一书中6 13 1章节中 给出了列表比较的一个准则 个人感觉还是不很完善 如果扫描到两个列表中当前比较元素是不可比较的 那么返回什么 我用的是python2 6 对这个问题做了
  • 用systemd挂载硬盘分区和进行bind挂栽文件夹以及定时关机

    Systemd是一个强大的Linux管理工具 xff0c 可以用来进行硬盘分区 xff0c 或者也称作文件系统的挂载 相较于使用fstab文件来进行管理 xff0c 采用systemd不会发生因为配置错误而无法开机的问题 xff0c 所以比
  • CoreOS 系统安装后的简单配置-允许root以ssh登录等(二)

    主要是对ssh工具进行配置 xff0c 修改监听 接入的端口 xff0c 限制接入者的ip地址 xff0c 身份等 1 修改 ssh 的配置文件 xff1a etc ssh sshd config 先查看一下配置文件的属性 ls al et
  • CentOS8 手工编译安装 Realtek 8125 2.5G网卡驱动

    刚组装的电脑 xff0c 用了华擎 Z390竞技专用主板6 xff0c 带了一个 Realtek 8125 2 5G高速网卡和intel I219 V千兆网卡 xff0c 安装后发现没有8125网卡的驱动 xff0c 所以找了教程 xff0
  • 【图神经网络】从0到1使用PyG手把手创建异构图

    从0到1用PyG创建异构图 异构图创建异构图电影评分数据集MovieLens建立二分图数据集转换为可训练的数据集 建立异构图神经网络以OGB数据集为例HeteroData中常用的函数将简单图神经网络转换为异质图神经网络 GraphGym的使