【DL】神经网络与机器学习基础知识介绍(二)【附程序】

原文:https://mengwoods.github.io/post/dl/009-dl-fundamental-2/

激活函数

  • 激活函数的目的是在模型中引入非线性,使网络能够学习和表示数据中的复杂模式。列出常见的激活函数。
    • 线性函数: y = x y=x y=x,通常只在输出层使用。
    • Sigmoid函数:S形曲线, y = 1 / ( 1 + e ( − x ) ) y = 1 / (1 + e^(-x)) y=1/(1+e(x))。它是非线性的,当X值在-2到2之间时,Y值变化非常陡峭。Y值范围是0到1。通常用于二分类的输出层,结果为0或1。
    • Tanh函数:效果比Sigmoid函数更好,亦称双曲正切函数,是Sigmoid函数的数学变形。 y = t a n h ( x ) = 2 / ( 1 + e − 2 x ) − 1 y = tanh(x) = 2/(1+e^{-2x})-1 y=tanh(x)=2/(1+e2x)1 y = 2 ∗ s i g m o i d ( 2 x ) − 1 y = 2*sigmoid(2x)-1 y=2sigmoid(2x)1。值范围是-1到1。通常用于网络的隐藏层,有助于通过将均值接近0来中心化数据。
    • ReLU函数:修正线性单元,最广泛使用的激活函数,主要用于隐藏层。 y = m a x ( 0 , x ) y = max(0,x) y=max(0,x)。由于涉及的数学运算更简单,ReLU比Tanh和Sigmoid的计算开销更小。ReLU学习速度比Sigmoid和Tanh快得多。
    • Softmax:也是一种Sigmoid函数,但适用于多分类问题。通常用于图像分类问题的输出层。理想情况下用于输出层,以输出概率来定义每个输入的类别。

基本规则:如果不知道使用哪种激活函数,可以简单地使用ReLU。对于输出层,二分类使用Sigmoid函数,多分类使用Softmax。

卷积神经网络

CNN专为处理结构化网格数据(如图像)而设计。它学习特征的空间层次,因此在图像分类、目标检测和语义分割等任务中效果显著。

  • CNN中的卷积层如何工作?

    • 它对输入数据应用一组滤波器(内核),每个滤波器在输入数据上滑动,计算点积。它生成一个特征图,突出显示特定特征(如边缘或纹理)的存在。卷积操作后接一个非线性激活函数。
  • CNN的主要组成部分是什么?

    • 输入层:保存图像的原始像素值。输入维度通常对应图像的高度、宽度和颜色通道。
    • 卷积层:重要参数包括滤波器数量、滤波器大小、步幅和填充。
    • 池化层:在保留最重要信息的同时,减少特征图的空间维度。常见类型包括最大池化和平均池化。
    • 输出层:使用如Softmax用于多分类或Sigmoid用于二分类的激活函数产生每个类别的输出概率。
  • 介绍一些著名的CNN网络:

    • AlexNet:2012年,包含5个卷积层,一些卷积层后跟随最大池化层,三个全连接层。激活函数使用ReLU。
    • VGGNet:2014年。由一系列具有小感受野(3x3)的卷积层、最大池化层和三个全连接层组成。变体包括VGG16和VGG19。它显示了网络深度是高性能的关键组成部分。

超参数

  • 简要介绍神经网络训练中的关键超参数。
    • 学习率Learning rate:控制每次模型更新时调整权重的幅度。较高的学习率意味着更大的步长,可以加速训练,但可能会超过最优解。较低的学习率意味着较小的步长和更精确的收敛。
    • 批大小Batch size:一次前向/后向传递中使用的训练样本数量。较大的批大小提供更准确的梯度估计,但需要更多内存。较小的批大小可能导致估计更嘈杂,但有助于泛化。
    • 训练轮数(Epochs):整个训练数据集通过神经网络的次数。更多的训练轮数可以更好地学习,但可能导致过拟合。
    • 丢弃率Dropout rate:正则化技术,在训练期间随机忽略神经元。决定丢弃的神经元比例。通常丢弃20%的节点。
    • 学习率衰减Learning rate decay:随着训练的进行,减少学习率,有助于在训练结束时更平滑地收敛。

其他

  • 什么是数据归一化?
    • 标准化和重构数据,是消除数据冗余的预处理步骤。将值缩放到特定范围,达到更好的收敛效果。
  • 前馈神经网络和循环神经网络的区别是什么?
    • 前馈网络中的信号从输入到输出单向传播,层之间没有反馈环。它不能记住先前的输入。
    • 循环神经网络中的信号双向传播,形成循环网络。它在生成层输出时考虑当前输入和先前收到的输入,能够由于其内部记忆而记住过去的数据。
  • 什么是批量归一化?
    • 通过在每一层中归一化输入使其具有零均值和单位标准差,以提高神经网络的性能和稳定性。
  • 什么是长短期记忆网络?
    • 是一种特殊的RNN,能够学习长期依赖性,记住信息的时间长短是其默认行为。

程序

用PyTorch编写一个简单的神经网络,包括训练步骤和通过新输入数据进行验证。

这个脚本用于创建、训练和评估一个简单的神经网络模型。首先,您可以通过设置mode='train'main函数中运行脚本来训练模型。在训练过程中,脚本将生成合成数据,定义网络结构,进行训练,并将训练后的模型保存到文件model.pth。如果您希望评估已训练的模型,则可以将mode设置为'eval',脚本将加载保存的模型并对新生成的输入数据进行预测,输出每个输入的特征和及其预测类别。通过调整mode参数,您可以在训练和评估模式之间切换。

# 引言
# 此脚本演示了使用PyTorch创建、训练和评估一个简单的神经网络。
# 生成的合成数据根据其特征和的特定规则,网络经过训练来分类这些数据。
# 脚本是模块化的,包括生成数据、定义模型、训练和评估的函数。
# main函数控制脚本运行在训练模式还是评估模式。

# 导入必要的库
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

# 生成具有某些底层规则的合成数据的函数
def generate_synthetic_data(num_samples, input_dim, num_classes):
    inputs = torch.randn(num_samples, input_dim)
    targets = torch.empty(num_samples, dtype=torch.long)
    
    for i in range(num_samples):
        feature_sum = inputs[i].sum().item()
        # 根据特征和的范围分配目标标签
        if feature_sum < -10:
            targets[i] = 0
        elif feature_sum < -5:
            targets[i] = 1
        elif feature_sum < 0:
            targets[i] = 2
        elif feature_sum < 5:
            targets[i] = 3
        elif feature_sum < 10:
            targets[i] = 4
        elif feature_sum < 15:
            targets[i] = 5
        elif feature_sum < 20:
            targets[i] = 6
        elif feature_sum < 25:
            targets[i] = 7
        elif feature_sum < 30:
            targets[i] = 8
        else:
            targets[i] = 9
            
    return inputs, targets

# 定义神经网络模型类
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.fc1 = nn.Linear(784, 128)  # 全连接层,从784个神经元到128个神经元
        self.fc2 = nn.Linear(128, 10)   # 全连接层,从128个神经元到10个神经元

    def forward(self, x):
        x = torch.relu(self.fc1(x))  # 在第一层之后应用ReLU激活函数
        x = self.fc2(x)              # 输出层,不使用激活函数
        return x

# 训练模型的函数
def train_model(model, dataloader, criterion, optimizer, num_epochs):
    for epoch in range(num_epochs):
        running_loss = 0.0
        for batch_inputs, batch_targets in dataloader:
            optimizer.zero_grad()  # 在反向传播之前清零梯度
            outputs = model(batch_inputs)  # 前向传播:计算输出
            loss = criterion(outputs, batch_targets)  # 计算损失
            loss.backward()  # 反向传播:计算梯度
            optimizer.step()  # 更新权重
            running_loss += loss.item() * batch_inputs.size(0)  # 累计损失以供监控
        epoch_loss = running_loss / len(dataloader.dataset)  # 计算平均损失
        print(f'第 {epoch+1}/{num_epochs} 轮,损失: {epoch_loss:.4f}')
    print('训练完成。')

# 评估模型的函数
def evaluate_model(model, inputs):
    model.eval()  # 设置模型为评估模式
    with torch.no_grad():  # 在推理过程中不需要计算梯度
        predictions = model(inputs)
    for i in range(len(inputs)):
        print(f"输入 {i+1} 的和: {inputs[i].sum().item()}")
        print(f"预测 {i+1}: {predictions[i].argmax().item()}")
        print("-" * 50)

# 主函数
def main(mode='train'):
    # 超参数
    num_samples = 1000
    input_dim = 784
    num_classes = 10
    batch_size = 64
    learning_rate = 0.001
    num_epochs = 100
    
    # 生成合成数据
    inputs, targets = generate_synthetic_data(num_samples, input_dim, num_classes)
    
    # 创建一个DataLoader以进行批处理
    dataset = TensorDataset(inputs, targets)
    dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
    
    # 实例化模型
    model = SimpleNN()
    
    # 定义损失函数和优化器
    criterion = nn.CrossEntropyLoss()  # 适用于具有多个类别的分类任务
    optimizer = optim.Adam(model.parameters(), lr=learning_rate)  # 学习率为0.001的Adam优化器
    
    if mode == 'train':
        # 训练模型
        train_model(model, dataloader, criterion, optimizer, num_epochs)
        # 保存模型状态字典
        torch.save(model.state_dict(), 'model.pth')
        print("模型已保存到 'model.pth'")
    elif mode == 'eval':
        # 加载模型
        model.load_state_dict(torch.load('model.pth'))
        print("模型已从 'model.pth' 加载")
        # 示例新输入数据
        new_inputs = torch.randn(10, 784)  # 10个新样本的批次,每个样本有784个特征
        # 评估模型
        evaluate_model(model, new_inputs)

if __name__ == '__main__':
    main(mode='eval')  # 根据需要设置为 'train' 或 'eval'


训练过程:

$ python pytorch.py 
Epoch 1/10, Loss: 2.2189
Epoch 2/10, Loss: 1.6003
Epoch 3/10, Loss: 1.2118
Epoch 4/10, Loss: 0.8805
Epoch 5/10, Loss: 0.5897
Epoch 6/10, Loss: 0.3645
Epoch 7/10, Loss: 0.2167
Epoch 8/10, Loss: 0.1331
Epoch 9/10, Loss: 0.0879
Epoch 10/10, Loss: 0.0624
Training complete.
Model saved to 'model.pth'

使用过程:

 $ python pytorch.py 
Model loaded from 'model.pth'
Input 1 Sum: 39.23176193237305
Prediction 1: 4
--------------------------------------------------
Input 2 Sum: -3.4055228233337402
Prediction 2: 2
--------------------------------------------------
Input 3 Sum: 32.59678649902344
Prediction 3: 9
--------------------------------------------------
Input 4 Sum: 32.965431213378906
Prediction 4: 3
--------------------------------------------------
Input 5 Sum: -11.920291900634766
Prediction 5: 0
--------------------------------------------------
Input 6 Sum: -6.332043647766113
Prediction 6: 4
--------------------------------------------------
Input 7 Sum: -1.9515066146850586
Prediction 7: 0
--------------------------------------------------
Input 8 Sum: 7.156068801879883
Prediction 8: 5
--------------------------------------------------
Input 9 Sum: 2.85219669342041
Prediction 9: 0
--------------------------------------------------
Input 10 Sum: -20.769487380981445
Prediction 10: 3
--------------------------------------------------
  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MengWoods

感谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值