【深度学习实验】前馈神经网络(final):final

目录

一、实验介绍

 二、实验环境

1. 配置虚拟环境

2. 库版本介绍

三、实验内容

0. 导入必要的工具包

1. 构建数据集(IrisDataset)

2. 构建模型(FeedForward)

a. __init__(初始化)

b. forward(前向传播)

3.整合训练、评估、预测过程(Runner)

4. 模型评价(Accuracy)

5. 代码整合


一、实验介绍

      

 二、实验环境

    本系列实验使用了PyTorch深度学习框架,相关操作如下:

1. 配置虚拟环境

conda create -n DL python=3.7 
conda activate DL
pip install torch==1.8.1+cu102 torchvision==0.9.1+cu102 torchaudio==0.8.1 -f https://download.pytorch.org/whl/torch_stable.html
conda install matplotlib
 conda install scikit-learn

2. 库版本介绍

软件包本实验版本目前最新版
matplotlib3.5.33.8.0
numpy1.21.61.26.0
python3.7.16
scikit-learn0.22.11.3.0
torch1.8.1+cu1022.0.1
torchaudio0.8.12.0.2
torchvision0.9.1+cu1020.15.2

三、实验内容

ChatGPT:

        前馈神经网络(Feedforward Neural Network)是一种常见的人工神经网络模型,也被称为多层感知器(Multilayer Perceptron,MLP)。它是一种基于前向传播的模型,主要用于解决分类和回归问题。

        前馈神经网络由多个层组成,包括输入层、隐藏层和输出层。它的名称"前馈"源于信号在网络中只能向前流动,即从输入层经过隐藏层最终到达输出层,没有反馈连接。

以下是前馈神经网络的一般工作原理:

  1. 输入层:接收原始数据或特征向量作为网络的输入,每个输入被表示为网络的一个神经元。每个神经元将输入加权并通过激活函数进行转换,产生一个输出信号。

  2. 隐藏层:前馈神经网络可以包含一个或多个隐藏层,每个隐藏层由多个神经元组成。隐藏层的神经元接收来自上一层的输入,并将加权和经过激活函数转换后的信号传递给下一层。

  3. 输出层:最后一个隐藏层的输出被传递到输出层,输出层通常由一个或多个神经元组成。输出层的神经元根据要解决的问题类型(分类或回归)使用适当的激活函数(如Sigmoid、Softmax等)将最终结果输出。

  4. 前向传播:信号从输入层通过隐藏层传递到输出层的过程称为前向传播。在前向传播过程中,每个神经元将前一层的输出乘以相应的权重,并将结果传递给下一层。这样的计算通过网络中的每一层逐层进行,直到产生最终的输出。

  5. 损失函数和训练:前馈神经网络的训练过程通常涉及定义一个损失函数,用于衡量模型预测输出与真实标签之间的差异。常见的损失函数包括均方误差(Mean Squared Error)和交叉熵(Cross-Entropy)。通过使用反向传播算法(Backpropagation)和优化算法(如梯度下降),网络根据损失函数的梯度进行参数调整,以最小化损失函数的值。

        前馈神经网络的优点包括能够处理复杂的非线性关系,适用于各种问题类型,并且能够通过训练来自动学习特征表示。然而,它也存在一些挑战,如容易过拟合、对大规模数据和高维数据的处理较困难等。为了应对这些挑战,一些改进的网络结构和训练技术被提出,如卷积神经网络(Convolutional Neural Networks)和循环神经网络(Recurrent Neural Networks)等。

本系列为实验内容,对理论知识不进行详细阐释

(咳咳,其实是没时间整理,待有缘之时,回来填坑)

977468b5ae9843c6a88005e792817cb1.png

0. 导入必要的工具包

import torch
from torch import nn
import torch.nn.functional as F
# 绘画时使用的工具包
import matplotlib.pyplot as plt
# 导入鸢尾花数据集
from sklearn.datasets import load_iris
# 构建自己的数据集,继承自Dataset类
from torch.utils.data import Dataset, DataLoader

1. 构建数据集(IrisDataset)

【深度学习实验】前馈神经网络(七):批量加载数据(直接加载数据→定义类封装数据)_QomolangmaH的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_63834988/article/details/133181882?spm=1001.2014.3001.5501

2. 构建模型(FeedForward)

        依靠深度学习框架,构建一个简单的两层前馈神经网络。这个前馈神经网络和前文实现的MLP类最大的区别在于,我们实现类中使用了自己写的激活函数,该激活函数不能通过反向传播更新参数,但深度学习框架已经帮我们完成了这个功能。(其实通过简单的改动,我们的激活函数也可以反传梯度)

【深度学习实验】前馈神经网络(三):自定义多层感知机(激活函数logistic、线性层算Linear)_QomolangmaH的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_63834988/article/details/133097102?spm=1001.2014.3001.5501

class FeedForward(nn.Module):def __init__(self, input_size, hidden_size, output_size):super(FeedForward,self).__init__()self.fc1 = nn.Linear(input_size, hidden_size)self.fc2 = nn.Linear(hidden_size, output_size)self.act = nn.Sigmoid()def forward(self, inputs):outputs = self.fc1(inputs)outputs = self.act(outputs)outputs = self.fc2(outputs)return outputs

a. __init__(初始化)

  • 三个参数:
    • input_size(输入大小)
    • hidden_size(隐藏层大小)
    • output_size(输出大小)
  • 调用父类nn.Module的初始化方法super(FeedForward, self).init(),确保正确地初始化该类作为一个nn.Module。
  • 两个线性层self.fc1和self.fc2:
    • self.fc1的输入大小为input_size,输出大小为hidden_size;
    • self.fc2的输入大小为hidden_size,输出大小为output_size。
  • 一个激活函数self.act,这里使用的是nn.Sigmoid(),即Sigmoid激活函数。

b. forward(前向传播)

  • 接受一个输入张量inputs。在前向传播过程中,
    • 输入经过self.fc1线性层,
    • 然后通过self.act激活函数进行非线性变换,
    • 再经过self.fc2线性层得到最终的输出张量outputs

3.整合训练、评估、预测过程(Runner)

4. 模型评价(Accuracy)

【深度学习实验】前馈神经网络(八):模型评价(自定义支持分批进行评价的Accuracy类)_QomolangmaH的博客-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/m0_63834988/article/details/133186305?spm=1001.2014.3001.5501

5. 代码整合

# 导入必要的工具包
import torch
from torch import nn
import torch.nn.functional as F
# 绘画时使用的工具包
import matplotlib.pyplot as plt
# 导入鸢尾花数据集
from sklearn.datasets import load_iris
# 构建自己的数据集,继承自Dataset类
from torch.utils.data import Dataset, DataLoader# 此函数用于加载鸢尾花数据集
def load_data(shuffle=True):x = torch.tensor(load_iris().data)y = torch.tensor(load_iris().target)# 数据归一化x_min = torch.min(x, dim=0).valuesx_max = torch.max(x, dim=0).valuesx = (x - x_min) / (x_max - x_min)if shuffle:idx = torch.randperm(x.shape[0])x = x[idx]y = y[idx]return x, y
class IrisDataset(Dataset):def __init__(self, mode='train', num_train=120, num_dev=15):super(IrisDataset, self).__init__()x, y = load_data(shuffle=True)if mode == 'train':self.x, self.y = x[:num_train], y[:num_train]elif mode == 'dev':self.x, self.y = x[num_train:num_train + num_dev], y[num_train:num_train + num_dev]else:self.x, self.y = x[num_train + num_dev:], y[num_train + num_dev:]def __getitem__(self, idx):return self.x[idx], self.y[idx]def __len__(self):return len(self.x)class FeedForward(nn.Module):def __init__(self, input_size, hidden_size, output_size):super(FeedForward, self).__init__()self.fc1 = nn.Linear(input_size, hidden_size)self.fc2 = nn.Linear(hidden_size, output_size)self.act = nn.Sigmoid()def forward(self, inputs):outputs = self.fc1(inputs)outputs = self.act(outputs)outputs = self.fc2(outputs)return outputs# 支持分批进行模型评价的 Accuracy 类
class Accuracy:def __init__(self, is_logist=True):# 正确样本个数self.num_correct = 0# 样本总数self.num_count = 0self.is_logist = is_logistdef update(self, outputs, labels):# 判断是否为二分类任务if outputs.shape[1] == 1:outputs = outputs.squeeze(-1)# 判断是否是logit形式的预测值if self.is_logist:preds = (outputs >= 0).long()else:preds = (preds >= 0.5).long()else:# 多分类任务时,计算最大元素索引作为类别preds = torch.argmax(outputs, dim=1).long()# 获取本批数据中预测正确的样本个数labels = labels.squeeze(-1)batch_correct = (preds == labels).float().sum()batch_count = len(labels)# 更新self.num_correct += batch_correctself.num_count += batch_countdef accumulate(self):# 使用累计的数据,计算总的评价指标if self.num_count == 0:return 0return self.num_correct / self.num_countdef reset(self):self.num_correct = 0self.num_count = 0class Runner(object):def __init__(self, model, optimizer, loss_fn, metric, **kwargs):self.model = modelself.optimizer = optimizerself.loss_fn = loss_fn# 用于计算评价指标self.metric = metric# 记录训练过程中的评价指标变化self.dev_scores = []# 记录训练过程中的损失变化self.train_epoch_losses = []self.dev_losses = []# 记录全局最优评价指标self.best_score = 0# 模型训练阶段def train(self, train_loader, dev_loader=None, **kwargs):# 将模型设置为训练模式,此时模型的参数会被更新self.model.train()num_epochs = kwargs.get('num_epochs', 0)log_steps = kwargs.get('log_steps', 100)save_path = kwargs.get('save_path', 'best_mode.pth')eval_steps = kwargs.get('eval_steps', 0)# 运行的step数,不等于epoch数global_step = 0if eval_steps:if dev_loader is None:raise RuntimeError('Error: dev_loader can not be None!')if self.metric is None:raise RuntimeError('Error: Metric can not be None')# 遍历训练的轮数for epoch in range(num_epochs):total_loss = 0# 遍历数据集for step, data in enumerate(train_loader):x, y = datalogits = self.model(x.float())loss = self.loss_fn(logits, y.long())total_loss += lossif log_steps and global_step % log_steps == 0:print(f'loss:{loss.item():.5f}')loss.backward()self.optimizer.step()self.optimizer.zero_grad()# 每隔一定轮次进行一次验证,由eval_steps参数控制,可以采用不同的验证判断条件if (epoch + 1) % eval_steps == 0:dev_score, dev_loss = self.evaluate(dev_loader, global_step=global_step)print(f'[Evalute] dev score:{dev_score:.5f}, dev loss:{dev_loss:.5f}')if dev_score > self.best_score:self.save_model(f'model_{epoch + 1}.pth')print(f'[Evaluate]best accuracy performance has been updated: {self.best_score:.5f}-->{dev_score:.5f}')self.best_score = dev_score# 验证过程结束后,请记住将模型调回训练模式self.model.train()global_step += 1# 保存当前轮次训练损失的累计值train_loss = (total_loss / len(train_loader)).item()self.train_epoch_losses.append((global_step, train_loss))print('[Train] Train done')# 模型评价阶段def evaluate(self, dev_loader, **kwargs):assert self.metric is not None# 将模型设置为验证模式,此模式下,模型的参数不会更新self.model.eval()global_step = kwargs.get('global_step', -1)total_loss = 0self.metric.reset()for batch_id, data in enumerate(dev_loader):x, y = datalogits = self.model(x.float())loss = self.loss_fn(logits, y.long()).item()total_loss += lossself.metric.update(logits, y)dev_loss = (total_loss / len(dev_loader))self.dev_losses.append((global_step, dev_loss))dev_score = self.metric.accumulate()self.dev_scores.append(dev_score)return dev_score, dev_loss# 模型预测阶段,def predict(self, x, **kwargs):self.model.eval()logits = self.model(x)return logits# 保存模型的参数def save_model(self, save_path):torch.save(self.model.state_dict(), save_path)# 读取模型的参数def load_model(self, model_path):self.model.load_state_dict(torch.load(model_path, map_location=torch.device('cpu')))batch_size = 16# 分别构建训练集、验证集和测试集
train_dataset = IrisDataset(mode='train')
dev_dataset = IrisDataset(mode='dev')
test_dataset = IrisDataset(mode='test')train_loader = DataLoader(train_dataset, batch_size=batch_size,shuffle=True)
dev_loader = DataLoader(dev_dataset, batch_size=batch_size)
test_loader = DataLoader(test_dataset, batch_size=1, shuffle=True)input_size = 4
output_size = 3
hidden_size = 6
# 定义模型
model = FeedForward(input_size, hidden_size, output_size)
# 定义损失函数
loss_fn = F.cross_entropy
# 定义优化器
optimizer = torch.optim.SGD(model.parameters(), lr=0.2)
# 定义评价方法
metric = Accuracy(is_logist=True)
# 实例化辅助runner类
runner = Runner(model, optimizer, loss_fn, metric)
# 模型训练
runner.train(train_loader, dev_loader, num_epochs=50, log_steps=10, eval_steps=5)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/139981.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

golang优先级坑

看如下代码,我本以为a1, a2是相同的 package mainimport "fmt"func main() {b, c, d : 1, 0, 1a1 : b ^ c&(^d) // 1 ^a2 : c ^ b&(^d) // 0 ^fmt.Println(a1, a2) // 1 0 }但结果却是不同的,在golang中&的优先级^和|…

罗德里格斯公式

1.点乘 A ⃗ ⋅ B ⃗ ∣ A ⃗ ∣ ∣ B ⃗ ∣ c o s ⟨ A ⃗ , B ⃗ ⟩ \vec{A} \cdot \vec{B} \left | \vec{A} \right | \left | \vec{B} \right | cos\left \langle \vec{A}, \vec{B} \right \rangle A ⋅B ​A ​ ​B ​cos⟨A ,B ⟩ 对应几何意义:向量 A ⃗…

众佰诚:抖音店铺开网店前期需要投入多少

随着互联网的迅猛发展,电子商务已经成为了商业领域中的一股不可忽视的力量。而在电子商务中,抖音店铺已经成为了一个备受关注的平台,吸引了众多创业者和商家的关注。那么,在开设抖音店铺并转型为网店之前,究竟需要投入…

SVN的基本使用

一、SVN介绍 SVN(Subversion)是一个开源的版本控制系统,它专门用于管理文件和目录的变更。SVN 提供了一种集中式的版本控制方案,其中有一个中央仓库存储所有文件的历史记录和变更。 SVN使用方式相对简单,可以通过命令…

ROS 基础教程

欢迎访问我的博客首页。 ROS 基础教程 1.urdf 文件1.1 在 Rviz 中显示 urdf1.1.1 定义 urdf1.1.2 在 Rviz 中查看 urdf 1.2 在 Gazebo 中显示 urdf1.2.1 定义 urdf1.2.2 在 Gazebo 中查看 urdf 2.建图-仿真2.1 模型 1.urdf 文件 假设我们的工作空间是 ws_ros。我们自己实现的包…

有效保护敏感数据的最佳实践

在当今数据驱动的环境中,数据就是力量,组织仍然高度关注如何利用其数据进行 BI、分析和其他业务驱动计划。 事实上,最近的研究表明,数据领导者的主要动机是对高质量分析洞察的需求,而不是合规性。 然而,…

Centos7原生hadoop环境,搭建Impala集群和负载均衡配置

Centos7原生hadoop环境,搭建Impala集群和负载均衡配置 impala介绍 Impala集群包含一个Catalog Server (Catalogd)、一个Statestore Server (Statestored) 和若干个Impala Daemon (Impalad)。Catalogd主要负责元数据的获取和DDL的执行,Statestored主要负…

greenhills compiler 2021.1.4 for x86 Linux

greenhills compiler 2021.1.4 for x86 Linux 2692407267qq.com,更多内容请见http://user.qzone.qq.com/2692407267/

ipad触控笔有必要买原装吗?ipad2023手写笔推荐

目前,在无纸教学、无纸办公的大背景下,电容笔得到了广泛的关注。只是,对于这两支电容笔的不同之处,不少人并不是很清楚。其实这两种电容笔都很好区分,第一种是主动电容笔,也就是我们常用的电容式屏幕&#…

JavaWeb开发-06-SpringBootWeb-MySQL

一.MySQL概述 1.安装、配置 官网下载地址:https://dev.mysql.com/downloads/mysql/ 2.数据模型 3.SQL简介 二.数据库设计-DDL 1.数据库 官网:http:// https://www.jetbrains.com/zh-cn/datagrip/ 2.表(创建、查询、修改、删除) #…

前端react 18.2整合ckeditor富文本编辑器——配置插件、自定义toolbar工具栏

文章目录 ⭐前言⭐引入ckeditor⭐npm 包引入⭐cdn资源引入 ⭐自定义插件💖 自定义yma16配置插件 ⭐总结⭐结束 ⭐前言 大家好,我是yma16,本文分享关于前端react整合ckeditor——配置插件、自定义toolbar工具栏。 react系列往期文章&#xff…

SpringBoot使用@Async异步注解

首先,想一想为什么使用异步线程? 举个例子: 当我们请求这个接口的时候,在接口调用了method这个方法 然而被调用的方法执行了一个线程睡眠三秒 因为method方法睡眠了三秒钟,所以这个接口响应的时间肯定是大于三秒。因为接口是从上往下执行的,首先会在控制台输出一…

UE5读取json文件

一、下载插件 在工程中启用 二、定义读取外部json文件的函数,参考我之前的文章 ue5读取外部文件_艺菲的博客-CSDN博客 三、读取文件并解析为json对象 这里Load Text就是自己定义的函数,ResourceBundle为一个字符串常量,通常是读取的文件夹…

Super Marker插件——标记资源,提高效率

插件介绍: 这是一款可以给资源添加颜色或图标标记📌的插件,当资源文件比较多的时候,颜色标记可以让你一眼定位到要使用的资源,提高开发效率。 插件地址: Cocos商店:https://store.cocos.com/a…

nginx SseEmitter 长连接

1、问题还原: 在做openai机器人时,后台使用 SseEmitterEventSource 实现流式获取数据,前端通过 EventSourcePolyfill 函数接收后端的数据,在页面流式输出到页面,做成逐字打稿的效果。本地测试后,可以正常获…

如何用好免费的ChatGPT

如何用好免费的ChatGPT 前言ChatGPT使用入口在线体验地址:点我体验 ChatGPT介绍ChatGPT初级使用技巧初级使用技巧:清晰明了的问题表达 ChatGPT中级使用语法中级使用语法:具体化问题并提供背景信息 ChatGPT高级使用高级使用:追问、…

python随手小练3

题目: 写出一个判断闰年的python代码: 闰年的条件: 如果N能够被4整除,并且不能被100整除,则是闰年 或者:N能被400整除,也是闰年 即:4年一润并且百年不润,每400年再润一…

怒刷LeetCode的第14天(Java版)

目录 第一题 题目来源 题目内容 解决方法 方法一:动态规划 方法二:栈 方法三:双指针 第二题 题目来源 题目内容 解决方法 方法一:二分查找 方法二:线性扫描 方法三:递归 第三题 题目来源 …

深度解析React 18应用性能提升

众所周知,React 18 引入的一个重要特性就是并发功能,从根本上改变了 React 应用程序的渲染方式。本文将带大家一同探讨这些最新功能的具体作用,特别是如何提高应用程序性能。 一、主线程与长任务 当我们在浏览器中运行 JavaScript 时,JS 引擎会在单线程环境下执行代码内容…

2、RocketMQ消息的分类

一、普通消息 1 消息发送分类 Producer对于消息的发送方式也有多种选择,不同的方式会产生不同的系统效果。 同步发送消息 同步发送消息是指,Producer发出⼀条消息后,会在收到MQ返回的ACK之后才发下⼀条消息。该方式的消息可靠性最高&#xff…