【人工智能基础】FNN前馈神经网络

【人工智能基础】FNN前馈神经网络本文详细介绍了 FNN 的原理 并给出了具体的推导过程 使用 Pytorch 搭建了 FNN 模型 并对糖尿病数据集开展分类任务实战 一 Introduction 在神经网络中 最基本的结构就是神经元 给定一组神经元 如何组合成一个神经网络呢

大家好,我是讯享网,很高兴认识大家。

 
讯享网

🍊本文详细介绍了FNN的原理,并给出了具体的推导过程

🍊使用Pytorch搭建了FNN模型,并对糖尿病数据集开展分类任务实战

一、Introduction

在神经网络中,最基本的结构就是神经元,给定一组神经元,如何组合成一个神经网络呢?一个最简单的做法就是将神经元分成不同的组,每组作为一个网络层,随后与前一层全连接,如下图中所示,这就是前馈神经网络。

 很多时候我们将前馈神经神经网络称为多层感知机MLP(Mutlti-Layer Perceptron),但是严谨的来讲,此称谓并不合适,因为FNN的每个神经元是LogisticRegression模型,是连续的非线性模型,而MLP的本意是非连续的非线性模型。

二、Principle

前馈神经网络的原理也非常简单,即每两层网络层都是全连接,每一层的神经元接受到上一层的神经元信号并传递到下一层。以下是数学公式推导过程

 令a^{0} = 𝒙,前馈神经网络通过不断迭代下面公式进行信息传播:

三、Experiment

题目:diabetes是一个糖尿病数据集,一共有8个特征,最终需要判断该人是否患有糖尿病,即二分类任务。其数据集如下(该数据集比较经典,网上很容易下载到)。现需要使用建立FNN模型对其开展分类任务。

伪代码

1 数据读取

2 定义FNN模型

3 定义损失函数和优化器

4 模型训练

5 可视化训练结果

import numpy as np import torch import matplotlib.pyplot as plt # Prepare the dataset dataset = np.loadtxt('diabetes.csv', delimiter=',', dtype=np.float32, encoding='utf-8') x_data = torch.from_numpy(dataset[:, :-1]) y_data = torch.from_numpy(dataset[:, [-1]]) # Define the model class FNNModel(torch.nn.Module): def __init__(self): super(FNNModel, self).__init__() self.linear1 = torch.nn.Linear(8, 6) # 输入数据的特征有8个,也就是有8个维度,随后将其降维到6维 self.linear2 = torch.nn.Linear(6, 4) # 6维降到4维 self.linear3 = torch.nn.Linear(4, 2) # 4维降到2维 self.linear4 = torch.nn.Linear(2, 1) # 2w维降到1维 self.sigmoid = torch.nn.Sigmoid() # 可以视其为网络的一层,而不是简单的函数使用 def forward(self, x): x = self.sigmoid(self.linear1(x)) x = self.sigmoid(self.linear2(x)) x = self.sigmoid(self.linear3(x)) x = self.sigmoid(self.linear4(x)) return x model = FNNModel() # Define the criterion and optimizer criterion = torch.nn.BCELoss(reduction='mean') # 返回损失的平均值 optimizer = torch.optim.SGD(model.parameters(), lr=0.1) epoch_list = [] loss_list = [] # Training for epoch in range(): y_pred = model(x_data) loss = criterion(y_pred, y_data) print('Epoch[{}/{}],loss:{:.6f}'.format(epoch+1, , loss.item())) epoch_list.append(epoch) loss_list.append(loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() # Drawing plt.plot(epoch_list, loss_list) plt.xlabel('epoch') plt.ylabel('loss') plt.show() 

讯享网

Result

 可以看到随着时间的推进,该模型的损失值在不断的收敛。说明此FNN模型是有效的

在正式的项目中,1数据集的处理都是通过Dataset类和DataLoader类进行的

                             2 使用SGD比较少,更多的是使用mini_batch训练方法

                             3 使用__main__脚本进行项目的开启

因此作者重写了上述内容 

讯享网import numpy as np import torch import matplotlib.pyplot as plt from torch.utils.data import Dataset, DataLoader # Prepare the dataset class DiabetesDateset(Dataset): # 加载数据集 def __init__(self, filepath): xy = np.loadtxt(filepath, delimiter=',', dtype=np.float32, encoding='utf-8') self.len = xy.shape[0] # shape[0]是矩阵的行数,shape[1]是矩阵的列数 self.x_data = torch.from_numpy(xy[:, :-1]) self.y_data = torch.from_numpy(xy[:, [-1]]) # 获取数据索引 def __getitem__(self, index): return self.x_data[index], self.y_data[index] # 获得数据总量 def __len__(self): return self.len dataset = DiabetesDateset('diabetes.csv') train_loader = DataLoader(dataset=dataset, batch_size=32, shuffle=True, num_workers=2) # num_workers为多线程 # Define the model class FNNModel(torch.nn.Module): def __init__(self): super(FNNModel, self).__init__() self.linear1 = torch.nn.Linear(8, 6) # 输入数据的特征有8个,也就是有8个维度,随后将其降维到6维 self.linear2 = torch.nn.Linear(6, 4) # 6维降到4维 self.linear3 = torch.nn.Linear(4, 2) # 4维降到2维 self.linear4 = torch.nn.Linear(2, 1) # 2w维降到1维 self.sigmoid = torch.nn.Sigmoid() # 可以视其为网络的一层,而不是简单的函数使用 def forward(self, x): x = self.sigmoid(self.linear1(x)) x = self.sigmoid(self.linear2(x)) x = self.sigmoid(self.linear3(x)) x = self.sigmoid(self.linear4(x)) return x model = FNNModel() # Define the criterion and optimizer criterion = torch.nn.BCELoss(reduction='mean') # 返回损失的平均值 optimizer = torch.optim.SGD(model.parameters(), lr=0.01) epoch_list = [] loss_list = [] # Training if __name__ == '__main__': for epoch in range(100): # i是一个epoch中第几次迭代,一共756条数据,每个mini_batch为32,所以一个epoch需要迭代23次 # data获取的数据为(x,y) loss_one_epoch = 0 for i, data in enumerate(train_loader, 0): inputs, labels = data y_pred = model(inputs) loss = criterion(y_pred, labels) loss_one_epoch += loss.item() optimizer.zero_grad() loss.backward() optimizer.step() loss_list.append(loss_one_epoch / 23) epoch_list.append(epoch) print('Epoch[{}/{}],loss:{:.6f}'.format(epoch + 1, 100, loss_one_epoch / 23)) # Drawing plt.plot(epoch_list, loss_list) plt.xlabel('epoch') plt.ylabel('loss') plt.show() 

Result 

因为Mini_batch训练的方法虽然最终效果比较好,但是训练的速度实在是太慢了,因此作者将Epoch只设置了100层,因此最终的Loss在67%左右,如果加大训练量如第一个实验中的Epoch中,那么Loss会继续收敛的

参考资料

《机器学习》周志华

《深度学习与机器学习》吴恩达

《神经网络与与深度学习》邱锡鹏

《Pytorch深度学习实战》刘二大人

小讯
上一篇 2025-03-21 13:03
下一篇 2025-03-26 19:29

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/36590.html