在具体的安装之前,你可以通过以下命令代码查看自己电脑中是否存在相关的依赖(比如我,就经常忘记自己的电脑里装过啥子):
torch.cuda.is_available()
如果返回结果是True,那么恭喜,你可以直接退出此操作了。不然,则接着cmd输入以下命令:
nvcc -V
来检查CUDA是否安装。如果已经安装可以跳过下面CUDA的安装介绍。
捷径
pytorch为我们提供了一条捷径可走。只需要在pytorch官网选择相应的版本就可以conda安装:
cmd使用如下命令,conda会自动集成所有的依赖,包括cuda。
conda install pytorch torchvision cudatoolkit=10.2 -c pytorch
但是,由于需要下载的模块较大,经常会存在time out并自动结束下载。对此有两种不同的对策:
- 添加国内镜像。
- 使用命令行设置conda 的最大time out时间。
以上两步操作都可以在别的博客上找到。但是,很不幸,如果你一直无法从命令行窗口直接下载好所有的依赖(比如我),就只有手动去安装相关环境了。
原材料
CUDA。CUDA(Compute Unified Device Architecture),是显卡厂商NVIDIA推出的运算平台。 CUDA™是一种由NVIDIA推出的通用并行计算架构,该架构使GPU能够解决复杂的计算问题。 许多帖子都说需要安装VS,但是我们并没有安装,可能以后会出问题,如果出了问题再补上这部分的操作。
cudnn。cudnn是pytorch搭建深度学习模型的依赖,没有它,不能运行卷积等操作。
GPU版本的pytorch。这个没什么好说,如果你原来有别的版本的pytorch,会自动将其卸载掉。
CUDA安装
CUDA可以从官网上获取。红框框就是我选的配置。然后下载这个巨大的文件就可以了。值得庆幸的是这个文件下得还挺快。
安装过程需要几个选项,具体过程可以看:https://www.cnblogs.com/arxive/p/11198420.html
安装的时候记住这几个文件夹,一会有大用:
之后天剑CUDA的环境变量:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\libnvvp
此时使用上文提到的nvcc -V,说明已经成了:
cuDNN下载
之后需要下载cuDNN
。下载这个需要注册一个官方账号,这个大家自己慢慢填吧。下载完解压之后得到这几个文件:
将这仨文件夹里面的文件分别复制到CUDA路径下的三个对应文件中:
cuDNN配置结束。
GPU版本pytorch安装
鉴于pip conda安装都因为网络问题而无法下载,所以直接从pytorch官网所指定的网站上下载whl文件自己安装:
这个网站进去之后长这样,选择自己所需的pytorch版本:
我选择了这个:torch-1.5.0+cu92-cp36-cp36m-win_amd64.whl。
通过pip install whl文件的绝对路径 安装此文件,或者cd进入whl文件所在的文件夹直接:
pip install torch-1.5.0+cu92-cp36-cp36m-win_amd64.whl
。等待安装结束即可。
最后,我们判断GPU版本的pytorch是否可用:
>>> import torch
>>> torch.cuda.is_available()
True
>>> exit()
True表示配置成功。
当然,可能在运行实际代码的过程中缺乏依赖,那时候,下载对应的模块即可。
代码
在实践中使用GPU,需要将变量与模型都转化到GPU上。最开始可以设置使用那块GPU(我只有一块…)
print(torch.cuda.is_available())
torch.cuda.set_device(0) # 设置GPU
以GAT为例,在定义模型时即将model转移到GPU上:
from utils.util import *
from config import *
from network.SNGCN import *
from network.GCN import *
from network.GAT import *
import torch.optim as optim
from sklearn.metrics import f1_score
from sklearn.metrics import accuracy_score
import time
import numpy as np
import torch
# print(torch.cuda.device_count()) # 可以使用的GPU数量
print(torch.cuda.is_available())
torch.cuda.set_device(0)
util = Util()
cfg = Config()
if cfg.model == 'GCN':
model = GCN()
if cfg.model == 'SNGCN':
model = SNGCN()
if cfg.model == 'GAT':
model = model = GAT(cfg.input_dims[0], cfg.input_dims[1],cfg.classes, 2)
print(model)
if cfg.use_gpu: # 使用GPU
model.cuda()
def eval_net(model, test_data_loader, k):
model.eval()
avg_loss = 0.0
pred_y = []
labels = []
for ii, data in enumerate(test_data_loader):
A = data[0]
X = data[1]
if cfg.use_gpu: # 使用GPU
A = A.cuda()
X = X.cuda()
out = model(X, A).cpu() # 将输出放回CPU计算
loss = F.cross_entropy(out, data[2].long())
pred_y.extend(torch.max(out, 1)[1].data.cpu().numpy().tolist())
labels.extend(data[-1].data.cpu().numpy().tolist())
avg_loss += loss.data.item()
size = len(test_data_loader.dataset)
assert len(pred_y) == size and len(labels) == size
# f1 = f1_score(labels, pred_y, average='None')
f1 = f1_score(labels, pred_y, average='micro')
acc = accuracy_score(labels, pred_y)
print('epoch:{} \t test_acc:{}'.format(k, acc))
return acc
train_loader, test_loader = util.load_data()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=cfg.init_lr)
best_acc = 0.0
accs = []
for epoch in range(1,cfg.epoch+1):
start = time.time()
total_loss = 0.0
for ii, data in enumerate(train_loader):
model.zero_grad() # 梯度清零
A = data[0]
X = data[1]
L = torch.from_numpy(np.array(list(data[2]))).long()
if cfg.use_gpu is True:
A = A.cuda()
X = X.cuda()
out = model(X, A).cpu()
loss = criterion(out, L)
loss.backward() # 反向传播
optimizer.step()
total_loss += loss.data.item()
if ii % 5 == 0: # 5个batch输出
# train_avg_loss = total_loss / len(train_label)
train_pre = torch.max(out, 1)[1].data.cpu().numpy().tolist()
train_acc = accuracy_score(L, train_pre)
print('batch: {}\t train_acc:{}\t'.format(ii, train_acc))
end = time.time()
print('Epoch:{}---------loss:{}-----------time:{}'.format(epoch,total_loss,(end-start)))
acc = eval_net(model, test_loader, epoch)
if best_acc < acc:
best_acc = acc
# write_result(model.model_name, pred_y)
torch.save(model, './models/{}'.format(cfg.model))
接下来就可以训练。可以看到在10000左右的数据集上训练1个Epoch时间大概是6秒:
GAT(
(attention_0): GraphAttentionLayer (50 -> 128)
(attention_1): GraphAttentionLayer (50 -> 128)
(dense): Linear(in_features=256, out_features=2, bias=True)
)
batch: 0 train_acc:0.5703125
batch: 5 train_acc:0.5078125
batch: 10 train_acc:0.484375
batch: 15 train_acc:0.5859375
batch: 20 train_acc:0.5546875
batch: 25 train_acc:0.5234375
batch: 30 train_acc:0.6171875
batch: 35 train_acc:0.5234375
batch: 40 train_acc:0.5625
batch: 45 train_acc:0.5546875
batch: 50 train_acc:0.5859375
batch: 55 train_acc:0.6323529411764706
Epoch:1---------loss:64.92530226707458-----------time:5.915594577789307
epoch:1 test_acc:0.6738885762521103
作为对比,不使用GPU,时间是38秒左右,可见GPU的能力真的不是吹啊:
Epoch:1---------loss:66.55792260169983-----------time:37.960792779922485