神经网络介绍及其在Python中的应用(一)

发布于:2024-10-13 ⋅ 阅读:(7) ⋅ 点赞:(0)

在这里插入图片描述

作者简介:热爱数据分析,学习Python、Stata、SPSS等统计语言的小高同学~
个人主页小高要坚强的博客
当前专栏Python之机器学习
本文内容:神经网络介绍及其在Python中的线性回归应用
作者“三要”格言:要坚强、要努力、要学习

一、神经网络原理详解

1. 神经网络的基本结构

神经网络由输入层、隐藏层和输出层组成。每层由多个神经元(节点)构成。以下是各层的功能:

  • 输入层:接收外部数据,每个输入对应一个神经元。
  • 隐藏层:进行特征提取和模式识别。可以有多个隐藏层,层数越多,模型越复杂,能够学习到更复杂的特征。
  • 输出层:生成最终的预测结果,节点数量根据具体任务而定(如分类任务的类别数)。

2.神经元模型

每个神经元的计算过程可以表示为:
y=f(w⋅x+b)

  • x:输入向量。
  • w:权重向量,决定输入对输出的影响。
  • b:偏置项,调整输出值。
  • f:激活函数,用于引入非线性。

3. 激活函数

激活函数在神经元的输出中引入非线性,常用的激活函数包括:

Sigmoid:输出范围在(0, 1)之间,适合二分类任务。
在这里插入图片描述
ReLU(Rectified Linear Unit):输出为输入值的正部分,避免了梯度消失问题。
在这里插入图片描述

Tanh:输出范围在(-1, 1)之间,常用于隐藏层。

4.前向传播

前向传播是指输入数据通过网络传播,直到输出结果的过程。每个神经元接收输入,应用权重和激活函数,最终生成输出。

具体过程如下:

  • 输入数据通过输入层进入。
  • 加权求和:每个神经元将输入值与权重相乘后相加,并加上偏置。
  • 应用激活函数:输出结果通过激活函数生成。
  • 结果传递:输出结果传递给下一层神经元,直到输出层。

5.反向传播

反向传播是神经网络学习的核心算法,通过最小化损失函数来更新权重和偏置。其步骤如下:

  • 计算损失:使用损失函数(如均方误差)计算输出和真实标签之间的误差。
  • 计算梯度:通过链式法则,计算损失函数关于每个权重的梯度。
  • 更新权重:使用优化器(如SGD或Adam)根据计算得到的梯度调整权重和偏置。

6. 损失函数

损失函数衡量模型预测与真实值之间的差异。常用的损失函数包括:

  • 均方误差(MSE):适合回归问题,公式为:
    在这里插入图片描述
  • 交叉熵损失:适合分类问题,公式为:
    在这里插入图片描述

7.优化算法

优化算法用于更新神经网络的权重,以减少损失。常用的优化算法有:

  • 随机梯度下降(SGD):每次仅使用一个样本更新权重,计算效率高,但可能在局部极小值处震荡。
  • Adam优化器:结合了Momentum和RMSProp的优点,能够自适应调整学习率,效果通常较好。

8.训练过程

整个训练过程可以分为以下几个步骤:

  • 数据准备:加载并预处理数据,划分为训练集和测试集。
  • 模型初始化:定义神经网络模型,选择损失函数和优化器。
  • 训练循环:在每个epoch中,进行前向传播、计算损失、反向传播和权重更新。
  • 评估性能:在验证集上评估模型性能,监控过拟合情况。

二、Python中的神经网络实现

我们将通过以下代码实现一个简单的线性回归模型,并逐步解释每个部分。

import torch
import matplotlib.pyplot as plt
import os
from torch import nn, optim
from time import perf_counter

# 为了防止有些版本的jupyter kernel崩溃,设置这个属性
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True'

# 源数据构造
X = torch.unsqueeze(torch.linspace(-3, 3, 100000), dim=1)  # 扩维
Y = X + 1.2 * torch.rand(X.size())  # 添加噪声

# 神经网络实现线性回归
class LR(nn.Module):  # 网络模型必须继承nn.Module类
    def __init__(self):
        super(LR, self).__init__() # 调用父类构造方法
        self.linear = nn.Linear(in_features=1, out_features=1)

    def forward(self, x):  # 前向传播方法,x参数接收输入数据
        out = self.linear(x)  # 线性加权操作
        return out

# 判断CUDA加速
CUDA = torch.cuda.is_available()
if CUDA:
    LR_module = LR().cuda()  # 将模型移动到GPU
    inputs = X.cuda()
    targets = Y.cuda()
else:
    LR_module = LR()
    inputs = X
targets = Y

# 损失函数和优化器
criterion = nn.MSELoss()  # 均方误差损失
optimizer = optim.SGD(LR_module.parameters(), lr=1e-4)  # 随机梯度下降优化器

# 绘图函数
def draw(output, loss):
    if CUDA:
        output = output.cpu()  # 将数据移回CPU以进行绘图
    plt.cla()
    plt.scatter(X.numpy(), Y.numpy())  # 原始数据散点图
    plt.plot(X.numpy(), output.data.numpy(), 'r-', lw=5)  # 绘制拟合直线
    plt.text(0.5, 0, 'Loss=%s' % (loss.item()), fontdict={'size': 20, 'color': 'red'})
    plt.pause(0.005)

# 训练函数
def train(model, criterion, optimizer, epochs):
    for epoch in range(epochs):
        output = model(inputs)  # 调用神经网络对象进行前向传播
        loss = criterion(output, targets)  # 损失函数的值
        optimizer.zero_grad()  #清空上一轮的梯度值
        loss.backward()  # 反向传播,计算梯度
        optimizer.step()  #  更新权重值
        if epoch % 80 == 0:  # 每80轮绘制图,观察训练效果,epoch为整个训练集通过网络进行一次前向和一次反向传播的过程
            draw(output, loss)
    return model, loss

# 调用测试
start = perf_counter()
model, loss = train(LR_module, criterion, optimizer, epochs=5000)
finish = perf_counter()
time_total = finish - start
print("训练耗费时间:%s" % time_total)
print("final loss:", loss.item())
print("weights:", list(model.parameters()))

代码详解

1.数据构造

  • X为输入特征,从-3到3的100,000个均匀分布的点。
  • Y是目标值,加入了随机噪声,使得模型更具挑战性。

2.定义神经网络

  • LR类继承自nn.Module,其中self.linear定义了一个线性层,输入和输出特征均为1。

3.CUDA支持

  • 检查是否可以使用CUDA加速,如果可以,则将模型和数据移动到GPU。

4.损失函数与优化器

  • 使用均方误差损失函数(MSELoss)和随机梯度下降(SGD)作为优化器。

5.绘图函数

  • draw函数用于实时显示训练过程中的数据点和模型拟合结果。

6.训练过程

  • train函数中,进行前向传播、计算损失、反向传播和权重更新。每80个epoch绘制一次图以观察训练进展。

通过上述代码,我们实现了一个简单的线性回归模型,演示了神经网络的基本构建和训练过程。

三、总结

神经网络通过层叠多个非线性变换,能够学习到复杂的模式和特征。在实际应用中,通过选择合适的架构、激活函数和优化算法,可以实现高效的模型训练和预测。随着深度学习技术的不断发展,神经网络将在更广泛的领域发挥作用。

在这里插入图片描述

码字艰辛,本篇内容就分享至此,如果渴望深入了解更多Python机器学习方面的应用,别忘了点击关注博主,引导你从零开始探索Python在统计分析上的奥秘。同时,对于在数据分析与机器学习旅程中感到迷茫的朋友们,欢迎浏览我的专题系列:《Python之机器学习》,让我们一起努力坚强学习,共同进步吧~

请添加图片描述