作者简介:热爱数据分析,学习Python、Stata、SPSS等统计语言的小高同学~
个人主页:小高要坚强的博客
当前专栏:Python之机器学习
本文内容:神经网络介绍及其在Python中的线性回归应用
作者“三要”格言:要坚强、要努力、要学习
目录
- 一、神经网络原理详解
- 1. 神经网络的基本结构
- 2.神经元模型
- 3. 激活函数
- 4.前向传播
- 5.反向传播
- 6. 损失函数
- 7.优化算法
- 8.训练过程
- 二、Python中的神经网络实现
- 代码详解
- 1.数据构造
- 2.定义神经网络
- 3.CUDA支持
- 4.损失函数与优化器
- 5.绘图函数
- 6.训练过程
- 三、总结
一、神经网络原理详解
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之机器学习》,让我们一起努力坚强学习,共同进步吧~