(四)动手实现多层感知机:深度学习中的非线性建模实战

news2025/6/5 22:28:17

1 多层感知机(MLP)

多层感知机(Multilayer Perceptron, MLP)是一种前馈神经网络,包含一个或多个隐藏层。它能够学习数据中的非线性关系,广泛应用于分类和回归任务。MLP的每个神经元对输入信号进行加权求和,然后通过激活函数引入非线性。

1.1 架构

MLP通常包含以下几部分:

  1. 输入层:接收输入特征。
  2. 隐藏层:一个或多个,每一层包含多个神经元。
  3. 输出层:产生最终的预测结果。

每层的输出作为下一层的输入。隐藏层的神经元通过激活函数引入非线性,使得模型能够学习复杂的模式。

1.2 激活函数

激活函数是神经元的输出函数,用于引入非线性。常见的激活函数包括:

  • ReLU(Rectified Linear Unit) ( ReLU ( x ) = max ⁡ ( 0 , x ) ) ( \text{ReLU}(x) = \max(0, x) ) (ReLU(x)=max(0,x))
  • Sigmoid ( Sigmoid ( x ) = 1 1 + e − x ) ( \text{Sigmoid}(x) = \frac{1}{1 + e^{-x}} ) (Sigmoid(x)=1+ex1)
  • Tanh ( Tanh ( x ) = e x − e − x e x + e − x ) ( \text{Tanh}(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} ) (Tanh(x)=ex+exexex)

激活函数的选择对模型的性能有重要影响。

1.3 训练过程

MLP的训练过程包括以下几个步骤:

  1. 前向传播:从输入层开始,逐层计算输出。
  2. 计算损失:通过损失函数(如交叉熵损失或均方误差损失)计算预测值与真实值之间的差异。
  3. 反向传播:计算损失函数关于每个参数的梯度。
  4. 参数更新:使用优化算法(如梯度下降法)更新模型参数。
1.4 应用场景

MLP可以应用于各种分类和回归任务,例如:

  • 图像分类:将图像的像素值作为输入,预测图像的类别。
  • 语音识别:将语音信号的特征作为输入,预测语音内容。
  • 自然语言处理:将文本的向量表示作为输入,预测文本的情感倾向等。
1.5 示例代码

以下是一个简单的MLP实现,使用PyTorch框架。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset

# 模拟一些简单的数据
X = torch.randn(100, 2)
y = torch.randint(0, 2, (100,))

# 定义MLP模型
class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.layers = nn.Sequential(
            nn.Linear(2, 10),  # 输入层到隐藏层
            nn.ReLU(),         # 激活函数
            nn.Linear(10, 2)   # 隐藏层到输出层
        )
    
    def forward(self, x):
        return self.layers(x)

# 实例化模型
model = MLP()

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

# 数据加载器
dataset = TensorDataset(X, y)
loader = DataLoader(dataset, batch_size=10, shuffle=True)

# 训练模型
num_epochs = 100
for epoch in range(num_epochs):
    for inputs, targets in loader:
        # 前向传播
        outputs = model(inputs)
        loss = criterion(outputs, targets)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    if (epoch + 1) % 10 == 0:
        print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')
  • 隐藏层:隐藏层是MLP的核心,通过引入非线性激活函数,使得模型能够学习复杂的模式。
  • 激活函数:激活函数引入非线性,使得模型能够处理非线性问题。
  • 反向传播:反向传播是训练MLP的关键,通过计算损失函数的梯度,更新模型参数,最小化损失函数。
  • 优化算法:选择合适的优化算法(如SGD、Adam等)对模型的训练效果有重要影响。

通过理解多层感知机的架构和训练过程,你可以更好地应用它来解决实际问题。

2 激活函数

激活函数是神经网络中每个神经元的输出函数,用于引入非线性,使得模型能够学习复杂的模式。以下是几种常见的激活函数及其特点:

2.1. ReLU(Rectified Linear Unit)
  • 公式 ( ReLU ( x ) = max ⁡ ( 0 , x ) ) ( \text{ReLU}(x) = \max(0, x) ) (ReLU(x)=max(0,x))
  • 特点:计算简单,收敛速度快,常用于隐藏层。但存在“神经元死亡”问题(当输入为负时,梯度为零)。
  • 应用场景:广泛应用于卷积神经网络和多层感知机。
2.2. Sigmoid
  • 公式 ( Sigmoid ( x ) = 1 1 + e − x ) ( \text{Sigmoid}(x) = \frac{1}{1 + e^{-x}} ) (Sigmoid(x)=1+ex1)
  • 特点:输出范围在 (0, 1),可用于二分类问题的输出层。但容易出现梯度消失问题(当输入绝对值较大时,梯度趋近于零)。
  • 应用场景:二分类问题的输出层。
2.3. Tanh(双曲正切函数)
  • 公式 ( Tanh ( x ) = e x − e − x e x + e − x ) ( \text{Tanh}(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}} ) (Tanh(x)=ex+exexex)
  • 特点:输出范围在 (-1, 1),比 Sigmoid 收敛更快,但同样存在梯度消失问题。
  • 应用场景:隐藏层。
2.4. Leaky ReLU
  • 公式 ( Leaky ReLU ( x ) = max ⁡ ( 0.01 x , x ) ) ( \text{Leaky ReLU}(x) = \max(0.01x, x) ) (Leaky ReLU(x)=max(0.01x,x))
  • 特点:解决了 ReLU 的“神经元死亡”问题,通过引入一个较小的斜率(如 0.01)来处理负值输入。
  • 应用场景:需要避免神经元死亡问题的场景。
2.5. ELU(Exponential Linear Unit)
  • 公式 ( ELU ( x ) = { x , x > 0 α ( e x − 1 ) , x ≤ 0 ) ( \text{ELU}(x) = \begin{cases} x, & x > 0 \\ \alpha(e^x - 1), & x \leq 0 \end{cases} ) (ELU(x)={x,α(ex1),x>0x0)
  • 特点:在负值区域引入非线性,有助于缓解梯度消失问题。参数 α \alpha α通常设置为 1.0。
  • 应用场景:需要更好的收敛性能的场景。
2.6. Swish
  • 公式 ( Swish ( x ) = x ⋅ Sigmoid ( x ) ) ( \text{Swish}(x) = x \cdot \text{Sigmoid}(x) ) (Swish(x)=xSigmoid(x))
  • 特点:由 Google 提出,具有平滑的非线性特性,通常比 ReLU 表现更好。
  • 应用场景:各种深度学习任务。
2.7 激活函数的比较
激活函数优点缺点应用场景
ReLU计算简单,收敛快神经元死亡问题隐藏层
Sigmoid输出范围固定梯度消失问题二分类输出层
Tanh输出范围对称梯度消失问题隐藏层
Leaky ReLU解决神经元死亡问题需要调整斜率参数需要避免神经元死亡的场景
ELU缓解梯度消失问题计算稍复杂需要更好收敛性能的场景
Swish平滑非线性,性能好计算稍复杂各种深度学习任务
2.8 代码示例

以下是使用PyTorch实现几种常见激活函数的示例:

import torch
import torch.nn as nn
import matplotlib.pyplot as plt

# 定义输入数据
x = torch.linspace(-5, 5, 100)

# 定义激活函数
relu = nn.ReLU()
sigmoid = nn.Sigmoid()
tanh = nn.Tanh()
leaky_relu = nn.LeakyReLU(0.01)
elu = nn.ELU()
swish = nn.SiLU()  # PyTorch 1.7+ 支持 Swish

# 计算输出
y_relu = relu(x)
y_sigmoid = sigmoid(x)
y_tanh = tanh(x)
y_leaky_relu = leaky_relu(x)
y_elu = elu(x)
y_swish = swish(x)

# 绘制图像
plt.figure(figsize=(12, 8))

plt.subplot(2, 3, 1)
plt.plot(x.numpy(), y_relu.numpy(), label='ReLU')
plt.xlabel('x')
plt.ylabel('y')
plt.title('ReLU')
plt.grid(True)

plt.subplot(2, 3, 2)
plt.plot(x.numpy(), y_sigmoid.numpy(), label='Sigmoid', color='orange')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Sigmoid')
plt.grid(True)

plt.subplot(2, 3, 3)
plt.plot(x.numpy(), y_tanh.numpy(), label='Tanh', color='green')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Tanh')
plt.grid(True)

plt.subplot(2, 3, 4)
plt.plot(x.numpy(), y_leaky_relu.numpy(), label='Leaky ReLU', color='red')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Leaky ReLU')
plt.grid(True)

plt.subplot(2, 3, 5)
plt.plot(x.numpy(), y_elu.numpy(), label='ELU', color='purple')
plt.xlabel('x')
plt.ylabel('y')
plt.title('ELU')
plt.grid(True)

plt.subplot(2, 3, 6)
plt.plot(x.numpy(), y_swish.numpy(), label='Swish', color='brown')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Swish')
plt.grid(True)

plt.tight_layout()
plt.show()
  • 非线性:激活函数的主要作用是引入非线性,使得神经网络能够学习数据中的复杂模式。
  • 梯度消失:Sigmoid 和 Tanh 等激活函数在输入绝对值较大时,梯度趋近于零,导致训练过程变慢。
  • 选择合适的激活函数:根据具体任务和网络结构选择合适的激活函数,可以显著提高模型的性能和训练效率。

通过理解不同激活函数的特点和应用场景,你可以更好地选择和应用它们来构建高效的神经网络模型。

3 多层感知机的从零开始实现

使用Python和PyTorch从零开始实现一个多层感知机(MLP)。我们将逐步构建模型,包括数据准备、模型定义、训练和评估。

3.1 数据准备

首先,我们需要准备一些用于训练的数据。这里我们使用一个简单的二维数据集,目标是将其分类为两个类别。

import numpy as np
import matplotlib.pyplot as plt

# 生成数据集
np.random.seed(42)
X = np.random.rand(100, 2)  # 100个样本,每个样本2个特征
y = (X[:, 0] + X[:, 1] > 1).astype(np.int64)  # 简单的分类规则

# 绘制数据
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='red', label='Class 0')
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='blue', label='Class 1')
plt.xlabel('X1')
plt.ylabel('X2')
plt.title('Generated Data')
plt.legend()
plt.show()
3.2 定义模型

接下来,我们定义一个多层感知机模型。我们将实现一个包含一个隐藏层的MLP,隐藏层使用ReLU激活函数。

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import TensorDataset, DataLoader

# 转换为张量
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.long)

# 创建数据集和数据加载器
dataset = TensorDataset(X_tensor, y_tensor)
data_loader = DataLoader(dataset, batch_size=10, shuffle=True)

# 定义模型
class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.hidden = nn.Linear(2, 4)  # 输入特征维度为2,隐藏层维度为4
        self.output = nn.Linear(4, 2)  # 隐藏层维度为4,输出维度为2

    def forward(self, x):
        x = torch.relu(self.hidden(x))  # 使用ReLU激活函数
        x = self.output(x)
        return x

model = MLP()
3.3 定义损失函数和优化器

我们使用交叉熵损失函数和随机梯度下降优化器来训练模型。

# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.1)
3.4 训练模型

现在,我们开始训练模型。我们将迭代多个周期,并在每个周期中执行前向传播、计算损失、执行反向传播和更新参数。

# 训练模型
num_epochs = 100
losses = []

for epoch in range(num_epochs):
    for X_batch, y_batch in data_loader:
        # 前向传播
        y_pred = model(X_batch)
        loss = criterion(y_pred, y_batch)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    losses.append(loss.item())
    if (epoch + 1) % 10 == 0:
        print(f'Epoch {epoch + 1}, Loss: {loss.item():.4f}')

# 绘制损失曲线
plt.plot(losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Loss Curve')
plt.show()
3.5 模型评估

训练完成后,我们评估模型的性能,计算准确率。

# 计算准确率
model.eval()  # 设置为评估模式
with torch.no_grad():
    y_pred = model(X_tensor)
    _, predicted = torch.max(y_pred, 1)
    accuracy = (predicted == y_tensor).sum().item() / len(y_tensor)

print(f'Accuracy: {accuracy * 100:.2f}%')
3.6 可视化决策边界

为了更好地理解模型的分类效果,我们可以可视化决策边界。

# 可视化决策边界
h = .02  # 网格步长
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

# 计算模型预测
Z = model(torch.tensor(np.c_[xx.ravel(), yy.ravel()], dtype=torch.float32))
Z = torch.max(Z, 1)[1].numpy().reshape(xx.shape)

# 绘制决策边界
plt.contourf(xx, yy, Z, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o')
plt.xlabel('X1')
plt.ylabel('X2')
plt.title('Decision Boundary')
plt.show()
3.7 完整代码

将上述代码整合在一起,可以直接运行以下代码来实现多层感知机模型的从零开始实现:

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import TensorDataset, DataLoader
import matplotlib.pyplot as plt

# 生成数据集
np.random.seed(42)
X = np.random.rand(100, 2)  # 100个样本,每个样本2个特征
y = (X[:, 0] + X[:, 1] > 1).astype(np.int64)  # 简单的分类规则

# 转换为张量
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.long)

# 创建数据集和数据加载器
dataset = TensorDataset(X_tensor, y_tensor)
data_loader = DataLoader(dataset, batch_size=10, shuffle=True)

# 定义模型
class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.hidden = nn.Linear(2, 4)  # 输入特征维度为2,隐藏层维度为4
        self.output = nn.Linear(4, 2)  # 隐藏层维度为4,输出维度为2

    def forward(self, x):
        x = torch.relu(self.hidden(x))  # 使用ReLU激活函数
        x = self.output(x)
        return x

model = MLP()

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

# 训练模型
num_epochs = 100
losses = []

for epoch in range(num_epochs):
    for X_batch, y_batch in data_loader:
        # 前向传播
        y_pred = model(X_batch)
        loss = criterion(y_pred, y_batch)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    losses.append(loss.item())
    if (epoch + 1) % 10 == 0:
        print(f'Epoch {epoch + 1}, Loss: {loss.item():.4f}')

# 绘制损失曲线
plt.plot(losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Loss Curve')
plt.show()

# 计算准确率
model.eval()  # 设置为评估模式
with torch.no_grad():
    y_pred = model(X_tensor)
    _, predicted = torch.max(y_pred, 1)
    accuracy = (predicted == y_tensor).sum().item() / len(y_tensor)

print(f'Accuracy: {accuracy * 100:.2f}%')

# 可视化决策边界
h = .02  # 网格步长
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

# 计算模型预测
Z = model(torch.tensor(np.c_[xx.ravel(), yy.ravel()], dtype=torch.float32))
Z = torch.max(Z, 1)[1].numpy().reshape(xx.shape)

# 绘制决策边界
plt.contourf(xx, yy, Z, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o')
plt.xlabel('X1')
plt.ylabel('X2')
plt.title('Decision Boundary')
plt.show()

4 多层感知机的简洁实现

利用 PyTorch 提供的高级 API 来构建多层感知机(MLP),这将帮助我们更加高效地实现模型,减少手动定义和管理模型细节的工作量。

4.1 构建多层感知机
4.1.1. 导入必要的库

首先,我们需要导入 PyTorch 中的相关模块,这些模块将被用于定义模型、优化器以及数据加载器等。

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
4.1.2. 定义 MLP 模型

使用 PyTorch 的 nn.Module 定义一个简单的多层感知机,包含一个隐藏层。这里我们定义一个简单的两层神经网络,隐藏层使用 ReLU 激活函数,输出层没有激活函数。

class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.fc1 = nn.Linear(784, 128)  # 输入层到隐藏层的线性变换
        self.fc2 = nn.Linear(128, 10)   # 隐藏层到输出层的线性变换

    def forward(self, x):
        x = F.relu(self.fc1(x))  # 隐藏层后应用 ReLU 激活函数
        x = self.fc2(x)
        return x
  • nn.Linear:定义了一个全连接层。
  • F.relu:将 ReLU 激活函数应用于隐藏层的输出。
4.1.3. 准备数据集

为了训练模型,我们需要一个数据集。这里我们使用 PyTorch 的 torchvision 库来加载 MNIST 数据集,并使用 DataLoader 将其封装为一个可迭代的数据加载器。

from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 数据转换
transform = transforms.Compose([
    transforms.ToTensor(),  # 将图像数据转换为张量
    transforms.Normalize((0.1307,), (0.3081,))  # 标准化
])

# 下载并加载训练集和测试集
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)

test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)
test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)
4.1.4. 初始化模型和优化器

创建 MLP 模型的实例,并初始化优化器。这里我们使用随机梯度下降(SGD)优化器。

model = MLP()
optimizer = optim.SGD(model.parameters(), lr=0.01)
4.1.5. 训练模型

定义一个训练函数,执行模型的训练过程。这个过程包括前向传播、损失计算、反向传播和参数更新。

def train(model, device, train_loader, optimizer, epoch):
    model.train()
    for batch_idx, (data, target) in enumerate(train_loader):
        data, target = data.view(-1, 784).to(device), target.to(device)  # 将数据展平为 784 维的向量
        optimizer.zero_grad()
        output = model(data)
        loss = F.cross_entropy(output, target)  # 计算交叉熵损失
        loss.backward()
        optimizer.step()
        if batch_idx % 100 == 0:
            print(f'Train Epoch: {epoch} [{batch_idx * len(data)}/{len(train_loader.dataset)} ({100. * batch_idx / len(train_loader):.0f}%)]\tLoss: {loss.item():.6f}')
4.1.6. 测试模型

定义一个测试函数,评估模型在测试集上的性能。

def test(model, device, test_loader):
    model.eval()
    test_loss = 0
    correct = 0
    with torch.no_grad():
        for data, target in test_loader:
            data, target = data.view(-1, 784).to(device), target.to(device)
            output = model(data)
            test_loss += F.cross_entropy(output, target, reduction='sum').item()  # 将一批的损失相加
            pred = output.argmax(dim=1, keepdim=True)  # 获得概率最大的索引
            correct += pred.eq(target.view_as(pred)).sum().item()

    test_loss /= len(test_loader.dataset)

    print(f'\nTest set: Average loss: {test_loss:.4f}, Accuracy: {correct}/{len(test_loader.dataset)} ({100. * correct / len(test_loader.dataset):.0f}%)')
4.1.7. 定义设备并开始训练

在训练之前,定义使用的设备(CPU 或 GPU),然后开始训练和测试过程。

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)

for epoch in range(1, 11):  # 进行 10 轮训练
    train(model, device, train_loader, optimizer, epoch)
    test(model, device, test_loader)
4.2 注意事项
  1. 数据预处理:数据预处理对于模型的性能至关重要。在 MNIST 数据集的例子中,我们进行了归一化处理,以提高模型的训练效率。
  2. 超参数调整:学习率、隐藏层大小、批次大小等超参数对模型的训练和测试性能有重要影响,需要根据具体任务进行调整。
  3. 模型复杂度:增加隐藏层或隐藏层神经元的数量可以提高模型的表示能力,但同时也会增加训练难度和计算成本。
  4. 过拟合和欠拟合:如果模型在训练集上表现很好,但在测试集上表现不佳,可能是过拟合;如果模型在训练集上表现也不好,可能是欠拟合。需要通过调整模型复杂度、增加数据量、使用正则化等方法来解决这些问题。

通过这种简洁的实现方式,我们可以快速地构建和训练一个基本的多层感知机模型,同时也可以方便地对模型进行扩展和优化,以适应更复杂的任务和数据集。

4.5 模型评估

评估训练后的模型性能,计算准确率:

# 计算准确率
model.eval()  # 设置为评估模式
with torch.no_grad():
    y_pred = model(X_tensor)
    _, predicted = torch.max(y_pred, 1)
    accuracy = (predicted == y_tensor).sum().item() / len(y_tensor)

print(f'Accuracy: {accuracy * 100:.2f}%')

4.6 多层感知机的应用

多层感知机可以应用于各种分类和回归任务。通过增加隐藏层和调整网络结构,可以提高模型的性能和泛化能力。

多层感知机通过引入隐藏层和非线性激活函数,能够学习数据中的复杂模式,适用于各种分类和回归任务。

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

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

相关文章

HTTP连接管理——短连接,长连接,HTTP 流水线

连接管理是一个 HTTP 的关键话题:打开和保持连接在很大程度上影响着网站和 Web 应用程序的性能。在 HTTP/1.x 里有多种模型:短连接、_长连接_和 HTTP 流水线。 下面分别来详细解释 短连接 HTTP 协议最初(0.9/1.0)是个非常简单的…

【免费】2004-2020年各省电力消费量数据

2004-2020年各省电力消费量数据 1、时间:2004-2020年 2、来源:国家统计局、统计年鉴 3、指标:行政区划代码、地区、年份、电力消费量(亿千瓦小时) 4、范围:31省 5、指标说明:电力消费量是指在一定时期内&#xff…

登录的写法,routerHook具体配置,流程

routerHook挂在在index.js/main.js下的,找不到可以去那边看一下 vuex需要做的: //创建token的sate,从本地取 let token window.localStorage.getItem(token) // 存储用户登录信息let currentUserInfo reactive({userinfo: {}}) //存根据不…

工作服/反光衣检测算法AI智能分析网关V4安全作业风险预警方案:筑牢矿山/工地/工厂等多场景安全防线

一、方案背景​ 在工地、矿山、工厂等高危作业场景,反光衣是保障人员安全的必备装备。但传统人工巡查存在效率低、易疏漏等问题,难以实现实时监管。AI智能分析网关V4基于人工智能技术,可自动识别人员着装状态,精准定位未穿反光衣…

设计模式——中介者设计模式(行为型)

摘要 文章详细介绍了中介者设计模式,这是一种行为型设计模式,通过中介者对象封装多个对象间的交互,降低系统耦合度。文中阐述了其核心角色、优缺点、适用场景,并通过类图、时序图、实现方式、实战示例等多方面进行讲解&#xff0…

MinGW-w64的安装详细步骤(c_c++的编译器gcc、g++的windows版,win10、win11真实可用)

文章目录 1、MinGW的定义2、MinGW的主要组件3、MinGW-w64下载与安装 3.1、下载解压安装地址3.2、MinGW-w64环境变量的设置 4、验证MinGW是否安装成功5、编写一段简单的代码验证下6、总结 1、MinGW的定义 MinGW(Minimalist GNU for Windows) 是一个用…

LabVIEW磁悬浮轴承传感器故障识别

针对工业高端装备中主动磁悬浮轴承(AMB)的位移传感器故障检测需求,基于 LabVIEW 平台构建了一套高精度故障识别系统。通过集成品牌硬件与 LabVIEW 的信号处理能力,实现了传感器探头故障的实时监测与精准定位,解决了传统…

多线程1(Thread)

认识线程(Thread) 在进程中,要创建一个进程和销毁一个进程所消耗的硬件和软件资源是巨大的,因此为了优化上述过程,我们引入了“线程”。 线程是系统调度的基本单位。 1)线程和进程的关系 可以认为进程包…

NVIDIA DOCA 3.0:引领AI基础设施革命的引擎简析

引言 在当今快速发展的AI时代,大规模AI模型的训练和部署对数据中心基础设施提出了前所未有的挑战。传统的CPU-centric架构已经难以满足超大规模AI工作负载对性能、效率和安全性的需求。NVIDIA于2025年4月正式发布了DOCA 3.0软件框架,这一创新性平台彻底改变了AI基础设施的设计…

小家电外贸出口新利器:WD8001低成本风扇智能控制方案全解析

低成本单节电池风扇解决方案WD8001 用途 低成本单节电池风扇解决方案WD8001用于小功率风扇供电及控制,具有三个档位调节、自动停机及锁机功能。 基本参数 充电参数:输入5V/500mA,满电4.2V,充电指示灯亮,满电后熄灭…

C++实现汉诺塔游戏用户交互

目录 一、模型调整(一)模型定义(二)模型实现1.电脑自动完成部分2.SDL图形显示2.1拿起放下盘子的函数2.2左右移动手指的函数 二、处理用户输入,进行人机分流三、总结四、源码下载 上篇文章使用C语言实现汉诺塔游戏电脑自动完成的步骤,还没有实现用户交互&…

谷歌地图手机版(Google maps)v11.152.0100安卓版 - 前端工具导航

谷歌地图(Google maps)是由谷歌官方推出的一款手机地图应用。软件功能强大,支持本地搜索查找世界各地的地址、地点和商家;支持在街景视图中查看世界各地的360度全景图;支持查找乘坐火车、公交车和地铁的路线,或者查找步行路线等 …

C++核心编程_关系运算符重载

4.5.5 关系运算符重载 作用:重载关系运算符,可以让两个自定义类型对象进行对比操作 /*#### 4.5.5 关系运算符重载 **作用:**重载关系运算符,可以让两个自定义类型对象进行对比操作 */class Person { public:Person(string name, …

T/CCSA 663-2025《医疗科研云平台技术要求》标准解读与深度分析

参考地址:https://www.doc88.com/p-30280431175529.html 引言 随着医疗信息化建设的深入推进,医疗行业正经历从"业务驱动"向"数据驱动"的转型。在这一背景下,中国通信标准化协会(CCSA)于2025年发布了T/CCSA 663-2025《医疗科研云平台技术要求》标准,并…

win11回收站中出现:查看回收站中是否有以下项: WPS云盘回收站

好久没更新了,首先祝所有大朋友、小朋友六一儿童节快乐,真的希望我们永远都不会长大呀,长大真的好累呀(•_•) 免责声明 笔者先来个免责声明吧,被网上的阴暗面吓到了 若读者参照笔者的这篇文章所执行的操作中途或后续出现的任何…

SCDN如何同时保障网站加速与DDoS防御?

在互联网时代,网站既要面对用户访问量的激增,又要抵御层出不穷的网络攻击,特别是DDoS攻击的威胁。SCDN(安全内容分发网络)作为融合加速与安全的解决方案,如何实现“加速”与“防御”的双重保障?…

项目前置知识——不定参以及设计模式

1.C语言不定参宏函数 c语言中&#xff0c;printf就是一个不定参函数&#xff0c;在使用不定参宏函数时&#xff0c;我们使用__VA_ARGS__来解析不定参&#xff1a; #include <iostream> #include <cstdarg>#define LOG(fmt/*格式*/, .../*用...表示不定参*/) prin…

04powerbi-度量值-筛选引擎CALCULATE()

1、calculate calculate 的参数分两部分&#xff0c;分别是计算器和筛选器 2、多条件calculater与表筛选 多条件有不列的多条件 相同列的多条件 3、calculatertable &#xff08;表&#xff0c;筛选条件&#xff09;表筛选 与calculate用法一样&#xff0c;可以用创建表&…

chromedriver 下载失败

问题描述 chromedriver 2.46.0 下载失败 淘宝https://registry.npmmirror.com/chromedriver/2.46/chromedriver_win32.zip无法下载 解决方法 找到可下载源 https://cdn.npmmirror.com/binaries/chromedriver/2.46/chromedriver_win32.zip &#xff0c;先将其下载到本地目录(D…

Weather app using Django - Python

我们的任务是使用 Django 创建一个 Weather 应用程序&#xff0c;让用户可以输入城市名称并查看当前天气详细信息&#xff0c;例如温度、湿度和压力。我们将通过设置一个 Django 项目&#xff0c;创建一个视图来从 OpenWeatherMap API 获取数据&#xff0c;并设计一个简单的模板…