Vitis AI 基本认知(构建线性回归Torch/TensorFlow+欠定系统+过拟合)

目录

1. 目的

2. Tensor Flow

2.1 Sequential

2.2 Functional

3. PyTorch

3.1 Sequential

3.2 Functional

4. 欠定系统

4.1 方程的解

4.2 欠定系统与过拟合

5. 总结


1. 目的

  • 学习不同深度学习框架下构建模型的区别。
  • 以简单的线性回归模型为例:y=\vec{W}x+b
  • 欠定系统与过拟合

2. Tensor Flow

在 Keras 中,介绍 Sequential 和 Functional 是两种不同的模型构建方式。

2.1 Sequential

特点:

  • 通过 Sequential() 创建模型,使用 model.add() 方法逐层添加网络层。这种方式简单直观,适用于线性堆叠的模型。
  • 不需要显式定义输入层,只需在第一层中指定 input_shape。
  • 适用于简单的线性堆叠模型,不支持共享层、多输入或多输出。
  • 代码结构简单,适合快速原型设计和简单模型。

示例代码:

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

# 输入数据
X = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
Y = tf.constant([[10.0], [20.0]])

# 创建模型
model = Sequential([
    Dense(1, activation=None, kernel_initializer='zeros', bias_initializer='zeros')
])

# 编译模型
model.compile(optimizer='sgd', loss='mse')

# 训练模型
model.fit(X, Y, epochs=500, verbose=0)

# 打印模型变量
print(model.variables)

 模型详细信息:

Model: "sequential"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 dense_14 (Dense)            (None, 1)                 4         
                                                                 
=================================================================
Total params: 4
Trainable params: 4
Non-trainable params: 0
_________________________________________________________________

2.2 Functional

特点:

  • 需要显式定义输入层,然后逐层调用函数来构建模型。这种方式更灵活,适用于复杂的网络结构。
  • 支持复杂的网络拓扑结构,包括共享层、多输入和多输出,适用于更复杂的模型设计。
  • 代码结构更复杂,适用于需要复杂拓扑结构的模型,如残差网络(ResNet)和注意力机制(Attention)模型。

示例代码:

import tensorflow as tf
from tensorflow.keras.layers import Input, Dense
from tensorflow.keras.models import Model

# 输入数据
X = tf.constant([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
Y = tf.constant([[10.0], [20.0]])

# 定义输入层
inputs = Input(shape=(3,))

# 定义输出层
output = Dense(1, activation=None, kernel_initializer='zeros', bias_initializer='zeros')(inputs)

# 创建模型
model = Model(inputs=inputs, outputs=output)

# 编译模型
model.compile(optimizer='sgd', loss='mse')

# 训练模型
model.fit(X, Y, epochs=500, verbose=0)

# 打印模型变量
print(model.variables)

 

3. PyTorch

3.1 Sequential

import torch
import torch.nn as nn
import torch.optim as optim

# 输入数据
X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
Y = torch.tensor([[10.0], [20.0]])

# 定义模型
model = nn.Sequential(
    nn.Linear(3, 1)
)

# 初始化权重和偏置为零
nn.init.zeros_(model[0].weight)
nn.init.zeros_(model[0].bias)

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
for epoch in range(500):
    model.train()
    optimizer.zero_grad()
    outputs = model(X)
    loss = criterion(outputs, Y)
    loss.backward()
    optimizer.step()

# 打印模型变量
for name, param in model.named_parameters():
    print(f"{name}: {param.data}")

3.2 Functional

import torch
import torch.nn as nn
import torch.optim as optim

# 输入数据
X = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
Y = torch.tensor([[10.0], [20.0]])

# 定义模型
class LinearRegressionModel(nn.Module):
    def __init__(self):
        super(LinearRegressionModel, self).__init__()
        self.linear = nn.Linear(3, 1)
        # 初始化权重和偏置为零
        nn.init.zeros_(self.linear.weight)
        nn.init.zeros_(self.linear.bias)

    def forward(self, x):
        return self.linear(x)

model = LinearRegressionModel()

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 训练模型
for epoch in range(500):
    model.train()
    optimizer.zero_grad()
    outputs = model(X)
    loss = criterion(outputs, Y)
    loss.backward()
    optimizer.step()

# 打印模型变量
for name, param in model.named_parameters():
    print(f"{name}: {param.data}")

模型训练,进行多次迭代(epoch),在每次迭代中:

  1. 设置模型为训练模式。
  2. 清空之前的梯度(optimizer.zero_grad())。
  3. 计算模型的输出。
  4. 计算损失。
  5. 进行反向传播(loss.backward())。
  6. 更新模型参数(optimizer.step())。

运行结果:

linear.weight: tensor([[0.0119, 1.1134, 2.2150]])
linear.bias: tensor([1.1015])

4. 欠定系统

4.1 方程的解

在这个线性系统中,有四个未知数(三个权重w1, w2, w3)和一个偏置(b),但只有两个方程。这构成了一个欠定系统,即方程的数量少于未知数的数量,方程可能有无限多个解,或者没有解。

在机器学习和统计建模中,这种情况非常常见,特别是在特征数量多于训练样本数量的情况下。为了解决这种情况,通常会采用以下方法之一:

1. 正则化:引入一种额外的约束(如 L1 或 L2 正则化)来控制模型复杂度,从而避免过拟合并帮助求解过程。

2. 增加数据:提供更多的训练数据可以帮助系统构建更多的方程,从而可能解决欠定的问题。

3. 减少特征数量:通过特征选择或降维技术减少输入特征的数量,使问题变得更易于管理。

4. 使用迭代优化方法:尽管系统欠定,但可以通过迭代算法(如梯度下降)找到使损失函数最小化的参数值。这些值可能不是唯一确定的,但可以是问题的有效解。

在以上代码示例中,使用了梯度下降算法来优化权重和偏置,目标是最小化预测输出和实际输出之间的均方误差。虽然理论上存在多个可能的解决方案,但梯度下降将寻找到这些解中的一个,这个解能够在给定的数据和模型配置下尽可能地减少损失函数。

尽管从理论上讲,这个线性系统可能没有唯一解,机器学习模型仍然可以通过优化技术找到一个合适的解,用于预测未见数据的输出。

4.2 欠定系统与过拟合

欠定系统(underdetermined system)

欠定系统是指方程的数量少于未知数的数量的情况。在这种情况下,可能有多个或无限多个解决方案满足这些方程。在机器学习中,当模型的参数(未知数)远多于可用的训练样本(方程)时,可以认为是一个欠定系统。这种情况下,找到一个唯一的、确定的解决方案可能是困难的或不可能的,因为有多个参数配置可以拟合数据。

过拟合(overfitting)

过拟合是指模型在训练数据上表现得异常好,但在新的、未见过的数据上表现不佳的现象。这通常发生在模型过于复杂,拥有大量自由度(参数),可以学习到训练数据中的噪声和特定细节,而不仅仅是潜在的、普遍适用的模式。过拟合的模型失去了泛化能力,即在新数据上的预测能力。

关系和区别

欠定系统可能导致过拟合。因为在参数数量过多而数据量不足的情况下,模型有能力学习到数据中的每一个具体细节和噪声,而不是只学习到更普遍的模式。

过拟合并不一定只因为欠定系统。过拟合也可以由于模型过于复杂或训练方法不当等其他因素引起。例如,即使在一个确定系统(方程数量等于未知数数量的系统)中,如果模型复杂度过高,也可能出现过拟合。
 

5. 总结

在本学习笔记中,笔者探讨了不同深度学习框架下构建线性回归模型的方式,主要集中于 TensorFlow 和 PyTorch。通过使用 Keras 的 Sequential 和 Functional API,我们展示了两种模型构建方式的特点与适用场景。Sequential API 适合简单的线性堆叠模型,而 Functional API 则提供了更大的灵活性,适用于复杂的网络结构。

在 PyTorch 中,我们定义了一个线性回归模型,通过自定义类实现模型结构,并使用标准的训练流程进行模型优化。这种方法突显了 PyTorch 的灵活性和可定制性。

此外,我们深入探讨了欠定系统及其与过拟合的关系。欠定系统是指方程数量少于未知数,这在机器学习中表现为参数数量多于训练样本。当模型参数过多而训练数据不足时,模型可能会学习到训练数据中的噪声,从而导致过拟合现象。过拟合使得模型在新数据上的泛化能力下降,虽然并非所有过拟合都源于欠定系统,但两者之间存在紧密联系。

综上所述,理解不同模型构建方式及欠定系统的特性,有助于我们在实际应用中选择合适的模型架构,并采取有效的策略来避免过拟合,从而提高模型的预测能力与泛化性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值