一、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^2
v_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/