如何正确重塑Tensor?PyTorch Geometric中GCN邻接矩阵维度调整
问题解答:Tensor重塑与GCN归一化邻接矩阵维度调整
嗨,我来帮你搞定这两个问题:
1. 如何正确重塑Tensor?
在PyTorch里,重塑Tensor主要有两个常用方法,各有适用场景:
view():速度快,但要求Tensor是连续存储的(如果不确定,可以先用contiguous()转换),它不会复制数据,只是改变数据的视图。reshape():更灵活,不管Tensor是否连续,都会自动处理——如果原Tensor连续,就和view()一样;如果不连续,会自动复制一份连续的Tensor再重塑。
举个简单例子:
import torch # 创建一个2×3×4的Tensor x = torch.randn(2, 3, 4) # 重塑为2×12 x_reshaped = x.reshape(2, 12) # 用view的话,先确保连续(如果原Tensor已经连续可以省略contiguous()) x_viewed = x.contiguous().view(2, 12)
另外,你可以用-1让PyTorch自动计算某个维度的大小,比如x.reshape(-1, 6)会自动算出第一维度是4(因为2×3×4=24,24÷6=4),最终得到4×6的Tensor。
2. 调整GCN归一化邻接矩阵维度为(50,50)
先解释下你当前的情况:代码里的norm是每条边对应的归一化系数,因为你的图(加上自环后)总共有500条边,所以它的维度是torch.Size([500])。要转成(50,50)的稠密邻接矩阵,本质是把这些系数放到对应的边位置上,没有边的位置填0,这里有两种简单方法:
方法一:稀疏矩阵转稠密矩阵
利用torch.sparse_coo_tensor创建稀疏邻接矩阵,再转成稠密格式:
import torch from torch_geometric.nn import MessagePassing from torch_geometric.utils import add_self_loops, degree from torch_geometric.data import Data from torch_geometric.utils import erdos_renyi_graph edge_index = erdos_renyi_graph(50, edge_prob=0.2) x = torch.eye(50, 50) data = Data(edge_index=edge_index, x=x,) edge_index, _ = add_self_loops(edge_index, num_nodes=data.x.size(0)) row, col = edge_index deg = degree(col, x.size(0), dtype=x.dtype) deg_inv_sqrt = deg.pow(-0.5) norm = deg_inv_sqrt[row] * deg_inv_sqrt[col] # 创建稀疏COO矩阵并转为稠密矩阵 adj_norm = torch.sparse_coo_tensor(edge_index, norm, (50, 50)).to_dense() print(adj_norm.size()) # 输出: torch.Size([50, 50])
方法二:直接初始化稠密矩阵填充
先创建全0的(50,50)矩阵,再把norm的值放到对应的(row, col)位置:
# 初始化全0的稠密邻接矩阵 adj_norm = torch.zeros(50, 50, dtype=x.dtype) # 将每条边的归一化系数填充到对应位置 adj_norm[row, col] = norm print(adj_norm.size()) # 输出: torch.Size([50, 50])
这两种方法都能得到你想要的(50,50)维度的归一化邻接矩阵,你可以根据自己的需求选择——如果后续需要进行稀疏运算,保留稀疏矩阵会更节省内存;如果需要稠密矩阵的操作,转成稠密格式就好。
内容的提问来源于stack exchange,提问作者TinaTz
相关产品推荐
相关产品推荐

