PyTorch简易入门
Posted 计算材料学与大数据
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PyTorch简易入门相关的知识,希望对你有一定的参考价值。
PyTorch是一个基于python的深度学习库,极具灵活性和高效性,支持GPU加速。使用PyTorch建立深度学习模型具有以下一些优势:
易于使用的API:就像使用python一样简单,相比于Tensorflow而言,PyTorch的数据加载模块更易于使用。。
动态计算图:可以随时构建、修改运行计算图,不必等待整个代码被完成后才知道它是否有效;易于构建复杂的计算图。
高效、灵活:在一项LSTM的基准测试中,PyTorch的平均训练时间最短;PyTorch在构建神经网络方面非常方便,不需要使用像Keras这样的第三方高级库。
我们开始使用PyTorch前,我们应该首先了解如下几个主要知识点:
PyTorch张量
数学运算操作
自动微分模块
优化模块和神经网络模块
一、PyTorch张量
张量不过是多维数组。 PyTorch中的张量与numpy的ndarrays相似,另外还可以在GPU上使用张量。 PyTorch支持各种类型的张量。
你可以使用如下命令定义一个简单的一维矩阵:
#导入torch
import torch
# 定义一个张量
torch.FloatTensor([2])
#输出
2
[torch.FloatTensor of size 1]
二、数学运算操作
与numpy一样, PyTorch能为您提供超过200多种数学运算操作,以下是PyTorch中一个简单的加法运算的例子。
#定义张量a,b
a = torch.FloatTensor([2])
b = torch.FloatTensor([3])
#加法运算操作
a + b
#输出
5
[torch.FloatTensor of size 1]
我们也可以对我们定义的PyTorch张量执行各种矩阵运算。 例如,一个二维矩阵的转置:
#定义PyTorch中的矩阵matrix
matrix = torch.randn(3, 3)
#输出矩阵
matrix
0.7162 1.0152 1.1525
-0.3503 -0.9452 -1.0861
-0.1093 -0.0927 -0.0476
[torch.FloatTensor of size 3x3]
#转置
matrix.t()
#输出转置矩阵
0.7162 -0.3503 -0.1093
1.0152 -0.9452 -0.0927
1.1525 -1.0861 -0.0476
[torch.FloatTensor of size 3x3]
三、自动微分模块(Autograd 模块)
该模块在建立神经网络时特别有用,用于神经网络前向传播过程中损失函数参数的微分计算。
#从autograd模块中导入Variable
from torch.autograd import Variable
#定义Variable
x = Variable(train_x)
y = Variable(train_y, requires_grad=False)
四、优化模块(torch.optim模块)和神经网络模块(torch.nn模块)
torch.optim模块实现了训练神经网络的优化算法。大多数常用的优化方法已经被实现,我们不必从头开始构建这些优化算法。
以下是使用Adam优化器的代码:
optimizer = torch.optim.Adam(model.parameters(),lr = learning_rate)
神经网络模块(torch.nn模块)
该模块能助你更快地构建神经网络,您可以将一个nn模块视为PyTorch的keras!该模块的使用方式如下:
#导入torch
import torch
#定义模型
model = torch.nn.Sequential(
torch.nn.Linear(input_num_units, hidden_num_units),
torch.nn.ReLU(),
torch.nn.Linear(hidden_num_units, output_num_units),
)
loss_fn = torch.nn.CrossEntropyLoss()
现在您已经了解了PyTorch的基本组件,您可以轻松构建自己的神经网络。下面让我们构建一个二分类的神经网络。使用PyTorch与Numpy非常相似,可以通过下面的例子来做个比较。
用Numpy建立神经网络
import numpy as np
#输入array,array的每一行表示一个样例,每一行的元素个数表示特征个数
X=np.array([[1,0,1,0],[1,0,1,1],[0,1,0,1]])
#输出结果,0,1分别表示两个类别,X中三个样例对应的标签分别是1,1,0
y=np.array([[1],[1],[0]])
#Sigmoid 函数
def sigmoid (x):
return 1/(1 + np.exp(-x))
#Sigmoid函数求微分
def derivatives_sigmoid(x):
return x * (1 - x)
#训练网络的迭代次数
epoch=5000
#学习速率
lr=0.1
#神经网络一般都有输入层、隐藏层和输出层。
#输入层神经元数目=每个样例的特征数
inputlayer_neurons = X.shape[1]
#隐藏层的神经元数目
hiddenlayer_neurons = 3
#输出层的神经元数目
output_neurons = 1
#权重和偏置的初始化
wh=np.random.uniform(size=(inputlayer_neurons,hiddenlayer_neurons))
bh=np.random.uniform(size=(1,hiddenlayer_neurons))
wout=np.random.uniform(size=(hiddenlayer_neurons,output_neurons))
bout=np.random.uniform(size=(1,output_neurons))
for i in range(epoch):
#前向传播计算损失函数
hidden_layer_input1=np.dot(X,wh)
hidden_layer_input=hidden_layer_input1 + bh
hiddenlayer_activations = sigmoid(hidden_layer_input)
output_layer_input1=np.dot(hiddenlayer_activations,wout)
output_layer_input= output_layer_input1+ bout
output = sigmoid(output_layer_input)
#反向传播更新权重wout,bout,wh,bh
E = y-output
slope_output_layer = derivatives_sigmoid(output)
slope_hidden_layer = derivatives_sigmoid(hiddenlayer_activations)
d_output = E * slope_output_layer
Error_at_hidden_layer = d_output.dot(wout.T)
d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layer
wout += hiddenlayer_activations.T.dot(d_output) *lr
bout += np.sum(d_output, axis=0,keepdims=True) *lr
wh += X.T.dot(d_hiddenlayer) *lr
bh += np.sum(d_hiddenlayer, axis=0,keepdims=True) *lr
#输出预测结果和实际结果
print('actual :\n', y, '\n')
print('predicted :\n', output)
现在,尝试在PyTorch中实现该神经网络,并给出与Numpy实现的差异(在下面的代码中以粗体表示差异)。
在PyTorch中实现神经网络
#导入torch库
import torch
#输入array,array的每一行表示一个样例,每一行的元素个数表示特征个数
X = torch.Tensor([[1,0,1,0],[1,0,1,1],[0,1,0,1]])
#输出结果,0,1分别表示两个类别,X中三个样例对应的标签分别是1,1,0
y = torch.Tensor([[1],[1],[0]])
#Sigmoid函数
def sigmoid (x):
return 1/(1 + torch.exp(-x))
#Sigmoid函数求微分
def derivatives_sigmoid(x):
return x * (1 - x)
#训练迭代次数
epoch=5000
#学习速率
lr=0.1
#输入层的神经元数目=每个样例的特征数
inputlayer_neurons = X.shape[1]
#隐藏层的神经元数目
hiddenlayer_neurons = 3
#输出层的神经元数目
output_neurons = 1
#权重和偏置初始化
wh=torch.randn(inputlayer_neurons, hiddenlayer_neurons).type(torch.FloatTensor)
bh=torch.randn(1,hiddenlayer_neurons).type(torch.FloatTensor)
wout=torch.randn(hiddenlayer_neurons, output_neurons)
bout=torch.randn(1, output_neurons)
for i in range(epoch):
#前向传播计算损失函数
hidden_layer_input1 = torch.mm(X, wh)
hidden_layer_input = hidden_layer_input1 + bh
hidden_layer_activations = sigmoid(hidden_layer_input)
output_layer_input1 = torch.mm(hidden_layer_activations, wout)
output_layer_input = output_layer_input1 + bout
output = sigmoid(output_layer_input1)
#反向传播更新权重
E = y-output
slope_output_layer = derivatives_sigmoid(output)
slope_hidden_layer = derivatives_sigmoid(hidden_layer_activations)
d_output = E * slope_output_layer
Error_at_hidden_layer = torch.mm(d_output, wout.t())
d_hiddenlayer = Error_at_hidden_layer * slope_hidden_layer
wout += torch.mm(hidden_layer_activations.t(), d_output) *lr
bout += d_output.sum() *lr
wh += torch.mm(X.t(), d_hiddenlayer) *lr
bh += d_output.sum() *lr
#输出预测结果与实际结果
print('actual :\n', y, '\n')
print('predicted :\n', output)
下面是PyTorch官网上的一段话:
PyTorch has a unique way of building neural networks: using and replaying a tape recorder.
Most frameworks such as TensorFlow, Theano, Caffe and CNTK have a static view of the world. One has to build a neural network, and reuse the same structure again and again. Changing the way the network behaves means that one has to start from scratch.
With PyTorch, we use a technique called Reverse-mode auto-differentiation, which allows you to change the way your network behaves arbitrarily with zero lag or overhead. Our inspiration comes from several research papers on this topic, as well as current and past work such as autograd, autograd, Chainer, etc.
While this technique is not unique to PyTorch, it’s one of the fastest implementations of it to date. You get the best of speed and flexibility for your crazy research.
以上是关于PyTorch简易入门的主要内容,如果未能解决你的问题,请参考以下文章