当前位置: 首页 > news >正文

《Python星球日记》 第51天:神经网络基础

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》
创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)

目录

    • 一、引言:走进神经网络的世界
    • 二、神经元与激活函数
      • 1. 神经元:计算的基本单元
      • 2. 激活函数的种类与特点
        • a) Sigmoid 函数
        • b) ReLU 函数
        • c) Tanh 函数
    • 三、多层感知机(MLP)结构
      • 1. 从单个神经元到神经网络
      • 2. MLP 的基本组成部分
      • 3. 多层感知机的特点与优势
    • 四、前向传播与损失计算
      • 1. 前向传播:信息的正向流动
      • 2. 损失函数:评估预测质量
    • 五、激活函数的选择与影响
      • 1. 不同层的激活函数选择策略
      • 2. 激活函数对模型性能的影响
    • 六、代码练习:使用框架构建简单神经网络
      • 1. 使用 PyTorch 构建神经网络
      • 2. 使用 TensorFlow/Keras 构建神经网络
    • 七、总结与展望
      • 1. 关键知识点回顾
      • 2. 深度学习的下一步

👋 专栏介绍: Python星球日记专栏介绍(持续更新ing)
上一篇: 《Python星球日记》 第50天:深度学习概述与环境搭建

今天是我们Python星球探索之旅的第51天!🪐

一、引言:走进神经网络的世界

经过前面的机器学习基础学习,我们今天将揭开深度学习的神秘面纱,探索神经网络的基本原理。

神经网络是什么?简单来说,它是一种模仿人类大脑结构和工作方式的算法模型,能够从大量数据中学习复杂的模式。无论是语音识别、图像分类还是自然语言处理,神经网络都展现出了强大的能力。让我们一起踏上这段奇妙的旅程吧!

二、神经元与激活函数

1. 神经元:计算的基本单元

神经元(Neuron)是神经网络的基本构建块,其灵感来源于生物神经元的工作方式。在数学上,一个神经元接收多个输入,对这些输入进行加权求和,然后通过一个激活函数转换为输出

在这里插入图片描述

神经元模型是一个接收多个输入值,并产生单一输出的基本计算单元。它包含三个关键组成部分:

  1. 输入与权重:每个输入值 x_i 都与一个对应的权重 w_i 相乘
  2. 求和函数:将所有加权输入求和,并加上一个偏置项 b
  3. 激活函数:将线性求和的结果转化为非线性输出

神经元的数学表达式为:

y = f(w₁x₁ + w₂x₂ + ... + wₙxₙ + b)

其中 f 就是激活函数,它决定了神经元的输出特性。

2. 激活函数的种类与特点

激活函数神经网络中引入非线性的关键组件,它能让网络学习复杂的模式。让我们来了解几种常用的激活函数:

在这里插入图片描述

a) Sigmoid 函数

Sigmoid 函数是最早使用的激活函数之一,其数学表达式为:

σ(x) = 1 / (1 + e^(-x))

它将任何输入映射到 0 到 1 之间的值,形成一条 S 形曲线。

  • 优点:输出范围有限,可以用于表示概率,平滑可导
  • 缺点:在输入值较大或较小时,梯度接近于零,导致梯度消失问题;输出不是零中心的
b) ReLU 函数

ReLU(Rectified Linear Unit,修正线性单元)是目前最受欢迎的激活函数之一,其数学表达式简单:

ReLU(x) = max(0, x)

它将所有负值置为零,而正值保持不变。

  • 优点:计算效率高,有效缓解梯度消失问题,促进稀疏激活
  • 缺点:可能导致"神经元死亡"(当输入总是为负时),输出不是零中心的
c) Tanh 函数

Tanh(双曲正切)函数在形状上类似于 Sigmoid,但其输出范围是 -1 到 1:

tanh(x) = (e^x - e^(-x)) / (e^x + e^(-x))
  • 优点:输出是零中心的,有助于后续层的学习
  • 缺点:仍然存在梯度消失问题,但比 Sigmoid 要轻微

在这里插入图片描述

三、多层感知机(MLP)结构

1. 从单个神经元到神经网络

单个神经元的能力有限,但当我们将多个神经元按层组织起来,就形成了多层感知机(Multilayer Perceptron,MLP)。MLP 是最基础的前馈神经网络,信息只从输入层向输出层单向传播。

在这里插入图片描述

2. MLP 的基本组成部分

多层感知机通常由以下三种层构成:

  • 输入层:接收原始数据的神经元,每个输入特征对应一个神经元
  • 隐藏层:位于输入层和输出层之间的中间层,可以有一层或多层
  • 输出层:产生最终预测结果的神经元层

每一层的神经元都与下一层的所有神经元全连接,这种结构也称为全连接层密集层。一个典型的 MLP 网络可以表示为:

输入层 → 隐藏层1 → 隐藏层2 → ... → 隐藏层n → 输出层

请添加图片描述

3. 多层感知机的特点与优势

多层感知机相比单层感知机有以下显著优势:

  • 非线性映射能力:通过激活函数引入非线性,能够学习复杂的非线性决策边界
  • 表达能力增强:隐藏层越多,网络的表达能力越强,可以拟合更复杂的函数
  • 分层特征学习:浅层网络学习简单特征,深层网络学习复杂特征,形成层次化的特征表示

四、前向传播与损失计算

1. 前向传播:信息的正向流动

前向传播(Forward Propagation)是神经网络中信息从输入层流向输出层的过程

在这里插入图片描述

在这个过程中,每一层的神经元接收前一层的输出,进行计算,然后将结果传递给下一层。让我们用一个简单的双隐层神经网络来解释这个过程:

1》输入层接收数据:假设我们有特征向量 X = [x₁, x₂, …, xₙ]
2》计算第一隐藏层

  • 线性变换:Z₁ = W₁X + b₁,其中 W₁ 是权重矩阵,b₁ 是偏置向量
  • 应用激活函数:A₁ = f₁(Z₁),如 ReLU(Z₁)

3》计算第二隐藏层

  • 线性变换:Z₂ = W₂A₁ + b₂
  • 应用激活函数:A₂ = f₂(Z₂)

4》计算输出层

  • 线性变换:Z₃ = W₃A₂ + b₃
  • 应用输出激活函数:Ŷ = f_out(Z₃)
    • 对于回归问题,可能不使用激活函数
    • 对于二分类问题,通常使用 Sigmoid 函数
    • 对于多分类问题,通常使用 Softmax 函数

前向传播是一个从输入到输出的计算过程,每一步都依赖于前一步的结果和当前层的参数(权重和偏置)。

2. 损失函数:评估预测质量

损失函数(Loss Function)用于衡量神经网络预测值与真实值之间的差距。不同类型的问题需要不同的损失函数:

  • 均方误差(Mean Squared Error, MSE):常用于回归问题

    MSE = (1/n) * Σ(y_i - ŷ_i)²
    
  • 交叉熵损失(Cross-Entropy Loss):常用于分类问题

    对于二分类:CE = -[y * log(ŷ) + (1-y) * log(1-ŷ)]
    对于多分类:CE = -Σ(y_i * log(ŷ_i))
    

损失函数越小,表示模型的预测越接近真实值,这是神经网络训练的目标。

五、激活函数的选择与影响

1. 不同层的激活函数选择策略

在神经网络设计中,激活函数的选择对模型性能有显著影响。这里有一些常用的选择策略:
在这里插入图片描述

1》隐藏层激活函数

  • ReLU 是目前隐藏层最常用的激活函数,因为它计算简单且有效缓解梯度消失问题
  • Leaky ReLUELU 是 ReLU 的变种,解决了 “神经元死亡” 问题
  • Tanh 在某些情况下仍然有用,特别是在循环神经网络中

2》输出层激活函数

  • 线性函数(即不使用激活函数):适用于回归问题
  • Sigmoid:适用于二分类问题(输出0-1之间的概率值)
  • Softmax:适用于多分类问题(输出多个类别的概率分布)

2. 激活函数对模型性能的影响

激活函数的选择会影响以下几个方面:

  • 训练速度:ReLU系列通常比 Sigmoid 和 Tanh 训练更快
  • 梯度流动:好的激活函数应当避免梯度消失或爆炸
  • 模型表达能力:非线性激活函数让网络能学习复杂模式
  • 稀疏激活:如 ReLU 让部分神经元不激活,增加模型稀疏性

一般的经验法则是:从 ReLU 作为隐藏层的激活函数开始,如果遇到问题再尝试其他选择。

六、代码练习:使用框架构建简单神经网络

现在让我们动手实践,分别使用 PyTorch 和 TensorFlow 构建一个简单的神经网络,来解决手写数字识别的经典问题(MNIST数据集)。

1. 使用 PyTorch 构建神经网络

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import DataLoader# 设定随机种子,确保结果可重复
torch.manual_seed(42)# 1. 数据准备
transform = transforms.Compose([transforms.ToTensor(),  # 将图像转换为张量transforms.Normalize((0.1307,), (0.3081,))  # 标准化(MNIST数据集的均值和标准差)
])# 加载MNIST训练集和测试集
train_dataset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)# 创建数据加载器
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)# 2. 定义神经网络模型
class MLP(nn.Module):def __init__(self):super(MLP, self).__init__()# 输入层 -> 隐藏层1self.fc1 = nn.Linear(28*28, 128)  # MNIST图像是28x28像素# 隐藏层1 -> 隐藏层2self.fc2 = nn.Linear(128, 64)# 隐藏层2 -> 输出层self.fc3 = nn.Linear(64, 10)  # 10个类别(数字0-9)# 定义激活函数self.relu = nn.ReLU()def forward(self, x):# 将28x28的图像展平为向量x = x.view(-1, 28*28)# 前向传播过程x = self.fc1(x)      # 线性变换x = self.relu(x)     # 应用ReLU激活函数x = self.fc2(x)      # 线性变换x = self.relu(x)     # 应用ReLU激活函数x = self.fc3(x)      # 线性变换到输出层return x             # 返回logits,不应用softmax(CrossEntropyLoss会内部处理)# 3. 实例化模型、定义损失函数和优化器
model = MLP()
criterion = nn.CrossEntropyLoss()  # 交叉熵损失函数(内部包含softmax)
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9)  # 随机梯度下降优化器# 4. 训练模型
num_epochs = 5
print("开始训练...")for epoch in range(num_epochs):running_loss = 0.0for i, (inputs, labels) in enumerate(train_loader):# 清空梯度optimizer.zero_grad()# 前向传播outputs = model(inputs)# 计算损失loss = criterion(outputs, labels)# 反向传播loss.backward()# 更新参数optimizer.step()# 统计损失running_loss += loss.item()# 每100批次打印一次训练信息if (i+1) % 100 == 0:print(f'Epoch [{epoch+1}/{num_epochs}], Step [{i+1}/{len(train_loader)}], Loss: {running_loss/100:.4f}')running_loss = 0.0# 5. 测试模型
model.eval()  # 设置为评估模式
correct = 0
total = 0with torch.no_grad():  # 不计算梯度for inputs, labels in test_loader:outputs = model(inputs)_, predicted = torch.max(outputs.data, 1)  # 获取最大概率的索引total += labels.size(0)correct += (predicted == labels).sum().item()print(f'测试准确率: {100 * correct / total:.2f}%')

在这里插入图片描述

2. 使用 TensorFlow/Keras 构建神经网络

import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models
import numpy as np# 设置随机种子,确保结果可重复
tf.random.set_seed(42)
np.random.seed(42)# 1. 加载和预处理MNIST数据集
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()# 标准化像素值到[0, 1]范围
x_train = x_train.astype("float32") / 255
x_test = x_test.astype("float32") / 255# 将图像展平为一维向量
x_train = x_train.reshape(-1, 28*28)
x_test = x_test.reshape(-1, 28*28)# One-hot编码标签
y_train = keras.utils.to_categorical(y_train, 10)
y_test = keras.utils.to_categorical(y_test, 10)# 2. 定义神经网络模型
model = models.Sequential([# 输入层 -> 隐藏层1layers.Dense(128, activation='relu', input_shape=(28*28,)),# 隐藏层1 -> 隐藏层2layers.Dense(64, activation='relu'),# 隐藏层2 -> 输出层layers.Dense(10, activation='softmax')  # 输出层使用softmax激活函数
])# 3. 编译模型
model.compile(optimizer=keras.optimizers.SGD(learning_rate=0.01, momentum=0.9),  # 随机梯度下降优化器loss='categorical_crossentropy',  # 分类交叉熵损失函数metrics=['accuracy']  # 评估指标
)# 4. 查看模型结构
model.summary()# 5. 训练模型
print("开始训练...")
history = model.fit(x_train, y_train,epochs=5,batch_size=64,validation_split=0.1,  # 使用10%的训练数据作为验证集verbose=1
)# 6. 评估模型性能
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"测试准确率: {test_acc*100:.2f}%")# 7. 进行预测示例
predictions = model.predict(x_test[:5])
print("预测结果示例:")
for i in range(5):predicted_label = np.argmax(predictions[i])true_label = np.argmax(y_test[i])print(f"样本 {i+1}: 预测为 {predicted_label}, 实际为 {true_label}")

在这里插入图片描述
在这里插入图片描述

七、总结与展望

今天,我们学习了神经网络的基础知识,包括神经元结构、激活函数、多层感知机以及前向传播的原理。通过实践,我们使用 PyTorch 和 TensorFlow 实现了简单的神经网络模型。这些概念是深度学习的基石,将帮助我们理解更复杂的神经网络架构。

1. 关键知识点回顾

  • 神经元是神经网络的基本单元,由输入、权重、偏置和激活函数组成
  • 激活函数(Sigmoid、ReLU、Tanh)为网络引入非线性,使其能学习复杂模式
  • 多层感知机(MLP)是一种基本的前馈神经网络,由输入层、隐藏层和输出层组成
  • 前向传播是信息从输入层到输出层的流动过程,用于生成预测
  • 损失函数用于衡量预测值与真实值之间的差距,是模型优化的目标

2. 深度学习的下一步

神经网络基础只是深度学习的开始。在接下来的学习中,我们将探索:

  • 反向传播算法:如何通过梯度下降更新网络权重
  • 卷积神经网络(CNN):特别适用于图像处理的神经网络
  • 循环神经网络(RNN):处理序列数据的网络架构
  • 注意力机制:提高模型对关键信息的关注
  • 预训练模型:如何利用迁移学习加速模型训练

深度学习是一个不断发展的领域,持续学习和实践是掌握这些技术的关键。明天,我们将继续我们的Python星球之旅,探索更多深度学习的奥秘!


祝你学习愉快,Python星球的探索者!👨‍🚀🌠

创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊)
如果你对今天的内容有任何问题,或者想分享你的学习心得,欢迎在评论区留言讨论!

相关文章:

  • JS较底层的用法,几类简单介绍
  • HTTP/2概览及内核解析
  • IPFS与去中心化存储:重塑数字世界的基石
  • BGP邻居建立
  • Redis-x64-3.0.500
  • rt-thread+STM32H7移植lwip出现问题解决方法
  • Spark MLlib网页长青
  • 养生:拥抱健康生活的秘诀
  • MySql 年,月,日 查询 某时间段的 日期列表
  • 自动泊车技术—相机模型
  • DNS服务实验
  • Python百库指南:数据科学到Web开发全解析
  • Spring事务融入(REQUIRED)具体实现步骤解析
  • 游戏引擎学习第269天:清理菜单绘制
  • 互联网大厂Java面试实录:从基础到微服务的深度考察
  • 使用 JAX-RS 创建 REST 服务/微服务
  • 5大B2B数字营销社群营销标杆案例TOB企业数字化营销内容营销AI营销培训讲师培训师专家顾问唐兴通分享
  • KTOR for windows:無文件落地HTTP服务扫描工具
  • SaaS场快订平台项目说明【持续更新】
  • window 显示驱动开发-AGP 类型伸缩空间段
  • 佩斯科夫:俄会考虑30天停火提议,但试图对俄施压无用
  • 巴基斯坦全面恢复领空开放
  • 瑞士联邦主席凯勒-祖特尔、联邦副主席帕姆兰会见何立峰
  • 理财经理泄露客户信息案进展:湖南省检受理申诉,证监会交由地方监管局办理
  • 习近平同瑞典国王卡尔十六世·古斯塔夫就中瑞建交75周年互致贺电
  • 美众议院通过法案将“墨西哥湾”更名为“美国湾”