Tensor
在PyTorch中,最核心的数据结构就是Tensor了,可以认为Tensor与Numpy中的ndarrays 非常类似,但是Tensor可以使用GPU加速而ndarrays不可以。
在pytorch进行GPU运算
if torch.cuda.is_available(): x=x.cuda() y= y.cuda() print(x+y)
numpy与pytorch互相转换
import torch import numpy as np np_data =np.arange(8).reshape((2,4)) #定义一个 numpy 的二维数组 torch data =torch.from_numpy(np_data)#转为pytorch中的tensor结构 print(np data) print(torch data) np_data2 = torch_data.numpy() print(np_data2) #转回 numpy
tensor做矩阵相乘
在Numpy中矩阵相乘使用的是dot这个方法,而在PyTorch中使用的是mm这个方法来表示
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))
Variable
Variable 是对 Tensor 的一种封装。其作与 Tensor 是一样的,但是每个 Variable都包含了三个属性data、grad 以及creator.Variable 中的Tensor 本身(通过.data来进行访问)、对应Tensor的梯度(通过.grad 进行访问)以及创建这个 Variable的Function的引用(通过.grad_fn进行访问),该引用可用于回溯整个创建链路,如果是用户自己创建Variable,则其 grad_fn为None
如果我们需要使用 Variable,则可在代码中输入如下语句:
from torch.autograd import Variable #导入Variable
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.nn,functional as F来加载激活函数,随着PyTorch版本的更新,通过torch 可以直接载激活函数。
import torch from torch.autograd import Variable import matplotlib.pyplot as plt tensor = torch.linspace(-6,6,200) #torch.linspace(start, end, steps)
是 PyTorch 中的一个函数,用于生成在start
和end
之间均匀分布的steps
个点。在这个例子中,它生成从-6
到6
的 200 个均匀分布的点。结果是一个一维张量,包含 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)) #创建一个图形(figure)对象,1
是图形的标识符,figsize=(8, 6)
用于设置图形的宽度(8英寸)和高度(6英寸)。
plt.subplot(221) #创建一个 2x2 的子图(subplot),并选择第 1 个子图(位置从左到右,从上到下编号 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中的交叉熵损失函数将nn.LogSoftmax()和nn.NLLLoss()合并在一个类中,函数名为CrossEntropyLoss()。CrossEntropyLoss是多分类任务中常用的损失函数,其调用方法如下:
torch.nn.CrossEntropyLoss(welght=None,size_average=None, ignore_index=-100,reduce=None, reduction='mean')
weight(Tensor,optional):多分类任务中,手动给出每个类别权重的缩放量。如果给出,则其是一个大小等于类别个数的张量。
size_average(bool,optional):默认情况下,损失是batch中每个损失元素的平均值。请注意,对于某些损失,每个样本都包含了多个元素。如果将字段 size_average设置为False,则将每个小批量的损失相加。reduce 为 False 时则忽略。默认值为 True。
ignore_index(int,optional):指定被忽略且不对输入梯度做贡献的目标值。当size_average 为True 时,损失则是未被忽略目标的平均。
reduce(bool,optional):默认情况下,根据size_average,对每个batch中结果的损失进行平均或求和。当reduce为False时,返回batch中每个元素的损失并忽略size_average。默认值为 True。
reduction(string,optional):输出元素有3种操作方式,即none、mean和sum
>>> loss = nn.CrossEntropyLoss() >>> input =torch.randn(3,5,requires_grad=True) >>> target =torch.empty(3,dtype=torch.long).random_(5) >> output =loss(input,target)
PyTorch 是不支持 one-hot 编码类型的,输人的都是真实的targt, 所如果输入的真实分类是one-hot编码的话则需要自行转换,即将target one-hot的编码格式换为每个样本的类别,再传给CrossEntropyLoss
import torch from torch import nn import numpy as np # 编码one_hot def one_hot(y): ''' y: (N)的一维tensor,值为每个样本的类别 out: y_onehot: 转换为one_hot 编码格式 ''' y = y.view(-1, 1)#第一个参数-1
表示让 PyTorch 自动计算这一维的大小。这意味着根据原有数据的总元素数量来决定这个维度的大小。第二个参数1
指定了新的张量的第二维的大小为 1。
y_onehot = torch.FloatTensor(3, 5) # In your for loop y_onehot.zero_() y_onehot.scatter_(1, y, 1)#scatter_
是一个原地操作方法,将数据放置到指定的索引位置。这个方法会修改y_onehot
张量本身。第一个参数1
表示在第二个维度上进行散布(即按列)。
return y_onehot def cross_entropy_one_hot(target): # 解码 _, labels = target.max(dim=1) return labels # 如果需要调用cross_entropy,则还需要传入一个input_ #return F.cross_entropy(input_, labels) x = np.array([1,2,3]) x_tensor =torch.from_numpy(x) print(one_hot(x_tensor)) x2 = np.array([[0,1,0,0,0]]) x2_tensor = torch.from_numpy(x2) print(cross_entropy_one_hot(x2_tensor))
pytorch进行mnist分类
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)
通过pytorch定义神经网络
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)
自定义神经网络模型在PyTorch中需要继承Module,然后用户自己重写Forward方法完成前向计算,因此我们的类Neural_net 必须继承torch.nn.Module。
Neural net( (layer1): Linear(in features=784,out features=500, bias=True) (layer2): Linear(in features=500,out features=10, bias=True) )
训练
# 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_oader : images =Variable(images.view(-1,28*28)) outputs =net(images) -,predicts =torch.max(outputs.data,1) total += labels.size(0) correct +=(predicts ==labels).sum() print('Accuracy =%.2f'%(100*correct /total))
标签:torch,神经网络,Variable,pytorch,图像,np,import,data,size From: https://www.cnblogs.com/candice1/p/18345859