目录
PyTorch fundamental functions
torch.cuda()方法
torch.cuda.empty_caches()
torch file
.pt, .pth, .pkl文件
torch.save()和torch.load()函数
torch.nn
传统建模方法
torch.nn.ModuleList()
torch.nn.Sequential()
torch.nn.Linear()
torch.nn.BatchNorm1d()
torch.nn.dropout()
torch.nn.init()
torch 创建张量tensor
torch.tensor()方法
torch.Tensor()方法
torch.randn()函数
torch.randperm(n)函数
torch.ones(*sizes, out=None)函数
torch.zeros(sizes, out=None)函数
torch 操作operation
加
torch.add(input, value, other, out=None)函数
torch.sum()函数
减
乘
torch.mm()函数和torch.mul()函数
torch.matmul()函数
torch.pow()函数
除
torch.view()函数
torch 统计statistics
torch.size()函数
torch.numel()函数
torch.mean()函数
torch.utils
torch.utils.data.Dataset()函数
torch_scatter package
torch_sparse package
torch_sparse.SparseTensor
torch_geometric package
torch_geometric.nn.GATConv
torch_geometric.data.Data
torch_geometric.loader.NeighborSample
torch_geometric.loader.RandomNodeSampler包
torch_geometric报错(一): "找不到指定的模块"
torch.nonzero()方法,返回非零元素的索引。
torch.tensor([0,1,2,0]).nonzero()
tensor([[1], [2]])
返回符合条件元素的索引index,以元素tuple形式给出,参考np.where(condition)。
a = torch.tensor([2,4,6,8,10])
torch.where(a > 5) # 得到元组tuple返回的index结果
'''
(array([2, 3, 4], dtype=int64),)
'''
# 如果得到index数组,需要加索引提取
torch.where(a > 5)[0]
'''
array([2, 3, 4], dtype=int64)
'''
pytorch深度学习框架在训练时,大多是利用GPU来提高训练速度,torch通过cuda()方法使用GPU。
cuda()方法将数据和模型送入GPU中。
model = MyNet() # 自己定义的网络类
model.cuda()
img = img.cuda()
释放显存
torch有后缀名为.pt, .pth, .pkl等后缀名的文件,但它们职级上没有什么不同,只是后缀名不同而已,根据个人喜好,用不同的后缀名。
torch.save()函数一般用于保存文件/模型,torch.load()函数一般用于加载文件/模型。
注意:torch.save()保存的是模型参数,而不是模型本身!
# 保存model
torch.save(model.state_dict(), mymodel.pth) # 只是保存模型权重参数,不保存模型结构
# 加载模型
model = My_model(*args, **kwargs) # 这里需要重新定义模型结构,mymodel
model.load_state_dict(torch.load(mymodel.pth)) # 这里根据模型结构,调用存储的模型参数
model.eval()
保存整个model的状态
# 保存model
torch.save(model, mymodel.pth) # 保存整个model的状态
# 加载model
model = torch.load(mymodel.pth) # 这里已经不需要重构模型结构了,直接load就可以
model.eval()
class model1(nn.Module):
def __init__(self):
super(model1,self).__init__()
self.linear1=nn.Linear(1,10)
self.activation1=nn.ReLU()
self.linear2=nn.Linear(10,100)
self.activation2=nn.ReLU()
self.linear3=nn.Linear(100,10)
self.activation3=nn.ReLU()
self.linear4=nn.Linear(10,1)
def forward(self,x):
out=self.linear1(x)
out=self.activation1(out)
out=self.linear2(out)
out=self.activation2(out)
out=self.linear3(out)
out=self.activation3(out)
out=self.linear4(out)
return out
nn.ModuleList()是一个无序性的序列,并没有实现forward()方法
nn.ModuleList()方法:
import torch
import torch.nn as nn
class testNet(nn.Module):
def __init__(self):
super(testNet, self).__init__()
self.combine = nn.Sequential(
nn.Linear(100,50),
nn.Linear(50,25),
)
def forward(self, x):
x = self.combine(x)
return x
testnet = testNet()
input_x = torch.ones(100)
output_x = testnet(input_x)
print(output_x)
nn.Sequential()定义的网络中各层会按照定义的顺序进行级联,需要保证各层的输入和输出之间要衔接,并且nn.Sequential实现了forward方法。
import torch
import torch.nn as nn
class testNet(nn.Module):
def __init__(self):
super(testNet, self).__init__()
self.combine = nn.Sequential(
nn.Linear(100,50),
nn.Linear(50,25),
)
def forward(self, x):
x = self.combine(x)
return x
testnet = testNet()
input_x = torch.ones(100)
output_x = testnet(input_x)
print(output_x)
nn.Linear()用于设置网络中全连接层的
相当于一个[batch_size, in_features]的输入tensor变换成了一个[batch_size, out_features]的输出tensor。
将num_features那一维进行归一化,防止梯度散射。
以概率p对input tensor的值随机置0。
Hinton提出用于在training时防止过拟合的trick
torch.nn.functional.dropout(input, p=0.5, training=True, inplace=False)
权值初始化方法
torch.tensor()创建张量。
arr = np.ones((3, 3))
t = torch.tensor(arr)
# 或直接创建一个空tensor
t = torch.tensor()
torch.Tensor是一种包含单一数据类型元素的多维矩阵。
定义了7种cpu tensor类型和8种GPU tensor类型:torch.Tensor默认的是(torch.FloatTensor)
import torch
x = torch.Tensor(2, 3) # 生成一个2*3的Tensor张量
# 将Tensor转换为numpy数组
y = x.numpy()
# 将numpy数组转换为Tensor
z = torch.from_numpy(y)
torch.randn()函数,产生大小为指定的,正态分布的采样点,数据类型是tensor
a=torch.randn(3) #生成一个一维的矩阵
b=torch.randn(1,3) #生成一个二维的矩阵
print(a)
print(b)
torch.mean(a)
torch.randperm(n)函数返回一个随机打散的0~n-1 tensor数组
torch.randperm(4)
-----------------------------
tensor([3, 1, 2, 0])
torch.Tensor
torch.ones()函数返回一个全为1的张量tensor,形状由可变参数sizes定义。
torch.ones(2, 3)
1 1 1
1 1 1
torch.zeros()函数,返回一个全为标量0的张量,形状由可变参数sizes定义。
torch.zeros(2, 3)
0 0 0
0 0 0
torch.add()函数对other张量的每一个元素乘以一个标量值value,并加到输入张量input上,并返回结果到一个新的张量out,即out = input + (other * value)。
torch.sum()函数对输入tensor的某一维求和
a = torch.ones((2,3))
torch.sum(a, dim=0) # 对行求和
torch.sum(a, dim=1) # 对列求和
torch.matmul()函数几乎用于所有矩阵/向量相乘的情况,其乘法规则由参与乘法的两个张量的维度而定,包括: 1d * 1d, 2d * 2d, 1d * 2d, 2d * 1d, 3d and above.
>>> vec1 = torch.tensor([1, 2, 3])
>>> vec2 = torch.tensor([2, 3, 4])
>>> torch.matmul(vec1, vec2)
tensor(20)
>>> torch.dot(vec1, vec2)
tensor(20)
# 两个一维张量的元素个数要相同!
>>> vec1 = torch.tensor([1, 2, 3])
>>> vec2 = torch.tensor([2, 3, 4, 5])
>>> torch.matmul(vec1, vec2)
Traceback (most recent call last):
File "", line 1, in
RuntimeError: inconsistent tensor size, expected tensor [3] and src [4] to have the same number of elements, but got 3 and 4 elements respectively
>>> arg1 = torch.tensor([[1, 2], [3, 4]])
>>> arg1
tensor([[1, 2],
[3, 4]])
>>> arg2 = torch.tensor([[-1], [2]])
>>> arg2
tensor([[-1],
[ 2]])
>>> torch.matmul(arg1, arg2)
tensor([[3],
[5]])
>>> torch.mm(arg1, arg2)
tensor([[3],
[5]])
>>> arg2 = torch.tensor([[-1], [2], [1]])
>>> torch.matmul(arg1, arg2) # 要求满足矩阵乘法的条件
Traceback (most recent call last):
File "", line 1, in
RuntimeError: mat1 and mat2 shapes cannot be multiplied (2x2 and 3x1)
>>> arg1 = torch.tensor([-1, 2])
>>> arg2 = torch.tensor([[1, 2], [3, 4]])
>>> torch.matmul(arg1, arg2)
tensor([5, 6])
>>> arg1 = torch.unsqueeze(arg1, 0) # 在一维张量前增加一个维度
>>> arg1.shape
torch.Size([1, 2])
>>> ans = torch.mm(arg1, arg2) # 进行矩阵乘法
>>> ans
tensor([[5, 6]])
>>> ans = torch.squeeze(ans, 0) # 移除增加的维度
>>> ans
tensor([5, 6])
torch.pow()函数,对输入的每个分量求幂次运算。
torch.view(a, b)函数的作用是重构张量的维度为a行b列,相当于numpy中的resize()功能。
tensor([[1., 2.],
[3., 4.],
[5., 6.]])
tensor([[1., 2., 3.],
[4., 5., 6.]])
torch.sort(input, dim=- 1, descending=False, stable=False, *, out=None)
- input (Tensor) – the input tensor
形式上与 numpy.narray 类似- dim (int, optional) – the dimension to sort along
维度,对于二维数据:dim=0 按列排序,dim=1 按行排序,默认 dim=1- descending (bool, optional) – controls the sorting order (ascending or descending)
降序,descending=True 从大到小排序,descending=False 从小到大排序,默认 descending=FlaseA tuple of (sorted_tensor, sorted_indices) is returned, where the sorted_indices are the indices of the elements in the original inputtensor.
import torch
x = torch.randn(3,4)
x #初始值,始终不变
tensor([[-0.9950, -0.6175, -0.1253, 1.3536],
[ 0.1208, -0.4237, -1.1313, 0.9022],
[-1.1995, -0.0699, -0.4396, 0.8043]])
sorted, indices = torch.sort(x) #按行从小到大排序
sorted
tensor([[-0.9950, -0.6175, -0.1253, 1.3536],
[-1.1313, -0.4237, 0.1208, 0.9022],
[-1.1995, -0.4396, -0.0699, 0.8043]])
indices
tensor([[0, 1, 2, 3],
[2, 1, 0, 3],
[0, 2, 1, 3]])
torch.size()函数,查看张量的维度信息
torch.numel()函数,查看一个张量有多少个元素,返回int类型的元素个数。
torch.mean()函数输入各个向量的均值。
代表自定义数据集方法的类。用户可以通过继承该类来自定义自己的数据集类,在继承时要求用户重载__len__()和__getitem__()这两个魔法方法。
from torch_scatter import
PyG实现GAT,使用封装好的GATConv函数。
from torch_geometric.nn import GATConv # torch_geometirc继承了GAT模型。
# 导入需要的包,遇到安装问题可在官方文档或其他文章查找解决方案
import torch
import torch.nn.functional as F
# 导入GCN层、GraphSAGE层和GAT层
from torch_geometric.nn import GCNConv, SAGEConv, GATConv
from torch_geometric.datasets import Planetoid
# 加载数据,出错可自行下载,解决方案见下文
dataset = Planetoid(root='./tmp/Cora', name='Cora')
class GAT_NET(torch.nn.Module):
def __init__(self, features, hidden, classes, heads=4):
super(GAT_NET, self).__init__()
self.gat1 = GATConv(features, hidden, heads=4) # 定义GAT层,使用多头注意力机制
self.gat2 = GATConv(hidden*heads, classes) # 因为多头注意力是将向量拼接,所以维度乘以头数。
def forward(self, data):
x, edge_index = data.x, data.edge_index
x = self.gat1(x, edge_index)
x = F.relu(x)
x = F.dropout(x, training=self.training)
x = self.gat2(x, edge_index)
return F.log_softmax(x, dim=1)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GAT_NET(dataset.num_node_features, 16, dataset.num_classes, heads=4).to(device) # 定义GAT
data = dataset[0].to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=5e-4)
model.train()
for epoch in range(200):
optimizer.zero_grad()
out = model(data)
loss = F.nll_loss(out[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
model.eval()
_, pred = model(data).max(dim=1)
correct = int(pred[data.test_mask].eq(data.y[data.test_mask]).sum().item())
acc = correct / int(data.test_mask.sum())
print('GAT Accuracy: {:.4f}'.format(acc))
torch_geometric提供了一种使用多属性表示图的数据类型Data
import torch
from torch_geometric.data import Data
# 由于是无向图,因此有 4 条边:(0 -> 1), (1 -> 0), (1 -> 2), (2 -> 1)
edge_index = torch.tensor([[0, 1, 1, 2],
[1, 0, 2, 1]], dtype=torch.long)
# 节点的特征
x = torch.tensor([[-1], [0], [1]], dtype=torch.float)
data = Data(x=x, edge_index=edge_index)
from torch_geometric.loader import NeighborSampler, RandomNodeSampler
A data loader that performs neighbor sampling as introduced in the "Inductive Representation Learning on Large Graphs" paper. 它允许对GNNs mini-batch training进行neighbor采样,并训练模型,使得大规模全连接的GNNs模型训练成为可能。
核心想法:给定mini-batch的节点和图卷积的层数L,以及每一层需要采样的邻居数目sizes,依次从每一层到第L层,对每一层进行邻居采样并返回一个bipartite(双方)子图。
For i in L:
L层采样完成后,返回结果(batch_size, n_id, adjs),
- 其中batch_size就是mini-batch的节点数目,
- n_id是包含所有在L层卷积中遇到的节点的list,且target节点在n_id前几位。
- adjs是一个list,包含了从第L层到第1层采样的结果,所以adjs中的子图是从大到小的。每一层采样返回的结果具体形式为 (edge_index, e_id, size)。
- edge_index是采样得到的bipartite子图中source节点到target节点的边。
- e_id是edge_index的边在原始大图中的IDs,
- size就是bipartite子图的shape。
以下是一个2
层采样的示意图,注意在第2
层采样的时候,使用了第1
层中涉及到的所有节点,包括出发点。
————————————————
版权声明:本文为CSDN博主「每天都想躺平的大喵」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_39925939/article/details/121458145
实现一个数据集的随机划分,使用num_parts确定划分数量
problem: 兼容性错误
solution: 重装package
pip install torch-scatter==2.0.9 -f https://pytorch-geometric.com/whl/torch-1.10.0+cpu.html
原因: 将单个None赋给了多个值。