多层感知机paddle

多层感知机——paddle部分

本文部分为paddle框架以及部分理论分析,torch框架对应代码可见多层感知机

import paddle
print("paddle version:",paddle.__version__)
paddle version: 2.6.1

多层感知机(MLP,也称为神经网络)与线性模型相比,具有以下几个显著的优势:

  1. 非线性建模能力:线性模型,如线性回归或逻辑回归,仅能够学习输入和输出之间的线性关系。然而,在现实世界中,许多问题和数据的关系是非线性的。多层感知机通过引入激活函数(如Sigmoid、ReLU等),能够在神经元之间创建非线性关系,从而能够捕捉和模拟更复杂的非线性模式。

  2. 强大的表征学习能力:多层感知机通过多层网络结构,能够学习到输入数据的层次化特征表示。每一层都可以被视为对输入数据进行的一种非线性变换,通过逐层传递,网络可以逐渐抽取出更高级、更抽象的特征,这有助于模型处理复杂的任务。

  3. 自动特征提取:在传统的机器学习模型中,特征工程是一个重要的步骤,需要人工设计和选择特征。然而,多层感知机具有自动学习和提取有用特征的能力。通过训练,网络可以自动发现数据中的重要特征,并据此进行预测和分类,从而减少了特征工程的依赖。

  4. 强大的泛化能力:由于多层感知机能够学习到数据的复杂非线性关系,并且具有自动特征提取的能力,因此它通常具有很好的泛化性能。这意味着训练好的模型能够较好地处理未见过的数据,这是机器学习模型的重要性能之一。

  5. 适应性强:多层感知机可以处理各种类型的数据,包括图像、文本、音频等。通过调整网络结构和参数,可以灵活地适应不同的学习任务和数据集。

  6. 持续优化和改进:多层感知机可以通过不同的优化算法(如梯度下降法)进行训练和调整,以不断改进模型的性能。此外,随着深度学习技术的不断发展,多层感知机的结构和训练方法也在不断优化和改进,使其在各种任务中取得更好的性能。

多层感知机(MLP)原理

多层感知机(Multilayer Perceptron, MLP)是一种前馈神经网络,由输入层、一个或多个隐藏层和输出层组成。每一层由若干个神经元构成,每个神经元执行线性变换和非线性激活。

网络结构

设:

  • 输入向量为 x = [ x 1 , x 2 , … , x n ] T \mathbf{x} = [x_1, x_2, \ldots, x_n]^T x=[x1,x2,,xn]T
  • 权重矩阵为 W ( l ) \mathbf{W}^{(l)} W(l) 和偏置向量为 b ( l ) \mathbf{b}^{(l)} b(l)
  • 激活函数为 ϕ ( ⋅ ) \phi(\cdot) ϕ()

l l l 层的输出 h ( l ) \mathbf{h}^{(l)} h(l) 可以表示为:
h ( l ) = ϕ ( W ( l ) h ( l − 1 ) + b ( l ) ) \mathbf{h}^{(l)} = \phi(\mathbf{W}^{(l)} \mathbf{h}^{(l-1)} + \mathbf{b}^{(l)}) h(l)=ϕ(W(l)h(l1)+b(l))
其中, h ( 0 ) = x \mathbf{h}^{(0)} = \mathbf{x} h(0)=x 表示输入层的输出。

每一层的计算过程包括线性变换和非线性变换:

  1. 线性变换
    a ( l ) = W ( l ) h ( l − 1 ) + b ( l ) \mathbf{a}^{(l)} = \mathbf{W}^{(l)} \mathbf{h}^{(l-1)} + \mathbf{b}^{(l)} a(l)=W(l)h(l1)+b(l)
  2. 非线性变换(激活函数)
    h ( l ) = ϕ ( a ( l ) ) \mathbf{h}^{(l)} = \phi(\mathbf{a}^{(l)}) h(l)=ϕ(a(l))
前向传播

前向传播是指从输入层到输出层的计算过程。通过前向传播可以得到网络的输出 y ^ \hat{\mathbf{y}} y^

对于一个三层的网络(输入层、一个隐藏层、输出层),前向传播的计算过程如下:

  1. 输入层到隐藏层:
    a ( 1 ) = W ( 1 ) x + b ( 1 ) \mathbf{a}^{(1)} = \mathbf{W}^{(1)} \mathbf{x} + \mathbf{b}^{(1)} a(1)=W(1)x+b(1)
    h ( 1 ) = ϕ ( a ( 1 ) ) \mathbf{h}^{(1)} = \phi(\mathbf{a}^{(1)}) h(1)=ϕ(a(1))

  2. 隐藏层到输出层:
    a ( 2 ) = W ( 2 ) h ( 1 ) + b ( 2 ) \mathbf{a}^{(2)} = \mathbf{W}^{(2)} \mathbf{h}^{(1)} + \mathbf{b}^{(2)} a(2)=W(2)h(1)+b(2)
    y ^ = ϕ ( a ( 2 ) ) \hat{\mathbf{y}} = \phi(\mathbf{a}^{(2)}) y^=ϕ(a(2))

损失函数

损失函数 L ( y , y ^ ) L(\mathbf{y}, \hat{\mathbf{y}}) L(y,y^) 用于衡量预测值 y ^ \hat{\mathbf{y}} y^ 和目标值 y \mathbf{y} y 之间的差异。常用的损失函数有均方误差和交叉熵损失。

对于均方误差:
L ( y , y ^ ) = 1 2 ∥ y − y ^ ∥ 2 L(\mathbf{y}, \hat{\mathbf{y}}) = \frac{1}{2} \|\mathbf{y} - \hat{\mathbf{y}}\|^2 L(y,y^)=21yy^2

反向传播

反向传播(Backpropagation)是通过计算损失函数相对于各层参数的梯度,从而更新网络参数以最小化损失函数的过程。

反向传播的关键步骤如下:

  1. 计算输出层的误差
    δ ( L ) = ∂ L ∂ a ( L ) = ( y ^ − y ) ⊙ ϕ ′ ( a ( L ) ) \delta^{(L)} = \frac{\partial L}{\partial \mathbf{a}^{(L)}} = (\hat{\mathbf{y}} - \mathbf{y}) \odot \phi'(\mathbf{a}^{(L)}) δ(L)=a(L)L=(y^y)ϕ(a(L))

  2. 计算隐藏层的误差
    δ ( l ) = ( W ( l + 1 ) ) T δ ( l + 1 ) ⊙ ϕ ′ ( a ( l ) ) \delta^{(l)} = (\mathbf{W}^{(l+1)})^T \delta^{(l+1)} \odot \phi'(\mathbf{a}^{(l)}) δ(l)=(W(l+1))Tδ(l+1)ϕ(a(l))
    其中, ⊙ \odot 表示元素逐个相乘, ϕ ′ ( a ( l ) ) \phi'(\mathbf{a}^{(l)}) ϕ(a(l)) 是激活函数的导数。

  3. 计算梯度
    ∂ L ∂ W ( l ) = δ ( l ) ( h ( l − 1 ) ) T \frac{\partial L}{\partial \mathbf{W}^{(l)}} = \delta^{(l)} (\mathbf{h}^{(l-1)})^T W(l)L=δ(l)(h(l1))T
    ∂ L ∂ b ( l ) = δ ( l ) \frac{\partial L}{\partial \mathbf{b}^{(l)}} = \delta^{(l)} b(l)L=δ(l)

  4. 更新权重
    使用梯度下降法,学习率为 η \eta η
    W ( l ) ← W ( l ) − η ∂ L ∂ W ( l ) \mathbf{W}^{(l)} \leftarrow \mathbf{W}^{(l)} - \eta \frac{\partial L}{\partial \mathbf{W}^{(l)}} W(l)W(l)ηW(l)L
    b ( l ) ← b ( l ) − η ∂ L ∂ b ( l ) \mathbf{b}^{(l)} \leftarrow \mathbf{b}^{(l)} - \eta \frac{\partial L}{\partial \mathbf{b}^{(l)}} b(l)b(l)ηb(l)L

通过反复进行以上步骤,网络的参数会逐渐调整,以最小化损失函数,从而提高模型的预测准确性。

激活函数

激活函数在神经网络中起着至关重要的作用,它们决定了神经网络的非线性特性和表达能力。注意,激活函数不会改变输入输出的形状,它只对每一个元素进行运算。以下是激活函数的主要作用和用途:

1. 引入非线性

神经网络的核心计算包括线性变换(矩阵乘法和加法)和非线性变换(激活函数)。如果没有激活函数,整个网络就只是线性变换的叠加,无论有多少层,最终也只是输入的线性变换,无法处理复杂的非线性问题。

通过引入非线性激活函数,神经网络能够逼近任意复杂的函数,从而具有更强的表达能力。

2. 提供特征转换

激活函数可以将线性变换的输出映射到不同的特征空间,从而使得神经网络能够捕捉输入数据的复杂特征。每一层的激活函数都对输入进行某种形式的特征转换,使得后续层能够更好地学习和提取特征。

3. 保持梯度流

在反向传播过程中,激活函数的选择会影响梯度的传播。如果激活函数的导数为0,梯度将无法传播,导致网络无法训练。适当的激活函数可以避免梯度消失和梯度爆炸问题,使得梯度能够顺利传播。

常用的激活函数
  1. Sigmoid 函数
    σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1 + e^{-x}} σ(x)=1+ex1
    • 优点:输出范围在 (0, 1) 之间,便于处理概率问题。
    • 缺点:容易导致梯度消失问题,特别是在深层网络中。
import numpy as np  
import matplotlib.pyplot as plt  # 测试sigmoid函数  
x_input = paddle.arange(-8.0, 8.0, 0.1, dtype='float32')  # 输入  
x_input.stop_gradient = False  # 允许梯度计算  
y_output = paddle.nn.functional.sigmoid(x_input)  # 输出  # 绘制图像  
plt.plot(x_input.numpy(), y_output.numpy())  
plt.show()

sigmoid

  1. Tanh 函数
    tanh ⁡ ( x ) = e x − e − x e x + e − x \tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} tanh(x)=ex+exexex
    • 优点:输出范围在 (-1, 1) 之间,相对于 Sigmoid 函数,梯度消失问题较少。
    • 缺点:仍然可能出现梯度消失问题。
# 测试Tanh函数  
x_input = paddle.arange(-8.0, 8.0, 0.1, dtype='float32')  # 输入  
x_input.stop_gradient = False  # 允许梯度计算  
y_output = paddle.nn.functional.tanh(x_input)  # 输出  # 绘制图像  
plt.plot(x_input.numpy(), y_output.numpy())  
plt.show()

tanh

  1. ReLU 函数
    ReLU ( x ) = max ⁡ ( 0 , x ) \text{ReLU}(x) = \max(0, x) ReLU(x)=max(0,x)
    • 优点:计算简单,高效,能够缓解梯度消失问题。
    • 缺点:在训练过程中,部分神经元可能会“死亡”(即长时间输出为0),导致梯度无法更新。
# 测试ReLU函数  
x_input = paddle.arange(-8.0, 8.0, 0.1, dtype='float32')  # 输入  
x_input.stop_gradient = False  # 允许梯度计算  
y_output = paddle.nn.functional.relu(x_input)  # 输出  # 绘制图像  
plt.plot(x_input.numpy(), y_output.numpy())  
plt.show()

relu

  1. Leaky ReLU 函数
    Leaky ReLU ( x ) = { x if  x ≥ 0 α x if  x < 0 \text{Leaky ReLU}(x) = \begin{cases} x & \text{if } x \geq 0 \\ \alpha x & \text{if } x < 0 \end{cases} Leaky ReLU(x)={xαxif x0if x<0
    • 优点:解决 ReLU 函数的神经元“死亡”问题。
    • 缺点:引入了一个需要调节的参数 α \alpha α
# 测试Leaky ReLU函数  
x_input = paddle.arange(-8.0, 8.0, 0.1, dtype='float32')  # 输入  
x_input.stop_gradient = False  # 允许梯度计算  
y_output = paddle.nn.functional.leaky_relu(x_input, negative_slope=0.01)  # 输出  # 绘制图像  
plt.plot(x_input.numpy(), y_output.numpy())  
plt.show()

leaky

  1. Softmax 函数
    Softmax ( x i ) = e x i ∑ j e x j \text{Softmax}(x_i) = \frac{e^{x_i}}{\sum_{j} e^{x_j}} Softmax(xi)=jexjexi
    • 优点:常用于分类问题的输出层,将输入映射为概率分布。
    • 缺点:计算开销较大,容易出现数值不稳定问题。
# 测试Softmax函数  
x_input = paddle.randn((1, 10), dtype=paddle.float32)  # 输入  
x_input.stop_gradient = False  # 允许梯度计算  
y_output = paddle.nn.functional.softmax(x_input)  # 输出  
x_input, y_output
(Tensor(shape=[1, 10], dtype=float32, place=Place(gpu:0), stop_gradient=False,[[ 0.77194822,  0.51511782, -0.10991125,  1.85037136,  1.80251789,1.33102489, -1.37035322,  1.50795293, -1.83983290, -0.36562130]]),Tensor(shape=[1, 10], dtype=float32, place=Place(gpu:0), stop_gradient=False,[[0.08144495, 0.06299762, 0.03371922, 0.23945138, 0.22826263, 0.14245182,0.00956036, 0.17002270, 0.00597836, 0.02611103]]))
激活函数的选择
  • 隐藏层:通常选择 ReLU 或其变种(如 Leaky ReLU、Parametric ReLU)作为隐藏层的激活函数,因为它们能有效缓解梯度消失问题。
  • 输出层:根据具体任务选择合适的激活函数。
    • 分类问题:使用 softmax 函数将输出映射为概率分布。
    • 回归问题:使用线性函数或没有激活函数。
    • 二分类问题:使用 sigmoid 函数。

手动实现多层感知机

接下来,我们将手动设计一个多层感知机模型,并实现前向传播和反向传播算法。我们利用面向对象编程的方法,结合深度学习库进行设计。

# 手动实现一个三层感知机模型,并实现前向传播和反向传播算法
import paddle.nn as nn  
import paddle.nn.functional as F  class Perceptron(nn.Layer):  def __init__(self, input_size, output_size, hidden_size=10):  super(Perceptron, self).__init__()  # 初始化权重和偏置  self.W1 = self.create_parameter(shape=[input_size, hidden_size], default_initializer=nn.initializer.Normal())  self.b1 = self.create_parameter(shape=[hidden_size], default_initializer=nn.initializer.Normal())  self.W2 = self.create_parameter(shape=[hidden_size, output_size], default_initializer=nn.initializer.Normal())  self.b2 = self.create_parameter(shape=[output_size], default_initializer=nn.initializer.Normal())  def forward(self, x):  # 前向传播  x = paddle.matmul(x, self.W1) + self.b1  x = F.relu(x)  # 激活函数  x = paddle.matmul(x, self.W2) + self.b2  return x

接下来让我们测试一下该模型的输入输出

# 检查是否有可用的GPU设备,并选择设备  
device = 'gpu' if paddle.is_compiled_with_cuda() else 'cpu'  
paddle.set_device(device)  # 创建随机的输入数据  
x_input = paddle.randn([1, 10])  # 实例化模型  
model = Perceptron(input_size=10, output_size=1)  # 前向传播  
y_output = model(x_input)  # 打印输入、输出及其形状  
print(x_input, y_output, x_input.shape, y_output.shape)
Tensor(shape=[1, 10], dtype=float32, place=Place(gpu:0), stop_gradient=True,[[-0.39587662, -1.33803356, -0.19662718, -0.33600944, -1.95559239,-0.94301635, -0.60298145,  0.75455868, -0.01416266, -3.05695415]]) Tensor(shape=[1, 1], dtype=float32, place=Place(gpu:0), stop_gradient=False,[[8.06220722]]) [1, 10] [1, 1]

接下来,我们导入一个California housing数据,用于训练测试多层感知机

from sklearn.model_selection import train_test_split  
from sklearn import datasets  
# 加载California housing数据集  
California = datasets.fetch_california_housing()
X = paddle.Tensor(California.data, dtype=paddle.float32)  
y = paddle.Tensor(California.target, dtype=paddle.float32)  
from sklearn.model_selection import train_test_split  
from paddle.io import Dataset, DataLoader class CustomDataset(Dataset):  def __init__(self, features, labels):  self.features = features  self.labels = labels  def __len__(self):  return len(self.labels)  def __getitem__(self, idx):  return self.features[idx], self.labels[idx]  def create_data_loaders(features, labels, batch_size=32, test_size=0.2, random_state=42):  # 划分数据集  X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=test_size, random_state=random_state)  # 创建Dataset对象  train_dataset = CustomDataset(X_train, y_train)  test_dataset = CustomDataset(X_test, y_test)  # 创建DataLoader对象  train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size, shuffle=True)  test_loader = DataLoader(dataset=test_dataset, batch_size=batch_size, shuffle=True)  return train_loader, test_loader  train_loader, test_loader = create_data_loaders(X, y, batch_size=64)
# 实例化模型  
model = Perceptron(input_size=8, output_size=1)  # 定义损失函数  
criterion = paddle.nn.MSELoss()  # 定义优化器  
optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.001)  num_epochs = 100  # 定义训练轮数  for epoch in range(num_epochs):  for batch_id, (inputs, labels) in enumerate(train_loader()):  # 前向传播  inputs = inputs.astype('float32')labels = labels.astype('float32')outputs = model(inputs)  labels = paddle.reshape(labels, shape=[-1, 1])  # 调整标签形状以匹配输出  loss = criterion(outputs, labels)  # 计算损失  # 反向传播和优化  loss.backward()  # 反向传播  optimizer.step()  # 更新权重  optimizer.clear_grad()  # 梯度清零,PaddlePaddle中在optimizer.step()之后需要清零梯度  if (epoch + 1) % 10 == 0:  # 每10轮输出一次损失  print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.numpy():.4f}')  # 进行测试  
model.eval()  # 设置模型为评估模式  
for batch_id, (inputs, labels) in enumerate(test_loader()):  inputs = inputs.astype('float32')labels = labels.astype('float32')outputs = model(inputs)  labels = paddle.reshape(labels, shape=[-1, 1])  # 调整标签形状以匹配输出  loss = criterion(outputs, labels)  # 计算损失  # 输出损失  print(f'Test Loss: {loss.numpy():.4f}')  break  # 假设我们只展示第一批测试数据的损失
Epoch [100/100], Loss: 0.6896
Test Loss: 0.5361

从上述过程中可以看到损失在不断减小,这证明模型在不断优化。然而观察X数据不难发现,X各维度之间的数值范围差异较大,这可能会导致模型在训练过程中收敛速度过慢。因此,我们可以对数据进行预处理,将数据缩放到一个较小的范围内。

import numpy as np  class Preprocessor:  def __init__(self):  self.min_values = None  self.scale_factors = None  def normalize(self, data):  """  对输入数据进行归一化处理。  data: numpy数组或类似结构,其中每一列是一个特征。  """  # 确保输入是numpy数组  data = np.asarray(data)  # 检查是否已经拟合过数据,如果没有,则先拟合  if self.min_values is None or self.scale_factors is None:  self.fit(data)  # 对数据进行归一化处理  normalized_data = (data - self.min_values) * self.scale_factors  return normalized_data  def denormalize(self, normalized_data):  """  对归一化后的数据进行反归一化处理。  normalized_data: 已经归一化处理的数据。  """  # 确保输入是numpy数组  normalized_data = np.asarray(normalized_data)  # 反归一化数据  original_data = normalized_data / self.scale_factors + self.min_values  return original_data  def fit(self, data):  """  计算每个特征的最小值和比例因子,用于后续的归一化和反归一化。  data: numpy数组或类似结构,其中每一列是一个特征。  """  # 确保输入是numpy数组  data = np.asarray(data)  # 计算每个特征(列)的最小值  self.min_values = np.min(data, axis=0)  # 计算每个特征(列)的比例因子  ranges = np.max(data, axis=0) - self.min_values  # 避免除以零错误,如果范围是零,则设置为1  self.scale_factors = np.where(ranges == 0, 1, 1.0 / ranges)  
data_all = np.concatenate((X.numpy(), y.reshape((-1, 1)).numpy()), axis=1)
# 这样,我们在data_all中,前8列是特征量,最后一列是目标变量
preprocessor = Preprocessor()
# 归一化
data_all_normalized = preprocessor.normalize(data_all)
train_loader, test_loader = create_data_loaders(data_all_normalized[:, :8], data_all_normalized[:, 8:], batch_size=256) # 划分数据集

再次进行训练

# 实例化模型  
model = Perceptron(input_size=8, output_size=1)  # 定义损失函数  
criterion = paddle.nn.MSELoss()  # 定义优化器  
optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.001)  num_epochs = 100  # 定义训练轮数  for epoch in range(num_epochs):  for batch_id, (inputs, labels) in enumerate(train_loader()):  # 前向传播  inputs = inputs.astype('float32')labels = labels.astype('float32')outputs = model(inputs)  labels = paddle.reshape(labels, shape=[-1, 1])  # 调整标签形状以匹配输出  loss = criterion(outputs, labels)  # 计算损失  # 反向传播和优化  loss.backward()  # 反向传播  optimizer.step()  # 更新权重  optimizer.clear_grad()  # 梯度清零,PaddlePaddle中在optimizer.step()之后需要清零梯度  if (epoch + 1) % 10 == 0:  # 每10轮输出一次损失  print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.numpy():.4f}')  
Epoch [100/100], Loss: 0.0142
# 在测试集上反归一化后计算损失值
model.eval()  # 设置模型为评估模式  for inputs, labels in test_loader():  inputs = inputs.astype('float32')labels = labels.astype('float32')outputs = model(inputs)  # 反归一化前的拼接操作  combined_outputs = paddle.concat([inputs, outputs], axis=1)  combined_labels = paddle.concat([inputs, labels], axis=1)  # 将Paddle Tensor转换为NumPy数组以进行反归一化  combined_outputs_np = combined_outputs.numpy()  combined_labels_np = combined_labels.numpy()  # 反归一化  denorm_outputs = preprocessor.denormalize(combined_outputs_np)  denorm_labels = preprocessor.denormalize(combined_labels_np)  # 截取反归一化后的预测值和真实值(假设我们感兴趣的是从第9列开始的数据)  denorm_outputs = denorm_outputs[:, 8:]  denorm_labels = denorm_labels[:, 8:]  # 将NumPy数组转回Paddle Tensor  outputs_tensor = paddle.to_tensor(denorm_outputs, dtype='float32')  labels_tensor = paddle.to_tensor(denorm_labels, dtype='float32')  # 计算损失  loss = criterion(outputs_tensor, labels_tensor)  # 输出损失  print(f'Test Loss: {loss.numpy():.4f}')  break  # 假设我们只展示第一批测试数据的损失
Test Loss: 0.6538

可见,当进行数据归一化操作后,在测试集上计算损失值时,我们能够得到一个差不多的结果。

多层感知机的简洁实现

接下来,我们将使用深度学习库来实现一个多层感知机(MLP)。

class MLP(nn.Layer):  def __init__(self, input_size, output_size):  super(MLP, self).__init__()  self.fc1 = nn.Linear(in_features=input_size, out_features=64)  # 第一个全连接层  self.relu = nn.ReLU()  # 激活函数  self.fc2 = nn.Linear(in_features=64, out_features=32)  # 第二个全连接层  self.fc3 = nn.Linear(in_features=32, out_features=output_size)  # 输出层  def forward(self, x):  out = self.fc1(x)  out = self.relu(out)  out = self.fc2(out)  out = self.relu(out)  out = self.fc3(out)  return out
# 进行训练
model = MLP(input_size=8, output_size=1).to(device)  # 实例化模型# 定义损失函数  
criterion = paddle.nn.MSELoss()  # 定义优化器  
optimizer = paddle.optimizer.Adam(parameters=model.parameters(), learning_rate=0.001)  num_epochs = 100  # 定义训练轮数  for epoch in range(num_epochs):  for batch_id, (inputs, labels) in enumerate(train_loader()):  # 前向传播  inputs = inputs.astype('float32')labels = labels.astype('float32')outputs = model(inputs)  labels = paddle.reshape(labels, shape=[-1, 1])  # 调整标签形状以匹配输出  loss = criterion(outputs, labels)  # 计算损失  # 反向传播和优化  loss.backward()  # 反向传播  optimizer.step()  # 更新权重  optimizer.clear_grad()  # 梯度清零,PaddlePaddle中在optimizer.step()之后需要清零梯度  if (epoch + 1) % 10 == 0:  # 每10轮输出一次损失  print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.numpy():.4f}')  # 进行测试  
# 在测试集上反归一化后计算损失值
model.eval()  # 设置模型为评估模式  for inputs, labels in test_loader():  inputs = inputs.astype('float32')labels = labels.astype('float32')outputs = model(inputs)  # 反归一化前的拼接操作  combined_outputs = paddle.concat([inputs, outputs], axis=1)  combined_labels = paddle.concat([inputs, labels], axis=1)  # 将Paddle Tensor转换为NumPy数组以进行反归一化  combined_outputs_np = combined_outputs.numpy()  combined_labels_np = combined_labels.numpy()  # 反归一化  denorm_outputs = preprocessor.denormalize(combined_outputs_np)  denorm_labels = preprocessor.denormalize(combined_labels_np)  # 截取反归一化后的预测值和真实值(假设我们感兴趣的是从第9列开始的数据)  denorm_outputs = denorm_outputs[:, 8:]  denorm_labels = denorm_labels[:, 8:]  # 将NumPy数组转回Paddle Tensor  outputs_tensor = paddle.to_tensor(denorm_outputs, dtype='float32')  labels_tensor = paddle.to_tensor(denorm_labels, dtype='float32')  # 计算损失  loss = criterion(outputs_tensor, labels_tensor)  # 输出损失  print(f'Test Loss: {loss.numpy():.4f}')  break  # 假设我们只展示第一批测试数据的损失
Epoch [100/100], Loss: 0.0111
Test Loss: 0.3320

可以看到,该模型在测试集上具有较好的精度。

如何查看模型中各个层的参数?

# 输出模型参数
# 假设model是一个已经定义好的PaddlePaddle模型  
for name, layer in model.named_sublayers():  for param in layer.parameters():  # 在PaddlePaddle中,参数名通常是通过 layer.name + 参数名 来获取的  # 例如:线性层的权重可能被命名为 "linear_0.w_0"  full_param_name = f"{name}.{param.name}"  print(full_param_name, param.shape, param.numpy())
fc1.linear_3.w_0 [8, 64] [[ 3.13081950e-01  2.06018716e-01 -2.03244463e-01  6.62552845e-031.20794969e-02 -1.63710177e-01 -7.88584426e-02 -1.71072856e-01-2.38272175e-01 -1.40343830e-01 -3.40595514e-01 -1.27847895e-01-8.12689662e-02 -1.93796322e-01 -1.73967615e-01 -6.09782934e-02-2.30334118e-01  5.17311767e-02  1.49296045e-01  1.77590698e-012.87044793e-01  3.24724615e-01 -9.37301572e-03  2.07839161e-022.03638270e-01 -2.86146969e-01  1.73401520e-01  2.73310632e-01-1.29703968e-03 -2.08033428e-01 -2.79000718e-02  2.02144414e-018.92829448e-02  2.35799953e-01 -1.24874398e-01 -2.52885759e-01-1.20067850e-01  1.37583837e-01  3.11312914e-01  2.81481184e-02-5.56637207e-03  3.96346040e-02 -9.06345099e-02  3.16798061e-011.95969284e-01  1.22597426e-01 -2.12079436e-01 -1.10605480e-022.52932459e-01  2.94231102e-02 -7.79357785e-03 -1.04727827e-011.52468294e-01 -3.32752287e-01 -3.68948251e-01 -4.53656614e-029.80597511e-02 -2.06019282e-01  6.06062263e-02  3.22720438e-01-1.39198959e-01  1.09098367e-01  1.65877655e-01  3.83714810e-02][ 1.97691053e-01  2.68247962e-01  1.02182925e-01 -2.21673980e-016.71685040e-02  2.14003429e-01  7.95149729e-02 -1.43927904e-021.95485000e-02 -2.51339942e-01  7.93670043e-02  1.12638079e-01-5.38468882e-02 -3.06898467e-02  1.51379794e-01  6.22531846e-022.14708835e-01  9.80924591e-02  1.66708350e-01 -3.12378965e-02-2.03294098e-01  1.10657394e-01 -2.52982259e-01  3.22187413e-03-8.82982910e-02 -1.55200779e-01 -2.23677039e-01 -1.12245090e-01-6.63331011e-04 -9.65051353e-02  7.15597644e-02  3.07830255e-025.82662830e-03 -2.87823766e-01  2.92417437e-01  3.21345702e-021.66399077e-01  4.70230281e-02 -7.07463454e-03 -6.04915805e-029.32222903e-02 -5.92378080e-02 -1.09557621e-01  3.09029445e-02-2.38836870e-01  1.38097152e-01  3.25661036e-03 -3.17538623e-031.48152769e-01  1.04433727e-02 -1.72422007e-02  2.42527097e-019.16873887e-02 -6.48293570e-02 -1.68860570e-01 -6.40835911e-026.08525500e-02 -1.49053276e-01 -2.48240486e-01  5.74986730e-033.12685445e-02 -6.31402507e-02 -2.81727612e-01  6.12065531e-02][-4.09857005e-01  3.11477602e-01  2.69458681e-01  4.48913306e-011.18098319e-01  2.47394755e-01 -1.15581743e-01 -2.04905525e-018.42827260e-01 -1.63813263e-01  1.00870140e-01 -1.04029886e-01-2.64002960e-02 -5.50883487e-02 -1.95006967e-01 -2.73619950e-01-3.00938524e-02  1.68695450e-01  5.22577986e-02  2.13823944e-014.51764077e-01  3.49374563e-01 -5.65181017e-01 -3.87557358e-011.29004359e-01 -1.20676987e-01  5.81966043e-01  3.37479147e-032.79788673e-02 -2.01127931e-01  2.44547185e-02 -1.75951913e-01-1.52701110e-01  2.95786243e-02  5.36481179e-02  2.97037140e-024.32989985e-01 -2.68881559e-01  4.25330549e-02  1.45621091e-015.48326433e-01 -3.74135941e-01  2.69327462e-01  1.13747448e-013.42393726e-01 -7.92791024e-02  2.18861148e-01  1.63596347e-011.47850409e-01 -4.30780828e-01 -4.81581949e-02 -2.52826780e-014.90360469e-01 -2.41113584e-02  7.71145597e-02 -1.40949534e-02-3.01896352e-02 -1.34475499e-01 -1.92220926e-01 -2.49957636e-01-2.03098997e-01 -1.53841227e-01  1.32989585e-01  4.62006480e-02][ 2.65925497e-01  4.05812204e-01  2.53788888e-01  4.99203712e-01-2.75020540e-01  3.65542322e-02 -3.27302329e-02 -2.58379102e-017.17044175e-01 -2.85323590e-01 -4.86054897e-01 -1.47260606e-01-9.64693353e-02 -4.43619825e-02 -6.87486455e-02  3.30955803e-011.83765545e-01 -1.89430609e-01  2.36887589e-01  3.58756721e-015.59944008e-03 -3.37457284e-02  2.50176519e-01 -4.56583709e-013.08023691e-01 -7.37715885e-02 -1.83679652e-03  9.28729996e-02-7.18701780e-01  2.79626548e-01 -2.19838172e-01 -6.79115504e-022.52646714e-01  2.41785645e-02 -6.17026567e-01  1.08945765e-01-1.62117127e-02  2.05493614e-01 -2.45605379e-01  2.65016913e-01-2.44144589e-01  4.52748537e-01 -2.06575722e-01  4.17236686e-01-1.04198933e-01 -2.66322345e-01 -5.73289171e-02  8.69868994e-02-3.20162088e-01  6.04037166e-01 -1.37159184e-01  2.63334125e-01-9.83569175e-02 -3.48932803e-01 -8.56782496e-02  2.06245899e-016.13508761e-01  2.07591414e-01  1.90393880e-01 -5.00104487e-01-1.53477311e-01  1.80223972e-01 -1.44515052e-01 -3.93530965e-01][-2.08107382e-02 -1.04099689e-02  1.54960945e-01 -1.76455304e-01-2.76900291e-01  2.41604139e-04 -6.17245845e-02 -1.93189204e-01-1.34109721e-01 -9.80562791e-02 -5.07896505e-02  8.53389949e-023.32316190e-01  1.53314933e-01  2.63355583e-01  8.86959657e-021.02258776e-03  2.05812305e-02  3.04718852e-01  1.02881730e-01-1.97050065e-01 -3.14103186e-01 -2.95645714e-01 -4.10347618e-022.84989476e-01  1.41007662e-01 -5.29043414e-02  3.68966639e-014.19721343e-02 -2.27591306e-01 -7.85444304e-02 -3.95845734e-02-2.98132330e-01  5.92459619e-01 -1.16872571e-01  6.15054853e-02-3.56268175e-02 -2.33406723e-02 -8.01426917e-02 -6.06930912e-01-1.41250402e-01 -3.51036370e-01 -2.24154398e-01  1.02946751e-01-1.62987053e+00  3.95317942e-01  1.55391753e-01 -1.58332791e-021.95650697e-01  7.13705143e-04  3.25329900e-01  1.07448131e-013.67635749e-02 -1.15112327e-01  8.02160278e-02  7.15531111e-025.10841250e-01 -1.32755637e-02  5.78131527e-02  2.79938608e-011.96959719e-01 -1.49558550e-02  3.00721645e-01  1.92038730e-01][-1.41917720e-01 -8.23766112e-01  3.62229139e-01 -4.03780222e-01-2.69680589e-01  5.43978333e-01  1.13129258e-01 -2.34977201e-013.57693760e-03 -2.98992321e-02  3.95094931e-01  1.11738533e-017.97432438e-02 -3.33442068e+00  2.30269492e-01 -7.64713943e-01-3.62472677e+00  7.77017295e-01 -2.42613745e+00 -1.50677538e+00-1.81879580e+00  9.88062397e-02  6.39276326e-01  4.79470283e-01-4.57693189e-01  1.07487750e+00 -1.29751253e+00 -8.10215354e-011.42558360e+00 -4.01732302e+00  4.02323753e-01  3.82710427e-01-3.57001638e+00  1.59708217e-01  1.28399014e+00  4.95734781e-01-5.63715808e-02 -3.56859064e+00  9.86382723e-01 -9.85695496e-02-7.60960162e-01 -9.98046935e-01  2.64710575e-01  1.63424224e-01-5.36435902e-01  6.28703833e-01 -1.64718166e-01  2.44663283e-011.47745657e+00 -4.11281919e+00 -7.97118247e-02 -1.20846283e+005.36247194e-01  1.03536451e+00  6.48276210e-01  3.26947302e-01-6.36863649e-01  2.36443996e-01 -1.75268464e-02  9.11053002e-011.20773637e+00 -2.47064066e+00  1.39027083e+00  3.95809710e-01][-1.61872298e-01 -4.73983921e-02  6.85898662e-02  1.39827654e-01-2.81924009e-01  1.64999783e-01  5.07304221e-02 -7.57065322e-031.31751299e-02 -9.22666211e-03 -2.24459730e-03 -1.60971448e-013.60914260e-01 -5.30816376e-01 -7.19735026e-01 -2.70165414e-01-6.34882301e-02  2.39850268e-01 -2.85788506e-01 -1.95005029e-01-3.71909924e-02  1.26119405e-01  2.35527605e-01 -4.28029150e-01-1.86404482e-01  3.03764254e-01  1.68191209e-01  1.67935163e-01-4.90795523e-01  1.00804202e-01  2.96638042e-01  1.71004266e-01-7.12542892e-01 -1.22327924e-01 -6.40762523e-02  1.65183812e-01-9.62912291e-03 -5.62684417e-01  1.75650641e-01 -4.40592200e-01-5.94980717e-02 -7.43935108e-02 -1.40420739e-02  1.86078727e-015.90516478e-02  1.40652969e-01  2.07288951e-01 -3.56071979e-01-4.49561607e-03 -1.98708162e-01 -6.95218593e-02  1.41653836e-01-1.28223494e-01  2.45206684e-01  5.62587902e-02  2.33916819e-01-2.45445043e-01 -1.57471791e-01  8.02162364e-02 -2.01123461e-012.75151104e-01 -7.36439764e-01  3.20188314e-01 -2.09429801e-01][-3.28922004e-01  3.21036875e-02  2.22631067e-01  3.42117250e-01-1.12229772e-01 -2.66779274e-01  2.27642640e-01  2.20010914e-021.13763986e-02 -1.42701551e-01  2.68349409e-01 -2.52015948e-01-3.80049646e-02  3.47857952e-01 -1.01911351e-01 -9.48912576e-023.98219973e-02  1.73353031e-02 -9.56577733e-02  5.20637492e-047.12814406e-02 -2.12296322e-01  2.00989246e-01  2.12521911e-01-2.45683312e-01  2.90980250e-01 -2.29072943e-01 -1.06725402e-011.87950462e-01  1.07663557e-01  1.29231781e-01  1.85621411e-012.34211445e-01  2.91730464e-01 -1.43423870e-01 -5.12544155e-011.94987655e-01  1.47930682e-01  3.78352068e-02  1.07470788e-01-9.71678831e-03  1.87591657e-01 -2.50399202e-01 -2.78749466e-01-3.17813486e-01 -1.39596477e-01 -5.97474456e-01  2.33624965e-011.88751385e-01 -2.05612496e-01 -4.54004332e-02 -1.34112224e-01-4.78985086e-02  2.64923960e-01  2.43170783e-01 -3.36947381e-01-2.53851831e-01 -1.67460501e-01 -4.19287942e-02  2.38913167e-027.84337968e-02  1.86697602e-01  2.65319109e-01  2.39701837e-01]]
fc1.linear_3.b_0 [64] [ 0.00306091 -0.02558158  0.00454489  0.03016263  0.         -0.02868694-0.03931118 -0.00534521 -0.01530213  0.         -0.03536369  0.0.02151108  0.0478561  -0.00703085  0.15141265 -0.00562203 -0.11636003-0.00471907  0.13182724  0.11320475 -0.07400184 -0.03130092 -0.037886560.20136295 -0.0085999   0.07928443  0.00637756 -0.01485943  0.07640248-0.01773066 -0.07182821  0.06375627 -0.04906173 -0.02948626  0.086062750.03898708  0.0261287  -0.11079289 -0.03349609  0.01131025  0.042847540.          0.08617433 -0.06705883 -0.00527788  0.00102845 -0.078828770.00541376  0.14916475 -0.04195836  0.03309786 -0.07463162  0.01432823-0.03576329 -0.0278319   0.128363    0.          0.16126738 -0.05268143-0.0318003   0.00874252 -0.12467249  0.00437972]
fc2.linear_4.w_0 [64, 32] [[ 0.12076211  0.29710326  0.18435588 ...  0.02129124 -0.14632721-0.0602207 ][-0.15748596 -0.13409673  0.16428283 ...  0.23962677  0.04871811-0.07986252][-0.22211064  0.08062842  0.23870611 ...  0.23241106  0.20715353-0.02460032]...[-0.06257392 -0.54390067  0.41931018 ... -0.00761214  0.137970670.13061428][-0.13696408  0.04951911  0.17234398 ...  0.02103687  0.090170390.2544022 ][ 0.00619695  0.10919159  0.02408725 ... -0.08012126 -0.119147960.09203152]]
fc2.linear_4.b_0 [32] [ 0.          0.11219498  0.03213965  0.08007792  0.01139668  0.03578897-0.00302749  0.02309586  0.06290476  0.01535221  0.         -0.04957908-0.01963384  0.02519283 -0.00790157  0.03342469  0.03499044 -0.06439646-0.01683257  0.01111472  0.0128254  -0.01295854 -0.01288085  0.0.02362463 -0.01070113 -0.04373857 -0.08965649  0.02834409  0.016859730.03126996  0.03094241]
fc3.linear_5.w_0 [32, 1] [[-0.055028  ][-1.2238208 ][ 0.33306003][ 1.0926676 ][ 0.33545637][-0.42914596][-0.23753783][-0.7103648 ][ 0.92299587][ 0.7484889 ][-0.03405289][-0.94157344][-0.3386857 ][-0.24807313][ 0.0398786 ][ 0.37158772][ 0.2504425 ][-0.6008288 ][-0.5686133 ][ 0.28256068][-0.31580347][-0.4092537 ][-0.32789922][ 0.31644353][-0.6614081 ][-0.6777225 ][-0.42700088][-0.7607351 ][ 0.07619953][ 0.44976866][ 0.26336157][ 0.14496523]]
fc3.linear_5.b_0 [1] [0.03343805]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/144265.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Visual Studio-X64汇编编写

纯64位汇编&#xff1a; includelib ucrt.lib includelib legacy_stdio_definitions.lib includelib user32.libextern printf:proc extern MessageBoxA:proc.data szFormat db "%s",0 szHello db "HelloWorld",0 szRk db "123",0.code start p…

鸿蒙生态应用

鸿蒙生态应用开发核心概念 HarmonyOS 应用&#xff1a;使用 HarmonyOS SDK 开发的应用程序&#xff0c;能够在华为终端设备 &#xff08;如&#xff1a;手机、平板等&#xff09;上运行&#xff0c;其有两种形态&#xff1a; ⚫ 传统方式的需要安装的 App。 ⚫ 轻量级&#xf…

碎纸片的自动拼接复原技术

摘要&#xff1a;破碎文件的拼接在司法物证复原、历史文献修复以及军事情报获取等领域都有着重要的应用。目前发现对碎纸片的拼接大部分由人工完成&#xff0c;准确率较高&#xff0c;但耗费大量人力财力及时间&#xff0c;效率很低。随着计算机技术的发展&#xff0c;人们试图…

java 解析excel

在Java中解析Excel文件&#xff0c;可以使用Apache POI库。以下是一个简单的例子&#xff0c;展示如何使用Apache POI读取一个Excel文件&#xff08;假设为.xlsx格式&#xff09;的内容。 首先&#xff0c;确保你的项目中包含了Apache POI的依赖。如果你使用Maven&#xff0c;…

结构体易忘点

结构体初始化 当我们去初始化一个结构体的时候&#xff0c;我们常常会按变量顺序初始化&#xff0c;但其实也可以不按顺序&#xff0c;同时也可以部分数据初始化。 结构体对齐 结构体里面的成员有一定的对齐规则&#xff0c;他不是每一个空间都存着有效数据的&#xff0c;有些…

综合时如何计算net delay?

在PR阶段&#xff0c;互连线的延迟可以通过抽取net的rc值计算得到。而在综合阶段&#xff0c;因为没有实际的布局布线&#xff0c;便无法去抽取net上的rc值。那么&#xff0c;线负载模型&#xff08;wire load model&#xff09;便派上用场了。 所谓线负载模型&#xff0c;就是…

力扣上刷题之C语言实现(数组)

一. 简介 本文记录一下力扣的逻辑题。主要是数组方面的&#xff0c;使用 C语言实现。 二. 力扣上刷题之C语言实现 1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target的那 两个 整数&#xff0c;并返回它们的数…

uni-app安装插件

1.通过插件市场安装https://ext.dcloud.net.cn 打开HBuilderX编辑器。 点击菜单栏中的“工具”->“插件安装”。 这里会看到已安装插件和安装新插件两个选项卡&#xff0c;点击安装新插件&#xff0c; 能看到一些核心插件&#xff0c;如果所需要的插件在核心插件里面有&…

PyCharm和VS Code 安装通义灵码,可本地安装包安装,解决插件安装不上问题

PyCharm和VS Code 安装通义灵码&#xff0c;可本地安装包安装&#xff0c;解决插件安装不上问题 PyCharm、VS Code 安装通义灵码介绍主要应用场景支持编程语言安装指南JetBrains IDEs 中安装指南步骤 1&#xff1a;准备工作步骤 2&#xff1a;在 JetBrains IDEs 中安装通义灵码…

【快速笔记】freeRTOS

第十八章 低功耗Tickless模式 睡眠模式:__WFI 中断唤醒 __WFE 事件唤醒 CPU CLK关闭 停止模式&#xff1a;RAM保持 中断唤醒 当 STM32F103 处于休眠模式的时候 Cortex-M3 内核停止运行&#xff0c;但是其他外设运行正常&#xff0c; 比如 NVIC、SRAM 等。 休眠模式的功耗比其他…

集运系统核心功能模块:打造高效集运仓日常管理

在跨境电商的快速发展背景下&#xff0c;集运业务作为物流环节中的重要一环&#xff0c;其效率和管理的精细化程度直接影响着客户体验和企业效益。集运系统作为提升管理效率的关键工具&#xff0c;需要具备一系列核心模块来确保业务的顺畅运行。以下是集运系统在日常管理中不可…

汇总:工业导管生产中 17种检测仪进行品质检测

定义 1&#xff09;泛指做疏导用的管子。2&#xff09;工业用导管即钻孔灌注桩水下浇灌砼导管。混凝土灌注导管用于大型的桥梁工程、中铁工程、公路工程、水电工程、高层地基的钻孔灌注桩的水下浇筑使用。 种类 工业导管种类繁多&#xff0c;主要包括钢管、铜管、不锈钢管、PVC…

golang操作mysql利器-gorm

1、傻瓜示例 GORM通过将数据库表中的数据映射到面向对象的模型中&#xff0c;简化了数据库操作&#xff0c;使得开发者可以很方便的使用代码来操作数据库&#xff0c;而无需编写SQL语句。 目前有个mysql表&#xff1a;miniprogram_orders&#xff0c;其存储了所有用户对应的订…

2023年全国研究生数学建模竞赛华为杯B题DFT类矩阵的整数分解逼近求解全过程文档及程序

2023年全国研究生数学建模竞赛华为杯 B题 DFT类矩阵的整数分解逼近 原题再现&#xff1a; 一、问题背景   离散傅里叶变换&#xff08;Discrete Fourier Transform&#xff0c;DFT&#xff09;作为一种基本工具广泛应用于工程、科学以及数学领域。例如&#xff0c;通信信号…

基于深度学习的手势识别算法(论文复现)

基于深度学习的手势识别算法&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 基于深度学习的手势识别算法&#xff08;论文复现&#xff09;概述算法原理核心逻辑效果演示使用方式 概述 本文基于论文 Simple Baselines for Human Pose Es…

Sublime Text 3 相关设置

打开设置 { “font_size”: 16, // 字体大小 “save_on_focus_lost”: true, // 自动保存 }

YOLOv8改进系列,YOLOv8 Neck结构引入BiFPN

摘要 模型效率在计算机视觉中变得越来越重要。本文系统地研究了神经网络架构设计选择用于目标检测,并提出了几项关键优化以提高效率。首先,提出了一种加权双向特征金字塔网络(BiFPN),它允许轻松快速的多尺度特征融合;其次,我们提出了一种复合缩放方法,该方法同时均匀地…

MATLAB 在数学建模中的深入应用:从基础到高级实践

目录 前言 一、MATLAB基础知识 1.1 MATLAB工作环境简介 1.1.1 命令窗口&#xff08;Command Window&#xff09; 1.1.2 工作区&#xff08;Workspace&#xff09; 1.1.3 命令历史&#xff08;Command History&#xff09; 1.1.4 编辑器&#xff08;Editor&#xff09; 1…

Electron 安装包 asar 解压定位问题实战

背景 在开发 Electron 过程中&#xff0c;我们想知道 Electron 打包的最终形态是什么样的&#xff0c;以便我们能更好的理解 Electron 打包的过程&#xff0c;以及逆向来快速追踪一些问题&#xff0c;例如下面这个报错&#xff0c;以前这类报错都是靠猜&#xff0c;现在则可以…

矿场工程车检测数据集 4900张 工程车 带标注voc yolo

矿场工程车检测数据集 数据集描述 该数据集旨在用于矿场工程车的检测和分类任务&#xff0c;涵盖了多种常见的工程车辆类型。数据集包含了大量的工程车图像及其对应的标注信息&#xff0c;可用于训练计算机视觉模型&#xff0c;以识别和定位矿场中的不同工程车辆。 数据规模 …