赞
踩
目录
神经网络是一种计算模型,它模拟了人类神经系统的工作方式,由大量的神经元和它们之间的连接组成。每个神经元接收一些输入信息,并对这些信息进行处理,然后将结果传递给其他神经元。这些神经元之间的连接具有不同的权重,这些权重可以根据神经网络的训练数据进行调整。通过调整权重,神经网络可以对输入数据进行分类、回归、聚类等任务。
通俗来讲,神经网络就是设置一堆参数,初始化这堆参数,然后通过求导,知道这些参数对结果的影响,然后调整这些参数的大小。直到参数大小可以接近完美地拟合实际结果。神经网络有两个部分:正向传播和反向传播。正向传播是求值,反向传播是求出参数对结果的影响,从而调整参数。所以,神经网络:正向传播->反向传播->正向传播->反向传播……
比如我们要预测一个图像是不是猫。如果是猫,它的结果就是1,如果不是猫,它的结果就是0.我们现在有一堆图片,有的是猫,有的不是猫,所以它对应的标签(这个是y)是:0 1 1 0 1。而我们的预测结果可能是对的,也可能是错的,假设我们的预测结果是:0 0 1 1 0.我们有3个预测对了,有2个预测错了。那么我们的损失值是2/5。当然这么搞的话太“粗糙”了,实际上我们会有一个函数来定义损失值是什么。而且我们的预测结果也不是一个确凿的数字,而是一个概率:比如我们预测第3张图片是猫的概率是0.8,那么我们的预测结果是0.8.总之,定义了损失值(这个损失值记为J)以后,我们要让这个损失值尽可能地小。
神经网络看上去挺复杂,节点多,层多,参数多,但其结构都是类似的,核心部分和组件都是相通的,确定完这些核心组件,这个神经网络也就基本确定了。
核心组件包括:
(1)层:神经网络的基础数据结构是层,层是一个数据处理模块,它接受一个或多个张量作为输入,并输出一个或多个张量,由一组可调整参数描述。
(2)模型:模型是由多个层组成的网络,用于对输入数据进行分类、回归、聚类等任务。
(3)损失函数:参数学习的目标函数,通过最小化损失函数来学习各种参数。损失函数是衡量模型输出结果与真实标签之间的差异的函数,目标是最小化损失函数,提高模型性能。
(4)优化器:使损失函数的值最小化。根据损失函数的梯度更新神经网络中的权重和偏置,以使损失函数的值最小化,提高模型性能和稳定性。
描述:多个层链接在一起构成一个模型或网络,输入数据通过这个模型转换为预测值,然后损失函数把预测值与真实值进行比较,得到损失值(损失值可以是距离、概率值等),该损失值用于衡量预测值与目标结果的匹配或相似程度,优化器利用损失值更新权重参数,从而使损失值越来越小。这是一个循环过程,损失值达到一个阀值或循环次数到达指定次数,循环结束。
参考:第3章 Pytorch神经网络工具箱 | Python技术交流与分享
在PyTorch中,构建神经网络主要使用以下工具:
torch.nn模块:提供了构建神经网络所需的各种层和模块,如全连接层、卷积层、池化层、循环神经网络等。
torch.nn.functional模块:提供了一些常用的激活函数和损失函数,如ReLU、Sigmoid、CrossEntropyLoss等。
torch.optim模块:提供了各种优化器,如SGD、Adam、RMSprop等,用于更新神经网络中的权重和偏置。
torch.utils.data模块:提供了处理数据集的工具,如Dataset、DataLoader等,可以方便地处理数据集、进行批量训练等操作。
这些工具之间的相互关系如下:
使用torch.nn模块构建神经网络的各个层和模块。
使用torch.nn.functional模块中的激活函数和损失函数对神经网络进行非线性变换和优化。
使用torch.optim模块中的优化器对神经网络中的权重和偏置进行更新,以最小化损失函数。
使用torch.utils.data模块中的数据处理工具对数据集进行处理,方便地进行批量训练和数据预处理。
实例环境使用Pytorch1.0+,GPU或CPU,源数据集为MNIST。
(1)利用Pytorch内置函数mnist下载数据
(2)利用torchvision对数据进行预处理,调用torch.utils建立一个数据迭代器
(3)可视化源数据
(4)利用nn工具箱构建神经网络模型
(5)实例化模型,并定义损失函数及优化器
(6)训练模型
(7)可视化结果
实验中使用两个隐含层,每层激活函数为Relu,最后使用torch.max(out,1)找出张量out最大值对应索引作为预测值。
- import numpy as np
- import torch
- # 导入 pytorch 内置的 mnist 数据
- from torchvision.datasets import mnist
- #导入预处理模块
- import torchvision.transforms as transforms
- from torch.utils.data import DataLoader
- #导入nn及优化器
- import torch.nn.functional as F
- import torch.optim as optim
- from torch import nn
- # 定义训练和测试时的批处理大小
- train_batch_size = 64
- test_batch_size = 128
-
- # 定义学习率和迭代次数
- learning_rate = 0.01
- num_epoches = 20
-
- # 定义优化器的超参数
- lr = 0.01
- momentum = 0.5
- #动量优化器通过引入动量参数(Momentum),在更新参数时考虑之前的梯度信息,可以使得参数更新方向更加稳定,同时加速梯度下降的收敛速度。动量参数通常设置在0.5到0.9之间,可以根据具体情况进行调整。
- #定义预处理函数,这些预处理依次放在Compose函数中。
- transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5], [0.5])])
- #下载数据,并对数据进行预处理
- train_dataset = mnist.MNIST('./data', train=True, transform=transform, download=True)
- test_dataset = mnist.MNIST('./data', train=False, transform=transform)
- #dataloader是一个可迭代对象,可以使用迭代器一样使用。
- train_loader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=True)
- test_loader = DataLoader(test_dataset, batch_size=test_batch_size, shuffle=False)
注:
①transforms.Compose可以把一些转换函数组合在一起;
②Normalize([0.5], [0.5])对张量进行归一化,这里两个0.5分别表示对张量进行归一化的全局平均值和方差。因图像是灰色的只有一个通道,如果有多个通道,需要有多个数字,如三个通道,应该是Normalize([m1,m2,m3], [n1,n2,n3])
③download参数控制是否需要下载,如果./data目录下已有MNIST,可选择False。
④用DataLoader得到生成器,这可节省内存。
- # 导入matplotlib.pyplot库,并设置inline模式
- import matplotlib.pyplot as plt
- %matplotlib inline
-
- # 枚举数据加载器中的一批数据
- examples = enumerate(test_loader)
- batch_idx, (example_data, example_targets) = next(examples)
-
- # 创建一个图像对象
- fig = plt.figure()
-
- # 显示前6个图像和对应的标签
- for i in range(6):
- plt.subplot(2,3,i+1) # 将图像分成2行3列,当前位置为第i+1个
- plt.tight_layout() # 自动调整子图之间的间距
- plt.imshow(example_data[i][0], cmap='gray', interpolation='none') # 显示图像
- plt.title("Ground Truth: {}".format(example_targets[i])) # 显示标签
- plt.xticks([]) # 隐藏x轴刻度
- plt.yticks([]) # 隐藏y轴刻度

注:
导入matplotlib.pyplot库,并设置inline模式,以在Jupyter Notebook中显示图像。
枚举数据加载器中的一批数据,其中test_loader是一个测试数据集加载器。
创建一个图像对象,用于显示图像和标签。
显示前6个图像和对应的标签,其中plt.subplot()用于将图像分成2行3列,plt.tight_layout()用于自动调整子图之间的间距,plt.imshow()用于显示图像,plt.title()用于显示标签,plt.xticks()和plt.yticks()用于隐藏x轴和y轴的刻度。
- class Net(nn.Module):
- """
- 使用sequential构建网络,Sequential()函数的功能是将网络的层组合到一起
- """
- def __init__(self, in_dim, n_hidden_1, n_hidden_2, out_dim):
- super(Net, self).__init__()
- self.layer1 = nn.Sequential(nn.Linear(in_dim, n_hidden_1),nn.BatchNorm1d(n_hidden_1))
- self.layer2 = nn.Sequential(nn.Linear(n_hidden_1, n_hidden_2),nn.BatchNorm1d(n_hidden_2))
- self.layer3 = nn.Sequential(nn.Linear(n_hidden_2, out_dim))
-
-
- def forward(self, x):
- x = F.relu(self.layer1(x))
- x = F.relu(self.layer2(x))
- x = self.layer3(x)
- return x
-
-
- #检测是否有可用的GPU,有则使用,否则使用CPU
- device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
- #实例化网络
- model = Net(28 * 28, 300, 100, 10)
- model.to(device)
-
- # 定义损失函数和优化器
- criterion = nn.CrossEntropyLoss()
- optimizer = optim.SGD(model.parameters(), lr=lr, momentum=momentum)

- # 开始训练
- losses = []
- acces = []
- eval_losses = []
- eval_acces = []
-
-
- for epoch in range(num_epoches):
- train_loss = 0
- train_acc = 0
- model.train()
- #动态修改参数学习率
- if epoch%5==0:
- optimizer.param_groups[0]['lr']*=0.1
- for img, label in train_loader:
- img=img.to(device)
- label = label.to(device)
- img = img.view(img.size(0), -1)
- # 前向传播
- out = model(img)
- loss = criterion(out, label)
- # 反向传播
- optimizer.zero_grad()
- loss.backward()
- optimizer.step()
- # 记录误差
- train_loss += loss.item()
- # 计算分类的准确率
- _, pred = out.max(1)
- num_correct = (pred == label).sum().item()
- acc = num_correct / img.shape[0]
- train_acc += acc
-
- losses.append(train_loss / len(train_loader))
- acces.append(train_acc / len(train_loader))
- # 在测试集上检验效果
- eval_loss = 0
- eval_acc = 0
- # 将模型改为预测模式
- model.eval()
- for img, label in test_loader:
- img=img.to(device)
- label = label.to(device)
- img = img.view(img.size(0), -1)
- out = model(img)
- loss = criterion(out, label)
- # 记录误差
- eval_loss += loss.item()
- # 记录准确率
- _, pred = out.max(1)
- num_correct = (pred == label).sum().item()
- acc = num_correct / img.shape[0]
- eval_acc += acc
-
- eval_losses.append(eval_loss / len(test_loader))
- eval_acces.append(eval_acc / len(test_loader))
- print('epoch: {}, Train Loss: {:.4f}, Train Acc: {:.4f}, Test Loss: {:.4f}, Test Acc: {:.4f}'
- .format(epoch, train_loss / len(train_loader), train_acc / len(train_loader),
- eval_loss / len(test_loader), eval_acc / len(test_loader)))

- plt.title('train loss')
- plt.plot(np.arange(len(losses)), losses)
- plt.legend(['Train Loss'], loc='upper right')
- # 绘制测试集损失函数
- plt.plot(eval_losses, label='Test Loss')
- plt.title('Test Loss')
- plt.xlabel('Epoch')
- plt.ylabel('Loss')
- plt.legend()
- plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。