优点:可以使用GPU加速
1)Tensor和numpy之间的转化
import torch
import numpy as np
np_data = np.arange(8).reshape((2,4)) #定义一个numpy的二维数组
torch_data = torch.from_numpy(np_data)
print(np_data)
print(torch_data)
np_data2 = torch_data.numpy() #转回numpy
print(np_data2)
2)矩阵运算
import torch
import numpy as np
np_data = np.array([[1,2],[3,5]])
torch_data = torch.from_numpy(np_data)
print(np_data)
print(np_data.dot(np_data))
print(torch_data.mm(torch_data))
Tensor是PyTorch中的基础组件,但是构建神经网络还远远不够,我们需要能够构建计算图的Tensor,也就是Variable(简单理解就是Variable是对Tensor的一种封装)。
其操作与Tensor是一样的,但是每个Variable都包含了三个属性
.data
Variable中的Tensor本身.grad
对应Tensor的梯度.grad_fn
创建这个Variable的Function的引用(该引用可用于回溯整个创建链路,如果是用户自己创建Variable,则其grad_fn为None)from torch.autograd import Variable
import torch
x_tensor = torch.randn(10, 5) #从标准正态分布中返回多个样本值
# 将Tensor变成Variable
x = Variable(x_tensor, requires_grad=True)
# 默认Variable是不需要求梯度的,所以用这个方式申明需要对其进行求梯度的操作
print(x.data)
print(x.grad)
print(x.grad_fn)
import torch
from torch.autograd import Variable
import matplotlib.pyplot as plt
tensor = torch.linspace(-6,6,200)
tensor = Variable(tensor)
np_data = tensor.numpy()
#定义激活函数
y_relu = torch.relu(tensor).data.numpy()
y_sigmoid =torch.sigmoid(tensor).data.numpy()
y_tanh = torch.tanh(tensor).data.numpy()
plt.figure(1, figsize=(8, 6))
plt.subplot(221)
plt.plot(np_data, y_relu, c='red', label='relu')
plt.legend(loc='best')
plt.subplot(222)
plt.plot(np_data, y_sigmoid, c='red', label='sigmoid')
plt.legend(loc='best')
plt.subplot(223)
plt.plot(np_data, y_tanh, c='red', label='tanh')
plt.legend(loc='best')
plt.show()
PyTorch中均方差损失函数被封装成MSELoss函数,其调用方法如下:
torch.nn.MSELoss(size_average=None, reduce=None,reduction='mean')
调用方法中的参数及说明具体如下:
size_average(bool,optional)
:基本弃用(参见reduction)。默认情况下,损失是批次(batch)中每个损失元素的平均值。请注意,对于某些损失,每个样本均有多个元素。如果将字段size_average
设置为False,则需要将每个batch的损失相加。当reduce
设置为False时忽略。默认值为True。
reduce(bool,optional)
:基本弃用(参见reduction)。默认情况下,根据size_average,对每个batch中结果的损失进行平均或求和。当reduce为False时,返回batch中每个元素的损失并忽略size_average。默认值为True。
reduction(string,optional)
:输出元素包含3种操作方式,即none、mean和sum。‘none’:不做处理。‘mean’:输出的总和除以输出中元素的数量。‘sum’:输出的和。注意:size_average和reduce基本已被弃用,而且指定这两个args中的任何一个都将覆盖reduce。默认值为mean。在PyTorch 0.4之后,参数size_average和reduce已被舍弃。
PyTorch中的交叉熵损失函数将nn.LogSoftmax()和nn.NLLLoss()合并在一个类中,函数名为CrossEntropyLoss()。CrossEntropyLoss是多分类任务中常用的损失函数,在PyTorch中其调用方法如下:
torch.nn.CrossEntropyLoss(weight=None, size_average=None,ignore_index=-100, reduce=None, reduction='mean')
调用方法中的参数及其说明具体如下。
weight(Tensor,optional)
:多分类任务中,手动给出每个类别权重的缩放量。如果给出,则其是一个大小等于类别个数的张量。
size_average(bool,optional)
:已基本弃用(参见reduction)。默认情况下,损失是batch中每个损失元素的平均值。请注意,对于某些损失,每个样本都包含了多个元素。如果将字段size_average设置为False,则将每个小批量的损失相加。当reduce为False时则忽略。默认值为True。
ignore_index(int,optional)
:指定被忽略且不对输入梯度做贡献的目标值。当size_average为True时,损失则是未被忽略目标的平均。
reduce(bool,optional)
:已基本弃用(参见reduction)。默认情况下,根据size_average,对每个batch中结果的损失进行平均或求和。当reduce为False时,返回batch中每个元素的损失并忽略size_average。默认值为True。
reduction(string,optional)
:输出元素有3种操作方式,即none、mean和sum。
‘none’:不做处理。
‘mean’:输出的总和除以输出中的元素数量。
‘sum’:输出的和。
注意:size_average和reduce正在被弃用,而且指定这两个args中的任何一个都将覆盖reduce。默认值为mean。
PyTorch实战之MNIST分类第一个案例我们使用MNIST数据集来进行手写数字的识别。
1)数据准备
import torch
from torch.utils.data import DataLoader
import torchvision.datasets as dsets
import torchvision.transforms as transforms
batch_size = 100
# MNIST dataset
train_dataset = dsets.MNIST(root = '/pymnist', #选择数据的根目录
train = True, # 选择训练集
transform = transforms.ToTensor(), #转换成tensor变量
download = True) # 从网络上download图片
test_dataset = dsets.MNIST(root = '/pymnist', #选择数据的根目录
train = False, # 选择测试集
transform = transforms.ToTensor(), #转换成tensor变量
download = True) # 从网络上download图片
#加载数据
train_loader = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size = batch_size, #使用批次数据
shuffle = True) # 将数据打乱
test_loader = torch.utils.data.DataLoader(dataset = test_dataset,
batch_size = batch_size,
shuffle = True)
2)创建神经网络模型
import torch.nn as nn
import torch
input_size = 784 #mnist的像素为28*28
hidden_size = 500
num_classes = 10 #输出为10个类别分别对应0-9
# 创建神经网络模型
class Neural_net(nn.Module):
#初始化函数,接受自定义输入特征的维数,隐含层特征维数以及输出层特征维数。
def __init__(self, input_num,hidden_size, out_put):
super(Neural_net, self).__init__()
self.layer1 = nn.Linear(input_num, hidden_size)#从输入到隐藏层的线性处理
self.layer2 = nn.Linear(hidden_size, out_put)#从隐层到输出层的线性处理
def forward(self, x):
out = self.layer1(x) #输入层到隐藏层的线性计算
out = torch.relu(out) #隐藏层激活
out = self.layer2(out) #输出层,注意,输出层直接接loss
return out
net = Neural_net(input_size, hidden_size, num_classes)
print(net)
3)训练
# optimization
from torch.autograd import Variable
import numpy as np
learning_rate = 1e-1 #学习率
num_epoches = 5
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr = learning_rate)#使用随机梯度下降
for epoch in range(num_epoches):
print('current epoch = %d' % epoch)
for i, (images, labels) in enumerate(train_loader): #利用enumerate取出一个可迭代对象的内容
images = Variable(images.view(-1, 28 * 28))
labels = Variable(labels)
outputs = net(images) #将数据集传入网络做前向计算
loss = criterion(outputs, labels) #计算loss
optimizer.zero_grad() #在做反向传播之前先清除下网络状态
loss.backward() #loss反向传播
optimizer.step() #更新参数
if i % 100 == 0:
print('current loss = %.5f' % loss.item())
print('finished training')
4)评估
#做prediction
total = 0
correct = 0
for images, labels in test_loader:
images = Variable(images.view(-1, 28 * 28))
outputs = net(images)
print(outputs)
_, predicts = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicts == labels).sum()
print('Accuracy = %.2f' % (100 * correct / total))
全部代码
import torch
from torch.utils.data import DataLoader
import torchvision.datasets as dsets
import torchvision.transforms as transforms
batch_size = 100
# MNIST dataset
train_dataset = dsets.MNIST(root = '/pymnist', #选择数据的根目录
train = True, # 选择训练集
transform = transforms.ToTensor(), #转换成tensor变量
download = True) # 从网络上download图片
test_dataset = dsets.MNIST(root = '/pymnist', #选择数据的根目录
train = False, # 选择测试集
transform = transforms.ToTensor(), #转换成tensor变量
download = True) # 从网络上download图片
#加载数据
train_loader = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size = batch_size, #使用批次数据
shuffle = True) # 将数据打乱
test_loader = torch.utils.data.DataLoader(dataset = test_dataset,
batch_size = batch_size,
shuffle = True)
import torch.nn as nn
import torch
input_size = 784 #mnist的像素为28*28
hidden_size = 500
num_classes = 10 #输出为10个类别分别对应0-9
# 创建神经网络模型
class Neural_net(nn.Module):
#初始化函数,接受自定义输入特征的维数,隐含层特征维数以及输出层特征维数。
def __init__(self, input_num,hidden_size, out_put):
super(Neural_net, self).__init__()
self.layer1 = nn.Linear(input_num, hidden_size)#从输入到隐藏层的线性处理
self.layer2 = nn.Linear(hidden_size, out_put)#从隐层到输出层的线性处理
def forward(self, x):
out = self.layer1(x) #输入层到隐藏层的线性计算
out = torch.relu(out) #隐藏层激活
out = self.layer2(out) #输出层,注意,输出层直接接loss
return out
net = Neural_net(input_size, hidden_size, num_classes)
print(net)
# optimization
from torch.autograd import Variable
import numpy as np
learning_rate = 1e-1 #学习率
num_epoches = 5
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr = learning_rate)#使用随机梯度下降
for epoch in range(num_epoches):
print('current epoch = %d' % epoch)
for i, (images, labels) in enumerate(train_loader): #利用enumerate取出一个可迭代对象的内容
images = Variable(images.view(-1, 28 * 28))
labels = Variable(labels)
outputs = net(images) #将数据集传入网络做前向计算
loss = criterion(outputs, labels) #计算loss
optimizer.zero_grad() #在做反向传播之前先清除下网络状态
loss.backward() #loss反向传播
optimizer.step() #更新参数
if i % 100 == 0:
print('current loss = %.5f' % loss.item())
print('finished training')
#做prediction
total = 0
correct = 0
for images, labels in test_loader:
images = Variable(images.view(-1, 28 * 28))
outputs = net(images)
print(outputs)
_, predicts = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicts == labels).sum()
print('Accuracy = %.2f' % (100 * correct / total))
1)数据准备
import torch
from torch.utils.data import DataLoader
import torchvision.datasets as dsets
import torchvision.transforms as transforms
batch_size = 100
# MNIST dataset
train_dataset = dsets.CIFAR10(root = '/ml/pycifar', #选择数据的根目录
train = True, # 选择训练集
transform = transforms.ToTensor(), #转换成tensor变量
download = True) # 从网络上download图片
test_dataset = dsets.CIFAR10(root = '/ml/pycifar', #选择数据的根目录
train = False, # 选择测试集
transform = transforms.ToTensor(), #转换成tensor变量
download = True) # 从网络上download图片
#加载数据
train_loader = torch.utils.data.DataLoader(dataset = train_dataset,
batch_size = batch_size,
shuffle = True) # 将数据打乱
test_loader = torch.utils.data.DataLoader(dataset = test_dataset,
batch_size = batch_size,
shuffle = True)
2)创建神经网络模型
from torch.autograd import Variable
import torch.nn as nn
import torch
# input_size = 3072
# hidden_size = 500
input_size = 784
hidden_size = 100
hidden_size2 = 200
num_classes = 10
num_epochs = 5
batch_size = 100
learning_rate = 0.001
#定义两层神经网络
class Net(nn.Module):
def __init__(self,input_size,hidden_size,hidden_size2,num_classes):
super(Net,self).__init__()
self.layer1 = nn.Linear(input_size,hidden_size)
self.layer2 = nn.Linear(hidden_size,hidden_size2)
self.layer3 = nn.Linear(hidden_size2,num_classes)
def forward(self,x):
out = torch.relu(self.layer1(x))
out = torch.relu(self.layer2(out))
out = self.layer3(out)
return out
net = Net(input_size,hidden_size,hidden_size2,num_classes)
print(net)
3)训练
# optimization
from torch.autograd import Variable
import numpy as np
learning_rate = 1e-1 #学习率
num_epoches = 5
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(net.parameters(), lr =
learning_rate)#使用随机梯度下降
for epoch in range(num_epoches):
print('current epoch = %d' % epoch)
for i, (images, labels) in enumerate(train_loader): #利 用enumerate取出一个可迭代对象的内容
images = Variable(images.view(-1, 28 * 28))
labels = Variable(labels)
outputs = net(images) #将数据集传入网络做前向计算
loss = criterion(outputs, labels) #计算Loss
optimizer.zero_grad() #在做反向传播之前先清除下网络状态
loss.backward() #Loss反向传播
optimizer.step() #更新参数
if i % 100 == 0:
print('current loss = %.5f' % loss.item())
print('finished training')
4)评估
#做prediction total = 0
correct = 0
for images, labels in test_loader:
images = Variable(images.view(images.size(0), -1))
outputs = net(images)
_, predicts = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicts == labels).sum()
print('Accuracy = %.2f' % (100 * correct / total))
最后我跑出来的结果是MINIST数据集的准确度为97.41%
而另一个复杂一些的彩色Cifar10数据集效果却不好,准确度只有48.35%。所以,浅层的神经网络keyi解决一部分简单的问题。深层的还是得看卷积神经网络。