当前位置 : 主页 > 手机开发 > ROM >

pytorch

来源:互联网 收集:自由互联 发布时间:2021-06-10
一、Torch与Numpy Torch可以把tensor放到GPU加速上训练,就像Numpy把array放到CPU上训练一样。 torch tensor和numpy array的相互转换 tensor= torch.from_numpy (array) array=tensor .numpy() 1 import torch 2 import n

一、Torch与Numpy

Torch可以把tensor放到GPU加速上训练,就像Numpy把array放到CPU上训练一样。

torch tensor和numpy array的相互转换

tensor=torch.from_numpy(array)

array=tensor.numpy()

 1 import torch
 2 import numpy as np
 3 
 4 np_data = np.arange(6).reshape((2, 3))
 5 torch_data = torch.from_numpy(np_data)
 6 tensor2array = torch_data.numpy()
 7 print(
 8     \nnumpy array:, np_data,          # [[0 1 2], [3 4 5]]
 9     \ntorch tensor:, torch_data,      #  0  1  2 \n 3  4  5    [torch.LongTensor of size 2x3]
10     \ntensor to array:, tensor2array, # [[0 1 2], [3 4 5]]
11 )

Torch中的数学运算,np.数学函数    torch.数学函数一个样。

 1 # abs 绝对值计算
 2 data = [-1, -2, 1, 2]
 3 tensor = torch.FloatTensor(data)  # 转换成32位浮点 tensor
 4 print(
 5     \nabs,
 6     \nnumpy: , np.abs(data),          # [1 2 1 2]
 7     \ntorch: , torch.abs(tensor)      # [1 2 1 2]
 8 )
 9 
10 # sin   三角函数 sin
11 print(
12     \nsin,
13     \nnumpy: , np.sin(data),      # [-0.84147098 -0.90929743  0.84147098  0.90929743]
14     \ntorch: , torch.sin(tensor)  # [-0.8415 -0.9093  0.8415  0.9093]
15 )
16 
17 # mean  均值
18 print(
19     \nmean,
20     \nnumpy: , np.mean(data),         # 0.0
21     \ntorch: , torch.mean(tensor)     # 0.0
22 )

矩阵乘法   np.matmul和torch.mm一样

 1 # matrix multiplication 矩阵点乘
 2 data = [[1,2], [3,4]]
 3 tensor = torch.FloatTensor(data)  # 转换成32位浮点 tensor
 4 # correct method
 5 print(
 6     \nmatrix multiplication (matmul),
 7     \nnumpy: , np.matmul(data, data),     # [[7, 10], [15, 22]]
 8     \ntorch: , torch.mm(tensor, tensor)   # [[7, 10], [15, 22]]
 9 )
10 
11 # !!!!  下面是错误的方法 !!!!
12 data = np.array(data)
13 print(
14     \nmatrix multiplication (dot),
15     \nnumpy: , data.dot(data),        # [[7, 10], [15, 22]] 在numpy 中可行
16     \ntorch: , tensor.dot(tensor)     # torch 会转换成 [1,2,3,4].dot([1,2,3,4) = 30.0
17 )

在>=0.3.0版本中,tensor.dot()只能针对一维数组

1 tensor.dot(tensor)     # torch 会转换成 [1,2,3,4].dot([1,2,3,4) = 30.0
2 
3 # 变为
4 torch.dot(tensor.dot(tensor)

 

二、变量

Torch里面的Variable就是一个鸡蛋篮子,里面的鸡蛋(tensor)在不停地变动如果用Variable进行计算,返回也是一个同类型的Variable

 1 import torch
 2 from torch.autograd import Variable # torch 中 Variable 模块
 3 
 4 # 先生鸡蛋
 5 tensor = torch.FloatTensor([[1,2],[3,4]])
 6 # 把鸡蛋放到篮子里, requires_grad是参不参与误差反向传播, 要不要计算梯度
 7 variable = Variable(tensor, requires_grad=True)
 8 
 9 print(tensor)
10 """
11  1  2
12  3  4
13 [torch.FloatTensor of size 2x2]
14 """
15 
16 print(variable)
17 """
18 Variable containing:
19  1  2
20  3  4
21 [torch.FloatTensor of size 2x2]
22 """

tensor和variable的计算没有什么不同。但是,Variable 计算时, 它在背景幕布后面一步步默默地搭建着一个庞大的系统, 叫做计算图, computational graph. 这个图是用来干嘛的? 原来是将所有的计算步骤 (节点) 都连接起来, 最后进行误差反向传递的时候, 一次性将所有 variable 里面的修改幅度 (梯度) 都计算出来, 而 tensor 就没有这个能力。

 

三、激励函数

y=AF(Wx)

AF是激励函数,掰弯神器,套在Wx上面,Wx就被掰弯了。

它其实就是另外一个非线性函数. 比如说relu, sigmoid, tanh. 将这些掰弯利器嵌套在原有的结果之上, 强行把原有的线性结果给扭曲了. 使得输出结果 y 也有了非线性的特征. 举个例子, 比如我使用了 relu 这个掰弯利器, 如果此时 Wx 的结果是1, y 还将是1, 不过 Wx 为-1的时候, y 不再是-1, 而会是0. 你甚至可以创造自己的激励函数来处理自己的问题, 不过要确保的是这些激励函数必须是可以微分的。

当你使用特别多层(三层以上)的神经网络, 在掰弯的时候, 玩玩不得随意选择利器. 因为这会涉及到梯度爆炸, 梯度消失的问题.

import torch
import torch.nn.functional as F     # 激励函数都在这
from torch.autograd import Variable

# 一些假数据
x = torch.linspace(-5, 5, 200)  
x = Variable(x)

# 几种常用的 激励函数
y_relu = F.relu(x)
y_sigmoid = F.sigmoid(x)
y_tanh = F.tanh(x)
y_softplus = F.softplus(x)
y_softmax = F.softmax(x)  #softmax 比较特殊, 不能直接显示, 不过他是关于概率的, 用于分类

 

四、线性回归

建立数据集

import torch
import matplotlib.pyplot as plt

x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)  # x data (tensor), shape=(100, 1)
y = x.pow(2) + 0.2*torch.rand(x.size())                 # noisy y data (tensor), shape=(100, 1)

# 画图
plt.scatter(x.data.numpy(), y.data.numpy())
plt.show()

建立神经网络

建立一个神经网络我们可以直接运用 torch 中的体系. 先定义所有的层属性(__init__()), 然后再一层层搭建(forward(x))层于层的关系链接. 建立关系的时候, 我们会用到激励函数。

 1 import torch
 2 import torch.nn.functional as F     # 激励函数都在这
 3 
 4 class Net(torch.nn.Module):  # 继承 torch 的 Module
 5     def __init__(self, n_feature, n_hidden, n_output):
 6         super(Net, self).__init__()     # 继承 __init__ 功能
 7         # 定义每层用什么样的形式
 8         self.hidden = torch.nn.Linear(n_feature, n_hidden)   # 隐藏层线性输出
 9         self.predict = torch.nn.Linear(n_hidden, n_output)   # 输出层线性输出
10 
11     def forward(self, x):   # 这同时也是 Module 中的 forward 功能
12         # 正向传播输入值, 神经网络分析出输出值
13         x = F.relu(self.hidden(x))      # 激励函数(隐藏层的线性值)
14         x = self.predict(x)             # 输出值
15         return x
16 
17 net = Net(n_feature=1, n_hidden=10, n_output=1)
18 
19 print(net)  # net 的结构
20 """
21 Net (
22   (hidden): Linear (1 -> 10)
23   (predict): Linear (10 -> 1)
24 )
25 """

训练网络

 1 # optimizer 是训练的工具
 2 optimizer = torch.optim.SGD(net.parameters(), lr=0.2)  # 传入 net 的所有参数, 学习率
 3 loss_func = torch.nn.MSELoss()      # 预测值和真实值的误差计算公式 (均方差)
 4 
 5 for t in range(100):
 6     prediction = net(x)     # 喂给 net 训练数据 x, 输出预测值
 7 
 8     loss = loss_func(prediction, y)     # 计算两者的误差
 9 
10     optimizer.zero_grad()   # 清空上一步的残余更新参数值
11     loss.backward()         # 误差反向传播, 计算参数更新值
12     optimizer.step()        # 将参数更新值施加到 net 的 parameters 上

可视化训练过程

 1 import matplotlib.pyplot as plt
 2 
 3 plt.ion()   # 画图
 4 plt.show()
 5 
 6 for t in range(200):
 7 
 8     ...
 9     loss.backward()
10     optimizer.step()
11 
12     # 接着上面来
13     if t % 5 == 0:
14         # plot and show learning process
15         plt.cla()
16         plt.scatter(x.data.numpy(), y.data.numpy())
17         plt.plot(x.data.numpy(), prediction.data.numpy(), r-, lw=5)
18         plt.text(0.5, 0, Loss=%.4f % loss.data.numpy(), fontdict={size: 20, color:  red})

分享图片

 

五、分类器

建立数据集

 1 import torch
 2 import matplotlib.pyplot as plt
 3 
 4 # 假数据
 5 n_data = torch.ones(100, 2)         # 数据的基本形态
 6 x0 = torch.normal(2*n_data, 1)      # 类型0 x data (tensor), shape=(100, 2)
 7 y0 = torch.zeros(100)               # 类型0 y data (tensor), shape=(100, )
 8 x1 = torch.normal(-2*n_data, 1)     # 类型1 x data (tensor), shape=(100, 1)
 9 y1 = torch.ones(100)                # 类型1 y data (tensor), shape=(100, )
10 
11 # 注意 x, y 数据的数据形式是一定要像下面一样 (torch.cat 是在合并数据)
12 x = torch.cat((x0, x1), 0).type(torch.FloatTensor)  # FloatTensor = 32-bit floating
13 y = torch.cat((y0, y1), ).type(torch.LongTensor)    # LongTensor = 64-bit integer
14 
15 # plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=y.data.numpy(), s=100, lw=0, cmap=‘RdYlGn‘)
16 # plt.show()
17 
18 # 画图
19 plt.scatter(x.data.numpy(), y.data.numpy())
20 plt.show()

建立神经网络

建立一个神经网络我们可以直接运用 torch 中的体系. 先定义所有的层属性(__init__()), 然后再一层层搭建(forward(x))层于层的关系链接. 这个和我们在前面 regression 的时候的神经网络基本没差. 建立关系的时候, 我们会用到激励函数。

 1 import torch
 2 import torch.nn.functional as F     # 激励函数都在这
 3 
 4 class Net(torch.nn.Module):     # 继承 torch 的 Module
 5     def __init__(self, n_feature, n_hidden, n_output):
 6         super(Net, self).__init__()     # 继承 __init__ 功能
 7         self.hidden = torch.nn.Linear(n_feature, n_hidden)   # 隐藏层线性输出
 8         self.out = torch.nn.Linear(n_hidden, n_output)       # 输出层线性输出
 9 
10     def forward(self, x):
11         # 正向传播输入值, 神经网络分析出输出值
12         x = F.relu(self.hidden(x))      # 激励函数(隐藏层的线性值)
13         x = self.out(x)                 # 输出值, 但是这个不是预测值, 预测值还需要再另外计算
14         return x
15 
16 net = Net(n_feature=2, n_hidden=10, n_output=2) # 几个类别就几个 output
17 
18 print(net)  # net 的结构
19 """
20 Net (
21   (hidden): Linear (2 -> 10)
22   (out): Linear (10 -> 2)
23 )
24 """

训练网络

 1 # optimizer 是训练的工具
 2 optimizer = torch.optim.SGD(net.parameters(), lr=0.02)  # 传入 net 的所有参数, 学习率
 3 # 算误差的时候, 注意真实值!不是! one-hot 形式的, 而是1D Tensor, (batch,)
 4 # 但是预测值是2D tensor (batch, n_classes)
 5 loss_func = torch.nn.CrossEntropyLoss()
 6 
 7 for t in range(100):
 8     out = net(x)     # 喂给 net 训练数据 x, 输出分析值
 9 
10     loss = loss_func(out, y)     # 计算两者的误差
11 
12     optimizer.zero_grad()   # 清空上一步的残余更新参数值
13     loss.backward()         # 误差反向传播, 计算参数更新值
14     optimizer.step()        # 将参数更新值施加到 net 的 parameters 上

可视化

 1 import matplotlib.pyplot as plt
 2 
 3 plt.ion()   # 画图
 4 plt.show()
 5 
 6 for t in range(100):
 7 
 8     ...
 9     loss.backward()
10     optimizer.step()
11 
12     # 接着上面来
13     if t % 2 == 0:
14         plt.cla()
15         # 过了一道 softmax 的激励函数后的最大概率才是预测值
16         prediction = torch.max(F.softmax(out), 1)[1]
17         pred_y = prediction.data.numpy().squeeze()
18         target_y = y.data.numpy()
19         plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=pred_y, s=100, lw=0, cmap=RdYlGn)
20         accuracy = sum(pred_y == target_y)/200.  # 预测中有多少和真实值一样
21         plt.text(1.5, -4, Accuracy=%.2f % accuracy, fontdict={size: 20, color:  red})
22         plt.pause(0.1)
23 
24 plt.ioff()  # 停止画图
25 plt.show()

分享图片

 

六、模型的保存、提取

建造数据、搭建网络

 1 torch.manual_seed(1)    # reproducible
 2 
 3 # 假数据
 4 x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1)  # x data (tensor), shape=(100, 1)
 5 y = x.pow(2) + 0.2*torch.rand(x.size())  # noisy y data (tensor), shape=(100, 1)
 6 
 7 def save():
 8     # 建网络
 9     net1 = torch.nn.Sequential(
10         torch.nn.Linear(1, 10),
11         torch.nn.ReLU(),
12         torch.nn.Linear(10, 1)
13     )
14     optimizer = torch.optim.SGD(net1.parameters(), lr=0.5)
15     loss_func = torch.nn.MSELoss()
16 
17     # 训练
18     for t in range(100):
19         prediction = net1(x)
20         loss = loss_func(prediction, y)
21         optimizer.zero_grad()
22         loss.backward()
23         optimizer.step()

保存

1 torch.save(net1, net.pkl)  # 保存整个网络
2 torch.save(net1.state_dict(), net_params.pkl)   # 只保存网络中的参数 (速度快, 占内存少)

提取整个网络

1 def restore_net():
2     # restore entire net1 to net2
3     net2 = torch.load(net.pkl)
4     prediction = net2(x)

只提取网络参数

 1 def restore_params():
 2     # 新建 net3
 3     net3 = torch.nn.Sequential(
 4         torch.nn.Linear(1, 10),
 5         torch.nn.ReLU(),
 6         torch.nn.Linear(10, 1)
 7     )
 8 
 9     # 将保存的参数复制到 net3
10     net3.load_state_dict(torch.load(net_params.pkl))
11     prediction = net3(x)

显示结果

1 # 保存 net1 (1. 整个网络, 2. 只有参数)
2 save()
3 
4 # 提取整个网络
5 restore_net()
6 
7 # 提取网络参数, 复制到新网络
8 restore_params()

 

七、网络的快速搭建

我们用 class 继承了一个 torch 中的神经网络结构, 然后对其进行了修改, 不过还有更快的一招, 用一句话就概括了net1的内容

1 net2 = torch.nn.Sequential(
2     torch.nn.Linear(1, 10),
3     torch.nn.ReLU(),
4     torch.nn.Linear(10, 1)
5 )

两者结构

print(net1)
"""
Net (
  (hidden): Linear (1 -> 10)
  (predict): Linear (10 -> 1)
)
"""
print(net2)
"""
Sequential (
  (0): Linear (1 -> 10)
  (1): ReLU ()
  (2): Linear (10 -> 1)
)
"""

我们会发现 net2 多显示了一些内容, 这是为什么呢? 原来他把激励函数也一同纳入进去了, 但是 net1 中, 激励函数实际上是在 forward() 功能中才被调用的. 这也就说明了, 相比 net2, net1 的好处就是, 你可以根据你的个人需要更加个性化你自己的前向传播过程

 

七、批训练

Dataloader整理数据结构,可以有效迭代数据

 1 import torch
 2 import torch.utils.data as Data
 3 torch.manual_seed(1)    # reproducible
 4 
 5 BATCH_SIZE = 5      # 批训练的数据个数
 6 
 7 x = torch.linspace(1, 10, 10)       # x data (torch tensor)
 8 y = torch.linspace(10, 1, 10)       # y data (torch tensor)
 9 
10 # 先转换成 torch 能识别的 Dataset
11 torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y)
12 
13 # 把 dataset 放入 DataLoader
14 loader = Data.DataLoader(
15     dataset=torch_dataset,      # torch TensorDataset format
16     batch_size=BATCH_SIZE,      # mini batch size
17     shuffle=True,               # 要不要打乱数据 (打乱比较好)
18     num_workers=2,              # 多线程来读数据
19 )
20 
21 for epoch in range(3):   # 训练所有!整套!数据 3 次
22     for step, (batch_x, batch_y) in enumerate(loader):  # 每一步 loader 释放一小批数据用来学习
23         # 假设这里就是你训练的地方...
24 
25         # 打出来一些数据
26         print(Epoch: , epoch, | Step: , step, | batch x: ,
27               batch_x.numpy(), | batch y: , batch_y.numpy())
28 
29 """
30 Epoch:  0 | Step:  0 | batch x:  [ 6.  7.  2.  3.  1.] | batch y:  [  5.   4.   9.   8.  10.]
31 Epoch:  0 | Step:  1 | batch x:  [  9.  10.   4.   8.   5.] | batch y:  [ 2.  1.  7.  3.  6.]
32 Epoch:  1 | Step:  0 | batch x:  [  3.   4.   2.   9.  10.] | batch y:  [ 8.  7.  9.  2.  1.]
33 Epoch:  1 | Step:  1 | batch x:  [ 1.  7.  8.  5.  6.] | batch y:  [ 10.   4.   3.   6.   5.]
34 Epoch:  2 | Step:  0 | batch x:  [ 3.  9.  2.  6.  7.] | batch y:  [ 8.  2.  9.  5.  4.]
35 Epoch:  2 | Step:  1 | batch x:  [ 10.   4.   8.   1.   5.] | batch y:  [  1.   7.   3.  10.   6.]
36 """

可以看出, 每步都导出了5个数据进行学习. 然后每个 epoch 的导出数据都是先打乱了以后再导出.如果我们改变一下 BATCH_SIZE = 8, 这样我们就知道, step=0 会导出8个数据, 但是, step=1 时数据不够则返回这个epoch中剩下的数据

 

八、优化器

为每个优化器建一种网络

 1 # 默认的 network 形式
 2 class Net(torch.nn.Module):
 3     def __init__(self):
 4         super(Net, self).__init__()
 5         self.hidden = torch.nn.Linear(1, 20)   # hidden layer
 6         self.predict = torch.nn.Linear(20, 1)   # output layer
 7 
 8     def forward(self, x):
 9         x = F.relu(self.hidden(x))      # activation function for hidden layer
10         x = self.predict(x)             # linear output
11         return x
12 
13 # 为每个优化器创建一个 net
14 net_SGD         = Net()
15 net_Momentum    = Net()
16 net_RMSprop     = Net()
17 net_Adam        = Net()
18 nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam]

接下来在创建不同的优化器, 用来训练不同的网络. 并创建一个 loss_func 用来计算误差. 我们用几种常见的优化器, SGD, Momentum, RMSprop, Adam.

1 # different optimizers
2 opt_SGD         = torch.optim.SGD(net_SGD.parameters(), lr=LR)
3 opt_Momentum    = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8)
4 opt_RMSprop     = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9)
5 opt_Adam        = torch.optim.Adam(net_Adam.parameters(), lr=LR, betas=(0.9, 0.99))
6 optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam]
7 
8 loss_func = torch.nn.MSELoss()
9 losses_his = [[], [], [], []]   # 记录 training 时不同神经网络的 loss

训练、出图

 1 for epoch in range(EPOCH):
 2     print(Epoch: , epoch)
 3     for step, (b_x, b_y) in enumerate(loader):
 4 
 5         # 对每个优化器, 优化属于他的神经网络
 6         for net, opt, l_his in zip(nets, optimizers, losses_his):
 7             output = net(b_x)              # get output for every net
 8             loss = loss_func(output, b_y)  # compute loss for every net
 9             opt.zero_grad()                # clear gradients for next train
10             loss.backward()                # backpropagation, compute gradients
11             opt.step()                     # apply gradients
12             l_his.append(loss.data.numpy())     # loss recoder

 

九、卷积神经网络

CNN模型

这个 CNN 整体流程是 卷积(Conv2d) -> 激励函数(ReLU) -> 池化, 向下采样 (MaxPooling) -> 再来一遍 -> 展平多维的卷积成的特征图 -> 接入全连接层 (Linear) -> 输出

 1 class CNN(nn.Module):
 2     def __init__(self):
 3         super(CNN, self).__init__()
 4         self.conv1 = nn.Sequential(  # input shape (1, 28, 28)
 5             nn.Conv2d(
 6                 in_channels=1,      # input height
 7                 out_channels=16,    # n_filters
 8                 kernel_size=5,      # filter size
 9                 stride=1,           # filter movement/step
10                 padding=2,      # 如果想要 con2d 出来的图片长宽没有变化, padding=(kernel_size-1)/2 当 stride=1
11             ),      # output shape (16, 28, 28)
12             nn.ReLU(),    # activation
13             nn.MaxPool2d(kernel_size=2),    # 在 2x2 空间里向下采样, output shape (16, 14, 14)
14         )
15         self.conv2 = nn.Sequential(  # input shape (16, 14, 14)
16             nn.Conv2d(16, 32, 5, 1, 2),  # output shape (32, 14, 14)
17             nn.ReLU(),  # activation
18             nn.MaxPool2d(2),  # output shape (32, 7, 7)
19         )
20         self.out = nn.Linear(32 * 7 * 7, 10)   # fully connected layer, output 10 classes
21 
22     def forward(self, x):
23         x = self.conv1(x)
24         x = self.conv2(x)
25         x = x.view(x.size(0), -1)   # 展平多维的卷积图成 (batch_size, 32 * 7 * 7)
26         output = self.out(x)
27         return output
28 
29 cnn = CNN()
30 print(cnn)  # net architecture
31 """
32 CNN (
33   (conv1): Sequential (
34     (0): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
35     (1): ReLU ()
36     (2): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
37   )
38   (conv2): Sequential (
39     (0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
40     (1): ReLU ()
41     (2): MaxPool2d (size=(2, 2), stride=(2, 2), dilation=(1, 1))
42   )
43   (out): Linear (1568 -> 10)
44 )
45 """

训练

下面我们开始训练, 将 x y 都用 Variable 包起来, 然后放入 cnn 中计算 output, 最后再计算误差.省略了计算精确度 accuracy 的部分

 1 optimizer = torch.optim.Adam(cnn.parameters(), lr=LR)   # optimize all cnn parameters
 2 loss_func = nn.CrossEntropyLoss()   # the target label is not one-hotted
 3 
 4 # training and testing
 5 for epoch in range(EPOCH):
 6     for step, (b_x, b_y) in enumerate(train_loader):   # 分配 batch data, normalize x when iterate train_loader
 7         output = cnn(b_x)               # cnn output
 8         loss = loss_func(output, b_y)   # cross entropy loss
 9         optimizer.zero_grad()           # clear gradients for this training step
10         loss.backward()                 # backpropagation, compute gradients
11         optimizer.step()                # apply gradients
12 
13 """
14 ...
15 Epoch:  0 | train loss: 0.0306 | test accuracy: 0.97
16 Epoch:  0 | train loss: 0.0147 | test accuracy: 0.98
17 Epoch:  0 | train loss: 0.0427 | test accuracy: 0.98
18 Epoch:  0 | train loss: 0.0078 | test accuracy: 0.98
19 """

测试

1 test_output = cnn(test_x[:10])
2 pred_y = torch.max(test_output, 1)[1].data.numpy().squeeze()
3 print(pred_y, prediction number)
4 print(test_y[:10].numpy(), real number)
5 
6 """
7 [7 2 1 0 4 1 4 9 5 9] prediction number
8 [7 2 1 0 4 1 4 9 5 9] real number
9 """

 

十、GPU加速运算

修改的地方包括将数据的形式变成 GPU 能读的形式, 然后将 CNN 也变成 GPU 能读的形式. 做法就是在后面加上 .cuda()

1 test_data = torchvision.datasets.MNIST(root=./mnist/, train=False)
2 
3 # !!!!!!!! 修改 test data 形式 !!!!!!!!! #
4 test_x = torch.unsqueeze(test_data.test_data, dim=1).type(torch.FloatTensor)[:2000].cuda()/255.   # Tensor on GPU
5 test_y = test_data.test_labels[:2000].cuda()

再来把我们的 CNN 参数也变成 GPU 兼容形式.

1 class CNN(nn.Module):
2     ...
3 
4 cnn = CNN()
5 
6 # !!!!!!!! 转换 cnn 去 CUDA !!!!!!!!! #
7 cnn.cuda()      # Moves all model parameters and buffers to the GPU.

然后就是在 train 的时候, 将每次的training data 变成 GPU 形式. + .cuda()

 1 for epoch ..:
 2     for step, ...:
 3         # !!!!!!!! 这里有修改 !!!!!!!!! #
 4         b_x = x.cuda()    # Tensor on GPU
 5         b_y = y.cuda()    # Tensor on GPU
 6         ...
 7         if step % 50 == 0:
 8             test_output = cnn(test_x)
 9             # !!!!!!!! 这里有修改  !!!!!!!!! #
10             pred_y = torch.max(test_output, 1)[1].cuda().data.squeeze()  # 将操作放去 GPU
11             accuracy = torch.sum(pred_y == test_y) / test_y.size(0)
12             ...
13 test_output = cnn(test_x[:10])
14 # !!!!!!!! 这里有修改 !!!!!!!!! #
15 pred_y = torch.max(test_output, 1)[1].cuda().data.squeeze()  # 将操作放去 GPU
16 ...
17 print(test_y[:10], real number)

转移至CPU

1 cpu_data = gpu_data.cpu()
网友评论