多层感知机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-03
   1.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-01
   2.87044793e-01  3.24724615e-01 -9.37301572e-03  2.07839161e-02
   2.03638270e-01 -2.86146969e-01  1.73401520e-01  2.73310632e-01
  -1.29703968e-03 -2.08033428e-01 -2.79000718e-02  2.02144414e-01
   8.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-01
   1.95969284e-01  1.22597426e-01 -2.12079436e-01 -1.10605480e-02
   2.52932459e-01  2.94231102e-02 -7.79357785e-03 -1.04727827e-01
   1.52468294e-01 -3.32752287e-01 -3.68948251e-01 -4.53656614e-02
   9.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-01
   6.71685040e-02  2.14003429e-01  7.95149729e-02 -1.43927904e-02
   1.95485000e-02 -2.51339942e-01  7.93670043e-02  1.12638079e-01
  -5.38468882e-02 -3.06898467e-02  1.51379794e-01  6.22531846e-02
   2.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-02
   5.82662830e-03 -2.87823766e-01  2.92417437e-01  3.21345702e-02
   1.66399077e-01  4.70230281e-02 -7.07463454e-03 -6.04915805e-02
   9.32222903e-02 -5.92378080e-02 -1.09557621e-01  3.09029445e-02
  -2.38836870e-01  1.38097152e-01  3.25661036e-03 -3.17538623e-03
   1.48152769e-01  1.04433727e-02 -1.72422007e-02  2.42527097e-01
   9.16873887e-02 -6.48293570e-02 -1.68860570e-01 -6.40835911e-02
   6.08525500e-02 -1.49053276e-01 -2.48240486e-01  5.74986730e-03
   3.12685445e-02 -6.31402507e-02 -2.81727612e-01  6.12065531e-02]
 [-4.09857005e-01  3.11477602e-01  2.69458681e-01  4.48913306e-01
   1.18098319e-01  2.47394755e-01 -1.15581743e-01 -2.04905525e-01
   8.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-01
   4.51764077e-01  3.49374563e-01 -5.65181017e-01 -3.87557358e-01
   1.29004359e-01 -1.20676987e-01  5.81966043e-01  3.37479147e-03
   2.79788673e-02 -2.01127931e-01  2.44547185e-02 -1.75951913e-01
  -1.52701110e-01  2.95786243e-02  5.36481179e-02  2.97037140e-02
   4.32989985e-01 -2.68881559e-01  4.25330549e-02  1.45621091e-01
   5.48326433e-01 -3.74135941e-01  2.69327462e-01  1.13747448e-01
   3.42393726e-01 -7.92791024e-02  2.18861148e-01  1.63596347e-01
   1.47850409e-01 -4.30780828e-01 -4.81581949e-02 -2.52826780e-01
   4.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-01
   7.17044175e-01 -2.85323590e-01 -4.86054897e-01 -1.47260606e-01
  -9.64693353e-02 -4.43619825e-02 -6.87486455e-02  3.30955803e-01
   1.83765545e-01 -1.89430609e-01  2.36887589e-01  3.58756721e-01
   5.59944008e-03 -3.37457284e-02  2.50176519e-01 -4.56583709e-01
   3.08023691e-01 -7.37715885e-02 -1.83679652e-03  9.28729996e-02
  -7.18701780e-01  2.79626548e-01 -2.19838172e-01 -6.79115504e-02
   2.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-01
   6.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-02
   3.32316190e-01  1.53314933e-01  2.63355583e-01  8.86959657e-02
   1.02258776e-03  2.05812305e-02  3.04718852e-01  1.02881730e-01
  -1.97050065e-01 -3.14103186e-01 -2.95645714e-01 -4.10347618e-02
   2.84989476e-01  1.41007662e-01 -5.29043414e-02  3.68966639e-01
   4.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-02
   1.95650697e-01  7.13705143e-04  3.25329900e-01  1.07448131e-01
   3.67635749e-02 -1.15112327e-01  8.02160278e-02  7.15531111e-02
   5.10841250e-01 -1.32755637e-02  5.78131527e-02  2.79938608e-01
   1.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-01
   3.57693760e-03 -2.98992321e-02  3.95094931e-01  1.11738533e-01
   7.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-01
   1.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-01
   1.47745657e+00 -4.11281919e+00 -7.97118247e-02 -1.20846283e+00
   5.36247194e-01  1.03536451e+00  6.48276210e-01  3.26947302e-01
  -6.36863649e-01  2.36443996e-01 -1.75268464e-02  9.11053002e-01
   1.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-03
   1.31751299e-02 -9.22666211e-03 -2.24459730e-03 -1.60971448e-01
   3.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-01
   5.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-01
   2.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-02
   1.13763986e-02 -1.42701551e-01  2.68349409e-01 -2.52015948e-01
  -3.80049646e-02  3.47857952e-01 -1.01911351e-01 -9.48912576e-02
   3.98219973e-02  1.73353031e-02 -9.56577733e-02  5.20637492e-04
   7.12814406e-02 -2.12296322e-01  2.00989246e-01  2.12521911e-01
  -2.45683312e-01  2.90980250e-01 -2.29072943e-01 -1.06725402e-01
   1.87950462e-01  1.07663557e-01  1.29231781e-01  1.85621411e-01
   2.34211445e-01  2.91730464e-01 -1.43423870e-01 -5.12544155e-01
   1.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-01
   1.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-02
   7.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.03788656
  0.20136295 -0.0085999   0.07928443  0.00637756 -0.01485943  0.07640248
 -0.01773066 -0.07182821  0.06375627 -0.04906173 -0.02948626  0.08606275
  0.03898708  0.0261287  -0.11079289 -0.03349609  0.01131025  0.04284754
  0.          0.08617433 -0.06705883 -0.00527788  0.00102845 -0.07882877
  0.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.13797067
   0.13061428]
 [-0.13696408  0.04951911  0.17234398 ...  0.02103687  0.09017039
   0.2544022 ]
 [ 0.00619695  0.10919159  0.02408725 ... -0.08012126 -0.11914796
   0.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.01685973
  0.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.mfbz.cn/a/881147.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

有关JS下隐藏的敏感信息

免责声明&#xff1a;本文仅做分享&#xff01; 目录 JavaScript 介绍 核心组成 工具 FindSomething ** 浏览器检查 ** LinkFinder URLfinder ** SuperSearchPlus ** ffuf ParasCollector waymore Packer Fuzzer JS逆向 应用&#xff1a; 小结&#xff1a; Ja…

java-----IDE(集成开发环境)

IDE&#xff08;集成开发环境&#xff09; IDE&#xff08;集成开发环境&#xff09;-IDEA IDEA 介绍 1) IDEA 全称 IntelliJ IDEA2) 在业界被公认为最好的Java开发工具3) IDEA是JetBrains 公司的产品&#xff0c;总部位于捷克的首都布拉格4) 除了支持Java开发&#xff0c;还…

54.【C语言】 字符函数和字符串函数(strncpy,strncat,strncmp函数)

和strcpy,strcat,strcmp函数对应的是strncpy,strncat,strncmp函数 8.strncpy函数 *简单使用 cplusplus的介绍 点我跳转 翻译: 函数 strncpy char * strncpy ( char * destination, const char * source, size_t num ); 从字符串中复制一些字符 复制源(source)字符串的前num个…

【专题】2024新能源企业“出海”系列之驶向中东、东南亚报告合集PDF分享(附原数据表)

原文链接&#xff1a; https://tecdat.cn/?p37698 在“双碳”目标引领下&#xff0c;中国新能源产业近年迅猛发展&#xff0c;新能源企业凭借技术革新、政策支持与市场驱动实现快速增长&#xff0c;在产业链完备、技术领先、生产效能及成本控制等方面优势显著。面对国内外环境…

MySQL中的LIMIT与ORDER BY关键字详解

前言 众所周知&#xff0c;LIMIT和ORDER BY在数据库中&#xff0c;是两个非常关键并且经常一起使用的SQL语句部分&#xff0c;它们在数据处理和分页展示方面发挥着重要作用。 今天就结合工作中遇到的实际问题&#xff0c;回顾一下这块的知识点。同时希望这篇文章可以帮助到正…

ZXing.Net:一个开源条码生成和识别器,支持二维码、条形码等

推荐一个跨平台的非常流行的条码库&#xff0c;方便我们在.Net项目集成条码扫描和生成功能。 01 项目简介 ZXing.Net是ZXing的.Net版本的开源库。支持跨多个平台工作&#xff0c;包括 Windows、Linux 和 macOS&#xff0c;以及在 .NET Core 和 .NET Framework 上运行。 解码…

【数据结构】设有一带头结点的单链表,编程将链表颠倒过来。要求不用另外的数 组或结点完成。

编程题&#xff1a; 设有一带头结点的单链表&#xff0c;编程将链表颠倒过来。要求不用另外的数 组或结点完成。 分析&#xff1a; 该算法通过维护三个指针&#xff08;prev、curr 和 next&#xff09;逐步遍历单链表&#xff0c;实现链表的逆转。在遍历过程中&#xff0c;cur…

IDEA Cody 插件实现原理

近年来&#xff0c;智能编程助手 在开发者日常工作中变得越来越重要。IDEA Cody 插件是 JetBrains 生态中一个重要的插件&#xff0c;它可以帮助开发者 快速生成代码、自动补全、并提供智能提示&#xff0c;从而大大提升开发效率。今天我们将深入探讨 Cody 插件的实现原理&…

技术成神之路:设计模式(十四)享元模式

介绍 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构性设计模式&#xff0c;旨在通过共享对象来有效地支持大量细粒度的对象。 1.定义 享元模式通过将对象状态分为内部状态&#xff08;可以共享&#xff09;和外部状态&#xff08;不可共享&#xff09;&#xf…

AI免费UI页面生成

https://v0.dev/chat v0 - UI设计 cursor - 编写代码 参考&#xff1a;https://www.youtube.com/watch?vIyIVvAu1KZ4 界面和claude类似&#xff0c;右侧展示效果和代码 https://pagen.so/

【重学 MySQL】三十、数值类型的函数

【重学 MySQL】三十、数值类型的函数 基本函数角度与弧度互换函数三角函数指数与对数进制间的转换示例 基本函数 MySQL提供了一系列基本的数值函数&#xff0c;用于处理数学运算和数值转换。以下是一些常用的基本函数及其用法&#xff1a; 函数用法ABS(x)返回x的绝对值。SIGN…

[docker]入门

本文章主要讲述的是&#xff0c;docker基本实现原理&#xff0c;docker概念的解释&#xff0c;docker的使用场景以及docker打包与部署的应用。 文章中docker所运行的系统&#xff1a;CentOS Linux release 7.9.2009 (Core) 目录 docker是什么&#xff0c;什么时候需要去使用 …

【Mysql-索引总结】

文章目录 什么是索引索引类型索引的数据结构Hash索引有序数组二叉搜索树平衡二叉树B树B索引 索引使用规则索引失效的情况如何选择正确的列进行索引&#xff1f; 什么是索引 索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构&#xff0c;它是某个表中…

无人机黑飞打击技术详解

随着无人机技术的普及&#xff0c;无人机“黑飞”&#xff08;未经授权或违反规定的飞行&#xff09;现象日益严重&#xff0c;对公共安全、隐私保护及重要设施安全构成了严重威胁。为有效应对这一挑战&#xff0c;各国政府和安全机构纷纷研发并部署了一系列无人机黑飞打击技术…

基于STM32的温度、电流、电压检测proteus仿真系统(OLED、DHT11、继电器、电机)

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STM32F103C8T6 采用DHT11读取温度、滑动变阻器模拟读取电流、电压。 通过OLED屏幕显示,设置电流阈值为80,电流小阈值为50,电压阈值为60,温度阈值为30 随便哪个超过预祝,则继电器切断,LE…

战神5/战神:诸神黄昏/God of War Ragnarok

版本介绍 v1.0.612.4312|容量175GB|官方简体中文|支持键盘.鼠标.手柄|赠单板学习补丁 配置要求 战神5/战神&#xff1a;诸神黄昏/God of War Ragnarok 游戏介绍 不灭的北欧传奇 由Santa Monica Studio出品、Jetpack Interactive负责PC移植的佳作《God of War Ragnark》将带您…

网络设备登录——《路由与交换技术》实验报告

目录 一、实验目的 二、实验设备和环境 三、实验记录 1.通过 Console 登录 步骤1:连接配置电缆。 步骤2:启动PC,运行超级终端。 步骤3:进入Console 配置界面 2.通过 Telnet 登录 步骤1:通过 Console 接口配置 Telnet 用户。 步骤2:配置 super 口令 步骤3:配置登录欢迎…

Java之封装

文章目录 1.封装1.1 什么是封装1.2 访问限定符1.3 包1.3.1 什么是包1.3.2 导包1.3.3 自定义包 2. static2.1 static 修饰成员变量2.2 static 修饰成员方法2.3 static成员变量初始化 3. 代码快3.1 普通代码块3.2 实例代码块3.3 静态代码块 4. 对象的打印 1.封装 1.1 什么是封装…

ubuntu安装emqx

目录 1.预先下载好emqx压缩包 2.使用tar命令解压 3.进入bin目录 5.放开访问端口18083 6.从通过ip地址访问emqx后台 7.默认用户名密码为admin/public 8.登录后台 9.资源包绑定在此博文可自取 1.预先下载好emqx压缩包 2.使用tar命令解压 sudo tar -xzvf emqx-5.0.8-el8-…

monorepo基础搭建教程(从0到1 pnpm+monorepo+vue)

monorepo 前言1、搭建空项目并配置pnpm-workspace.yamlpnpm initpnpm-workspace.yaml 2.配置packages测试文件配置相关内容 3.引入packages内容至公共package.json4.创建测试项目&#xff0c;并引入公共包结语 前言 有个项目要引入一个第三方库&#xff0c;但是第三方库下载下…