首页 > 其他分享 >pytorch实现神经网络图像分类

pytorch实现神经网络图像分类

时间:2024-08-06 19:39:35浏览次数:16  
标签:torch 神经网络 Variable pytorch 图像 np import data size

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

相关文章

  • 使用pytorch实现数字识别器
    前言:本篇文章是关于数字识别器的识别和卷积神经网络的应用。若对卷积神经网络不熟悉,可参考文章:卷积神经网络关于深度学习的一些代码及实战,可参考深度学习基础(github)下面我们尝试用PyTorch搭建一个卷积神经网络,并用它来解决手写数字识别的问题。1、数据准备#torchvisio......
  • pytorch OSError: [WinError 1114] 动态链接库(DLL)初始化例程失败”原因分析
    动态链接库失败“OSError:[WinError1114]动态链接库(DLL)初始化例程失败。Errorloading"cublas64_12.dll"oroneofitsdependencies”原因分析出错情况:在importtorch中直接被抛出异常环境探讨【问题复现】:因为使用了新的torch-gpu环境【name称为torch】,固怀疑......
  • 人工神经网络相关名词
    一、人工神经网络人工神经网络(ArtificialNeuralNetworks,ANN)是一种模拟人脑神经网络结构和功能的计算模型,用于解决各种问题,如分类、回归、聚类等。它由多个神经元(Neuron)组成,每个神经元接收多个输入信号,通过加权和和激活函数进行计算,产生一个输出信号,作为下一层神经元的输入信......
  • 高速图像采集卡设计原理图: 613-基于6UVPX C6678+XCVU9P的信号处理板卡
    基于6UVPXC6678+XCVU9P的信号处理板卡一、板卡概述      板卡基于6U VPX标准结构,包含一个C6678 DSP芯片,一个XCVU9P 高性能FPGA,双路HPC FMC。  二、处理板技术指标•  DSP处理器采用TI 8核处理器TMS320C6678;•  DSP 外挂一组64bit DDR3......
  • 图像风格迁移技术(论文复现)
    图像风格迁移技术(论文复现)本文所涉及所有资源均在传知代码平台可获取文章目录图像风格迁移技术(论文复现)概述内容&风格表示内容风格演示效果核心逻辑使用方式概述图像风格迁移是指将一张图像的内容与另一张图像的风格相融合,生成具有新风格的图像。风格......
  • pytorch 模型加载和保存
    模型加载torch.load(f,map_location=None,pickle_module=<module'pickle'from'/opt/conda/lib/python3.6/pickle.py'>,**pickle_load_args) map_location适用于修改模型能在gpu上运行还是cpu上运行。一般情况下,加载模型,主要用于预测新来的一组样本。预测的主要流程包......
  • YOLOv9改进系列,YOLOv9引入SPDConv(新颖的卷积),用于低分辨率图像和小物体目标,实现大幅
    前言卷积神经网络在许多计算机视觉任务中取得了显著成功,例如图像分类和目标检测。然而,在图像分辨率较低或目标较小的更困难任务中,它们的性能会迅速下降。在本文中,指出这根源于现有CNN架构中一个常见但有缺陷的设计,即使用了步幅卷积和/或池化层,这导致了细粒度信息的丢失以......
  • 深度学习与图像识别(误差反向传播)
    误差反向传播法一 一个高效计算权重以及偏置量的梯度方法ReLU反向传播实现classRelu:def_init_(self):self.x=Nonedefforward(self,x):self.x=np.maximum(0,x)out=self.xreturnoutdefbackward(self,dout):dx=doutdx[self.x<=......
  • 基于神经网络的手写数字识别及其ZYNQ实现
        基于MNIST数据集的手写数字识别是神经网络(NeuralNetwork)的经典应用。    本文将讨论一种名为“ZYNET”的全连接神经网络框架,它可以自动生成针对FPGA的硬件实现架构。我们以手写数字识别为例,在ZYNQ平台上对该架构进行验证。本章包括以下几个部分:1环境配......
  • pytorch学习笔记5 tensor 广播broadcasting
    不同shape直接加减,系统会自动做broadcasting操作先右对齐(小维度对齐)比如:Featuremaps:[4,32,14,14]Bias:[32,1,1]=>][1,32,1,1]=>[4,32,14,14]做到与Featuremaps的shape相同,才能进行相加广播扩展的时候只是做这样的操作,并不实质拷贝数据,以节省内存空间可广播的条件......