一、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中安装可能报错- 安装
python3.5时的配置:
- 安装
|
|
- 然后运行
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、和Numpy相似之处
(1) 数据转换
- 导入包:
import torch - 将
numpy数据转为torch数据
|
|
- 将
torch数据转为numpy数据
|
|
(2) Torch中的运算
- API:http://pytorch.org/docs/torch.html#math-operations
torch中tensor的运算和numpy array运算很相似,比如np.abs() --> torch.abs()np.sin() --> torch.sin()等
- 矩阵相乘:
Variable就是一个存放会变化的值的位置- 这里变化的值就是tensor数据
(2) 使用
导入包
12import torchfrom torch.autograd import Variable # torch 中 Variable 模块定义
tensor:tensor = torch.FloatTensor([[1,2],[3,4]])- 将
tensor放入Variable:variable = Variable(tensor, requires_grad=True)requires_grad是参不参与误差反向传播, 要不要计算梯度print(variable)会输出,(多出Variable containing:,表明是Variable)
|
|
(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/2x120.5000 1.00001.5000 2.0000
(4) Variable里面的数据
- 直接
print(variable)只会输出Variable形式的数据, 在很多时候是用不了的(比如想要用plt画图), 所以我们要转换一下, 将它变成tensor形式. - 获取
tensor数据:print(variable.data) # tensor 形式 - 导入包:
import torch.nn.functional as F # 激励函数都在这 - 平时要用到的就这几个.
relu, sigmoid, tanh, softplus - 激励函数
x是Variable数据,F.relu(x)也是返回Variable数据,然后.data获取tensor数据1234# 做一些假数据来观看图像x = torch.linspace(-5, 5, 200) # x data (tensor), shape=(100, 1)x = Variable(x)x_np = x.data.numpy() # 换成 numpy array, 出图时用
|
|
softplus的公式为:f(x)=ln(1+ex)
三、建立基础的神经网络
1、回归问题
(1) 准备工作
- 导入包
|
|
制造假数据
torch.unsqueeze是转成2维的数据[[]],加上一个假的维度12x = 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进行传播,也就是整个网络的搭建,因为是预测,最后一层不需要激励函数123456789101112class Net(torch.nn.Module): # 继承 torch 的 Moduledef __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),结果为
|
|
(3) 训练网络
- 定义优化器:
optimizer = torch.optim.SGD(net.parameters(), lr=0.5) # 传入 net 的所有参数, 学习率lr - 定义损失函数:
loss_func = torch.nn.MSELoss() # 预测值和真实值的误差计算公式 (均方差) - 训练
|
|
2、分类问题
(1) 准备工作
- 导入包
|
|
制造假数据
x0是一个类别的x1,x2y0就是对应这个类别的label,这里是0- 然后将
x0,x1,y0,y1合并在一起123456789# 假数据n_data = torch.ones(100, 2) # 数据的基本形态x0 = torch.normal(2*n_data, 1) # 类型0 x data (tensor), shape=(100, 2)y0 = torch.zeros(100) # 类型0 y data (tensor), shape=(100, 1)x1 = torch.normal(-2*n_data, 1) # 类型1 x data (tensor), shape=(100, 1)y1 = torch.ones(100) # 类型1 y data (tensor), shape=(100, 1)# 注意 x, y 数据的数据形式是一定要像下面一样 (torch.cat 是在合并数据)x = torch.cat((x0, x1), 0).type(torch.FloatTensor) # FloatTensor = 32-bit floatingy = torch.cat((y0, y1), ).type(torch.LongTensor) # LongTensor = 64-bit integer
定义Variable:
x, y = Variable(x), Variable(y)
(2) 建立网络
与上面回归的例子类似
- 使用
relu激励函数 - 这里最后一层并没有使用激励函数或是
softmax,因为下面使用了CrossEntropyLoss,这个里面默认会调用log_softmax函数(nll_loss(log_softmax(input), target, weight, size_average)) - 当然这里也可以最后返回
F.softmax(x), 那么下面的损失函数就是loss = F.nll_loss(out, y)1234567891011class Net(torch.nn.Module): # 继承 torch 的 Moduledef __init__(self, n_feature, n_hidden, n_output):super(Net, self).__init__() # 继承 __init__ 功能self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隐藏层线性输出self.out = torch.nn.Linear(n_hidden, n_output) # 输出层线性输出def forward(self, x):# 正向传播输入值, 神经网络分析出输出值x = F.relu(self.hidden(x)) # 激励函数(隐藏层的线性值)x = self.out(x) # 输出值, 但是这个不是预测值, 预测值还需要再另外计算return x
- 使用
建立网络:
net = Net(n_feature=2, n_hidden=10, n_output=2) # 几个类别就几个 output(3) 训练网络
- 优化器:
optimizer = torch.optim.SGD(net.parameters(), lr=0.02) # 传入 net 的所有参数, 学习率 - 损失函数:
loss_func = torch.nn.CrossEntropyLoss() - 训练:
|
|
- 预测:
- 输出至最大的那个(概率最大的)坐标12# 过了一道 softmax 的激励函数后的最大概率才是预测值prediction = torch.max(F.softmax(out), 1)[1]
- 输出至最大的那个(概率最大的)坐标
3、快速搭建神经网络
- 使用
torch.nn.Sequential
|
|
- 输出:
print(net2)- 相比我们之前自己定义的类,激励函数也显示出来了12345Sequential ((0): Linear (1 -> 10)(1): ReLU ()(2): Linear (10 -> 1))
- 相比我们之前自己定义的类,激励函数也显示出来了
4、保存和提取
(1) 保存(两种方法)
- 保存整个网络
torch.save(net1, 'net.pkl')# 保存整个网络,net1就是定义的网络
- 只保存网络中的参数
- 提取整个网络:
net2 = torch.load('net.pkl')prediction = net2(x)
- 只提取网络参数
- 上面我们虽然是
torch.optim.SGD进行优化,但是还是将所有数据放进去训练(1) DataLoader
- 是
torch用来包装你的数据(tensor)的工具 - 导入包:
import torch.utils.data as Data 将tensor数据转为
torch能识别的Dataset1torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y)把 dataset 放入 DataLoader
BATCH_SIZE是我们定义的batch大小123456loader = Data.DataLoader(dataset=torch_dataset, # torch TensorDataset formatbatch_size=BATCH_SIZE, # mini batch sizeshuffle=True, # 要不要打乱数据 (打乱比较好)num_workers=2, # 多线程来读数据)
就可以得到
batch数据了12345678for epoch in range(3): # 训练所有!整套!数据 3 次for step, (batch_x, batch_y) in enumerate(loader): # 每一步 loader 释放一小批数据用来学习# 假设这里就是你训练的地方...# 打出来一些数据print('Epoch: ', epoch, '| Step: ', step, '| batch x: ',batch_x.numpy(), '| batch y: ', batch_y.numpy())这里还是
tensor数据,真正训练时还要放到Variable中
|
|
6、优化器 optimizer
SGD- 就是随机梯度下降
momentum- 动量加速
- 在
SGD函数里指定momentum的值即可
RMSprop- 指定参数
alpha
- 指定参数
Adam- 参数
betas=(0.9, 0.99)1234opt_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
- 使用mnist数据集
- 导入包
|
|
- 下载数据集
|
|
处理数据
- 使用
DataLoader进行batch训练 - 将测试数据放到
Variable里,并加上一个维度(在第二维位置dim=1),因为下面训练时是(batch_size, 1, 28, 28)12345train_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.0test_y = test_data.test_labels
- 使用
建立计算图模型
|
|
- 定义优化器
optimizer和损失
|
|
- 进行batch训练
|
|
Reference
- 本文链接: http://lawlite.me/2017/05/10/PyTorch/
-
版权声明:
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议
。转载请注明出处!