一、PyTorch介绍
1、说明
PyTorch 是 Torch 在 Python 上的衍生(Torch 是一个使用 Lua 语言的神经网络库)和tensorflow比较
PyTorch建立的神经网络是动态的 Tensorflow是建立静态图 Tensorflow 的高度工业化, 它的底层代码是很难看懂的.PyTorch 好那么一点点, 如果你深入 API, 你至少能比看 Tensorflow 多看懂一点点 PyTorch 的底层在干嘛.
2、安装PyTorch
官网:http://pytorch.org/ 进入官网之后可以选择对应的安装选项
目前只支持Linux和MacOS版本(2017-05-06) 执行下面对应的安装命令即可 安装 PyTorch 会安装两个模块
一个是 torch, 一个 torchvision, torch 是主模块 , 用来搭建神经网络的, torchvision 是辅模块 ,有数据库,还有一些已经训练好的神经网络等着你直接用, 比如 (VGG, AlexNet, ResNet).
上面在ubuntu14下自带的python2.7安装没有问题,在CentOS6.5下的python3.5中安装可能报错
1
2
3
./configure --enable-shared \
--prefix=/usr/local/python3.
5 \
LDFLAGS=
"-Wl,--rpath=/usr/local/lib"
然后运行python可能报loading shared libraries: libpython3.5m.so.1.0: cannot open shared object file: No such file or directory的错误,拷贝一份libpython3.5m.so.1.0到/usr/lib64目录下即可
1
cp /home/Python/Python-
3.5 .
3 /libpython3.
5 m
.so .
1.0 /usr/lib64
二、基础知识
1、和Numpy相似之处
(1) 数据转换
导入包:import torch 将numpy数据转为torch数据
1
2
np_data = np.arange(
6 ).reshape((
2 ,
3 ))
torch_data = torch.from_numpy(np_data)
1
tensor2array = torch_data.numpy()
(2) Torch中的运算
1
2
3
4
Variable containing:
1
2
3
4
[torch
.FloatTensor of size
2 x2]
(3) 计算梯度
v_out = torch.mean(variable*variable) # x^2v_out.backward() # 模拟 v_out 的误差反向传递print(variable.grad) # 显示 Variable 的梯度
输出结果如下 因为torch.mean(variable*variable)是1/4*x^2,导数就是1/2x
1
2
0.5000
1.0000
1.5000
2.0000
(4) Variable里面的数据
直接print(variable)只会输出 Variable 形式的数据, 在很多时候是用不了的(比如想要用 plt 画图), 所以我们要转换一下, 将它变成 tensor 形式. 获取 tensor 数据:print(variable.data) # tensor 形式
然后也可以转而numpy数据:print(variable.data.numpy()) # numpy 形式 3、Torch 中的激励函数 导入包:import torch.nn.functional as F # 激励函数都在这 平时要用到的就这几个. relu, sigmoid, tanh, softplus 激励函数
x是Variable数据,F.relu(x)也是返回Variable数据,然后.data获取 tensor 数据
1
2
3
4
# 做一些假数据来观看图像
x = torch.linspace(-5, 5, 200) # x data (tensor), shape=(100, 1)
x = Variable(x)
x_np = x.data.numpy() # 换成 numpy array, 出图时用
1
2
3
4
5
y_relu = F.relu(x).data.numpy()
y_sigmoid = F.sigmoid(x).data.numpy()
y_tanh = F.tanh(x).data.numpy()
y_softplus = F.softplus(x).data.numpy()
# y_softmax = F.softmax(x) softmax 比较特殊, 不能直接显示, 不过他是关于概率的, 用于分类
softplus的公式为:f(x)=ln(1+ex)
三、建立基础的神经网络
1、回归问题
(1) 准备工作
1
2
3
4
import torch
from torch
.autograd import Variable
import torch
.nn
.functional as F
import matplotlib
.pyplot as plt
制造假数据
torch.unsqueeze是转成2维的数据[[]],加上一个假的维度
1
2
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)
定义Variable: x, y = torch.autograd.Variable(x), Variable(y)
(2) 建立神经网络 使用类的方式class
继承torch.nn.Module 这里只包含一个隐层,__init__只是定义了几个层 forward进行传播,也就是整个网络的搭建,因为是预测,最后一层不需要激励函数
1
2
3
4
5
6
7
8
9
10
11
12
class Net(torch.nn.Module): # 继承 torch 的 Module
def __init__(self, n_feature, n_hidden, n_output):
super(Net, self).__init__() # 继承 __init__ 功能
# 定义每层用什么样的形式
self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隐藏层线性输出
self.predict = torch.nn.Linear(n_hidden, n_output) # 输出层线性输出
def forward(self, x): # 这同时也是 Module 中的 forward 功能
# 正向传播输入值, 神经网络分析出输出值
x = F.relu(self.hidden(x)) # 激励函数(隐藏层的线性值)
x = self.predict(x) # 输出值
return x
使用:net = Net(n_feature=1, n_hidden=10, n_output=1)
输出:print(net),结果为
1
2
3
4
Net (
(hidden): Linear (
1 ->
10 )
(predict): Linear (
10 ->
1 )
)
(3) 训练网络
定义优化器:optimizer = torch.optim.SGD(net.parameters(), lr=0.5) # 传入 net 的所有参数, 学习率lr 定义损失函数:loss_func = torch.nn.MSELoss() # 预测值和真实值的误差计算公式 (均方差) 训练
1
2
3
4
5
6
7
8
for t in range(100):
prediction = net(x) # 喂给 net 训练数据 x, 输出预测值
loss = loss_func(prediction, y) # 计算两者的误差
optimizer.zero_grad() # 清空上一步的残余更新参数值
loss.backward() # 误差反向传播, 计算参数更新值
optimizer.step() # 将参数更新值施加到 net 的 parameters 上
2、分类问题
(1) 准备工作
1
2
3
4
import torch
from torch.autograd import Variable
import torch.nn.functional as F # 激励函数都在这
import matplotlib.pyplot as plt
(2) 建立网络
1
2
3
4
5
6
7
8
for t in range(100):
out = net(x) # 喂给 net 训练数据 x, 输出分析值
loss = loss_func(out, y) # 计算两者的误差
optimizer.zero_grad() # 清空上一步的残余更新参数值
loss.backward() # 误差反向传播, 计算参数更新值
optimizer.step() # 将参数更新值施加到 net 的 parameters 上
预测:
输出至最大的那个(概率最大的)坐标
1
2
# 过了一道 softmax 的激励函数后的最大概率才是预测值
prediction = torch.max(F.softmax(out), 1)[1]
3、快速搭建神经网络
1
2
3
4
5
net2 = torch
.nn
.Sequential (
torch
.nn
.Linear (
1 ,
10 ),
torch
.nn
.ReLU (),
torch
.nn
.Linear (
10 ,
1 )
)
输出:print(net2)
相比我们之前自己定义的类,激励函数 也显示出来了
1
2
3
4
5
Sequential (
(
0 ): Linear (
1 ->
10 )
(
1 ): ReLU ()
(
2 ): Linear (
10 ->
1 )
)
4、保存和提取
(1) 保存(两种方法)
1
2
b_x = Variable(batch_x) # 务必要用 Variable 包一下
b_y = Variable(batch_y)
6、优化器 optimizer
SGD
momentum
动量加速 在SGD函数里指定momentum的值即可 RMSprop
Adam
参数betas=(0.9, 0.99)
1
2
3
4
opt_SGD = torch
.optim
.SGD (net_SGD.parameters(), lr=LR)
opt_Momentum = torch
.optim
.SGD (net_Momentum.parameters(), lr=LR, momentum=
0.8 )
opt_RMSprop = torch
.optim
.RMSprop (net_RMSprop.parameters(), lr=LR, alpha=
0.9 )
opt_Adam = torch
.optim
.Adam (net_Adam.parameters(), lr=LR, betas=(
0.9 ,
0.99 ))
四、高级神经网络
1、卷积神经网络 CNN
1
2
3
4
5
import torch
from torch
.autograd import Variable
import torch
.utils
.data as Data
import torchvision
from matplotlib import pyplot as plt
1
2
3
4
5
6
7
8
9
EPOCH = 10
BATCH_SIZE = 50
LR = 0.001
train_data = torchvision.datasets.MNIST(root='./mnist',
transform=torchvision.transforms.ToTensor(),
download=False) # first set True, then set False
print(train_data.train_data.size())
test_data = torchvision.datasets.MNIST(root='./mnist', train=False)
处理数据
使用 DataLoader 进行batch训练 将测试数据放到Variable里,并加上一个维度(在第二维位置dim=1),因为下面训练时是(batch_size, 1, 28, 28)
1
2
3
4
5
train_loader = Data.DataLoader(dataset=train_data, batch_size=128, shuffle=True)
# shape from (total_size, 28, 28) to (total_size, 1, 28, 28)
test_x = Variable(torch.unsqueeze(test_data.test_data, dim=1), volatile=True).type(torch.FloatTensor)/255.0
test_y = test_data.test_labels
建立计算图模型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class CNN(torch.nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.conv1 = torch.nn.Sequential( # input shape (1, 28, 28)
torch.nn.Conv2d(in_channels=1,
out_channels=16,
kernel_size=5,
stride=1,
padding=2),
torch.nn.ReLU(),
torch.nn.MaxPool2d(kernel_size=2)
) # output shape (16, 14, 14)
self.conv2 = torch.nn.Sequential(
torch.nn.Conv2d(16, 32, 5, 1, 2),
torch.nn.ReLU(),
torch.nn.MaxPool2d(2)
) # output shape (32, 7, 7)
self.out = torch.nn.Linear(in_features=32*7*7, out_features=10)
def forward(self, x):
x = self.conv1(x)
x = self.conv2(x)
x = x.view(x.size(0), -1) # 展平多维的卷积图成 (batch_size, 32 * 7 * 7)
output = self.out(x)
return output
cnn = CNN()
1
2
optimizer = torch
.optim
.Adam (cnn.parameters(), lr=LR)
loss_func = torch
.nn
.CrossEntropyLoss ()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for epoch in range(EPOCH):
for i, (x, y) in enumerate(train_loader):
batch_x = Variable(x)
batch_y = Variable(y)
output = cnn(batch_x)
loss = loss_func(output, batch_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if i % 50 == 0:
# 用 test 数据来验证准确率
test_output = cnn(test_x)
pred_y = torch.max(test_output, 1)[1].data.squeeze()
accuracy = sum(pred_y == test_y) / float(test_y.size(0))
print('Epoch: ', epoch, '| train loss: %.4f' % loss.data[0], '| test accuracy: %.2f' % accuracy)
Reference
原文地址: http://lawlite.me/2017/05/10/PyTorch/