PyTorch中神經網絡的模型構建

要構建自定義模型,需完成兩個核心步驟:繼承 nn.Module 類;重載 __init__ 方法(初始化)和 forward 方法(前向計算)

神經網絡的構造

初始化方法(__init__

def __init__(self, **kwargs):# 調用父類構造函數,確保Module的初始化邏輯被執行super(MLP, self).__init__(** kwargs)# 定義隱藏層:輸入784維,輸出256維self.hidden = nn.Linear(784, 256)# 定義激活函數self.act = nn.ReLU()# 定義輸出層:輸入256維,輸出10維self.output = nn.Linear(256, 10)

super(MLP, self).__init__(**kwargs)這行代碼非常重要,它會調用父類 Module 的構造函數,完成必要的初始化工作;self.hidden、self.act、self.output這些是我們定義的網絡組件

**kwargs 是一個特殊的語法,用于在函數定義時接收任意數量的關鍵字參數(Keyword Arguments)。** 的作用是將參數收集為一個字典(dict),鍵為參數名,值為參數值。必須放在函數參數列表的末尾,否則會報錯。

前向傳播方法(forward

def forward(self, x):o = self.act(self.hidden(x))  # 輸入→隱藏層→激活函數return self.output(o)         # 激活結果→輸出層

輸入 x 首先通過隱藏層 self.hidden 進行線性變換;變換結果通過激活函數 self.act(ReLU)引入非線性特性;最后通過輸出層 self.output 得到最終輸出

我們只需要定義前向傳播,反向傳播會由 PyTorch 的自動求導機制自動生成

創建模型實例

net = MLP()  # 實例化MLP模型
print(net)   # 打印模型結構

輸出:

MLP((hidden): Linear(in_features=784, out_features=256, bias=True)(act): ReLU()(output): Linear(in_features=256, out_features=10, bias=True)
)

這表明我們的模型包含:
一個名為 hidden 的線性層(輸入 784 維,輸出 256 維)
一個 ReLU 激活函數層
一個名為 output 的線性層(輸入 256 維,輸出 10 維)

執行前向計算

X = torch.rand(2, 784)
output = net(X)  # 執行前向計算
print(output)

輸出:

tensor([[ 0.0149, -0.2641, -0.0040,  0.0945, -0.1277, -0.0092,  0.0343,  0.0627,-0.1742,  0.1866],[ 0.0738, -0.1409,  0.0790,  0.0597, -0.1572,  0.0479, -0.0519,  0.0211,-0.1435,  0.1958]], grad_fn=<AddmmBackward>)

輸出結果是一個形狀為 (2, 10) 的張量,表示:2 個樣本的輸出,每個樣本有 10 個輸出值

這里并沒有將?Module?類命名為?Layer?(層)或者?Model?(模型)之類的名字,這是因為該類是一個可供?由組建的部件。它的子類既可以是?個層(如PyTorch提供的 Linear 類),?可以是一個模型(如這里定義的 MLP 類),或者是模型的?個部分。

神經網絡中常見的層

不含模型參數的層

import torch
from torch import nnclass MyLayer(nn.Module):def __init__(self, **kwargs):super(MyLayer, self).__init__(**kwargs)def forward(self, x):return x - x.mean()# 測試
layer = MyLayer()
print(layer(torch.tensor([1, 2, 3, 4, 5], dtype=torch.float)))
# 輸出: tensor([-2., -1.,  0.,  1.,  2.])

這個層不含模型參數,作用是把輸入減去均值后輸出

  1. 無參數:不需要訓練參數
  2. 功能單一:通常執行固定的數學變換
  3. 可復用:可以在多個模型中重復使用

含模型參數的自定義層

Parameter?類其實是?Tensor?的子類,如果一個?Tensor?是?Parameter?,那么它會?動被添加到模型的參數列表里。所以在?定義含模型參數的層時,我們應該將參數定義成?Parameter?,除了直接定義成?Parameter?類外,還可以使??ParameterList?和?ParameterDict?分別定義參數的列表和字典。

使用?ParameterList?管理參數列表

與普通 Python 列表的關鍵區別在于,nn.ParameterList會通知 PyTorch 這些是需要優化的參數。

class MyListDense(nn.Module):def __init__(self):super(MyListDense, self).__init__()# 創建3個4x4的參數矩陣self.params = nn.ParameterList([nn.Parameter(torch.randn(4, 4)) for _ in range(3)])# 添加一個4x1的參數矩陣self.params.append(nn.Parameter(torch.randn(4, 1)))def forward(self, x):for param in self.params:x = torch.mm(x, param)return x# 測試
net = MyListDense()
print(net)

使用?ParameterDict?管理參數字典

ParameterDict?用于管理帶鍵名的參數字典,適合需要根據條件選擇不同參數的場景:

class MyDictDense(nn.Module):def __init__(self):super(MyDictDense, self).__init__()# 初始化參數字典self.params = nn.ParameterDict({'linear1': nn.Parameter(torch.randn(4, 4)),'linear2': nn.Parameter(torch.randn(4, 1))})# 添加新參數self.params.update({'linear3': nn.Parameter(torch.randn(4, 2))})def forward(self, x, choice='linear1'):return torch.mm(x, self.params[choice])# 測試
net = MyDictDense()
print(net)
print(net(torch.randn(1, 4), 'linear2'))  # 使用指定參數進行前向計算

自定義二維卷積層

import torch
from torch import nn# 卷積運算(二維互相關)
def corr2d(X, K):h, w = K.shapeX, K = X.float(), K.float()Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i, j] = (X[i: i + h, j: j + w] * K).sum()return Y# 二維卷積層
class Conv2D(nn.Module):def __init__(self, kernel_size):super(Conv2D, self).__init__()# 初始化卷積核參數self.weight = nn.Parameter(torch.randn(kernel_size))# 初始化偏置參數self.bias = nn.Parameter(torch.randn(1))def forward(self, x):return corr2d(x, self.weight) + self.bias

首先根據卷積核的大小確定輸出特征圖的尺寸,然后通過雙重循環遍歷輸入的每個可能區域,在每個區域上執行元素級乘法并求和,得到對應位置的輸出值。這個過程可以看作是使用一個小的矩陣(卷積核)在大矩陣(輸入)上滑動,每次計算重疊區域的相似度。

自定義的 Conv2D 模塊繼承自 nn.Module,包含權重和偏置兩個核心參數。權重參數表示卷積核,其形狀由 kernel_size 參數指定,而偏置參數則為每個輸出值添加一個可學習的常數。前向傳播過程簡單直接:調用 corr2d 函數執行卷積操作,然后添加偏置項。

卷積層的填充與步幅

保持輸出尺寸與輸入相同

這段代碼展示了如何使用 PyTorch 的卷積層并通過填充 (padding) 操作保持輸入輸出尺寸相同。我們先看comp_conv2d輔助函數,它的作用是簡化卷積操作的調用:將輸入張量擴展為包含批量維度和通道維度的四維張量 (格式為[批量, 通道, 高度, 寬度]),然后通過卷積層計算輸出,最后再移除批量和通道維度,返回二維的輸出結果。

具體來看卷積層的定義:這里創建了一個nn.Conv2d實例,設置了輸入通道數和輸出通道數都為 1(處理單通道圖像),卷積核大小為 3×3,并指定了兩側各填充 1 個像素。當卷積核在圖像上滑動時,填充操作會在輸入圖像的邊界周圍添加額外的像素(默認填充值為 0),這樣可以避免卷積操作導致的尺寸縮減。

在二維卷積操作中,輸出尺寸的計算公式為:

輸出高度 = (輸入高度 + 2× 填充 - 卷積核高度) / 步長 + 1
輸出寬度 = (輸入寬度 + 2× 填充 - 卷積核寬度) / 步長 + 1

填充(padding)是指在輸?高和寬的兩側填充元素(通常是0元素)。

例子中,參數設置如下:

  • 輸入尺寸:8×8
  • 卷積核大小:3×3(高度 = 3,寬度 = 3)
  • 填充(padding):1(兩側各填充 1 個像素)
  • 步長(stride):默認值 1(代碼中未顯式指定)

當我們設置padding=1時,PyTorch 會在輸入張量的上下左右各添加 1 行 / 列的零值像素。因此,實際參與卷積計算的輸入尺寸變為:

原始高度 + 2×填充 = 8 + 2×1 = 10
原始寬度 + 2×填充 = 8 + 2×1 = 10

對于 3×3 的卷積核,在填充后的 10×10 輸入上滑動時,其中心點可以到達的有效區域為:

  • 垂直方向:從第 2 行(索引 1)到第 9 行(索引 8),共 8 個位置
  • 水平方向:從第 2 列(索引 1)到第 9 列(索引 8),共 8 個位置

因此有:

輸出高度 = (10 - 3) / 1 + 1 = 7 + 1 = 8? ? ? ? ?輸出寬度 = (10 - 3) / 1 + 1 = 7 + 1 = 8

import torch
from torch import nn# 輔助函數:計算卷積結果
def comp_conv2d(conv2d, X):X = X.view((1, 1) + X.shape)  # 添加批量和通道維度Y = conv2d(X)return Y.view(Y.shape[2:])  # 移除批量和通道維度# 3x3卷積核,兩側各填充1
conv2d = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, padding=1)X = torch.rand(8, 8)  # 輸入尺寸8x8
print(comp_conv2d(conv2d, X).shape)  # 輸出尺寸仍為8x8

非對稱填充與步幅

# 5x3卷積核,高度方向填充2,寬度方向填充1,步幅為(3, 4)
conv2d = nn.Conv2d(1, 1, kernel_size=(5, 3), padding=(2, 1), stride=(3, 4))
print(comp_conv2d(conv2d, X).shape)  # 輸出尺寸: [2, 2]

自定義池化層

池化層(Pooling Layer)是一種重要的下采樣操作層,它的核心作用是通過對輸入特征圖的局部區域進行聚合計算,在減少特征圖尺寸的同時保留關鍵信息。池化層就像一個 “信息篩選器”,它會滑動過輸入的特征圖,對每個局部區域提取一個代表性的值,讓特征圖變得更緊湊。

import torch
from torch import nndef pool2d(X, pool_size, mode='max'):p_h, p_w = pool_sizeY = torch.zeros((X.shape[0] - p_h + 1, X.shape[1] - p_w + 1))for i in range(Y.shape[0]):for j in range(Y.shape[1]):if mode == 'max':Y[i, j] = X[i: i + p_h, j: j + p_w].max()  # 最大池化elif mode == 'avg':Y[i, j] = X[i: i + p_h, j: j + p_w].mean()  # 平均池化return Y# 測試
X = torch.tensor([[0, 1, 2], [3, 4, 5], [6, 7, 8]], dtype=torch.float)
print(pool2d(X, (2, 2)))  # 最大池化結果
print(pool2d(X, (2, 2), 'avg'))  # 平均池化結果

pool2d函數模擬了池化操作的基本過程。它需要輸入張量X、池化窗口大小pool_size,以及指定池化模式(最大池化或平均池化)。函數首先根據輸入尺寸和池化窗口大小計算輸出特征圖的尺寸,輸出高度為輸入高度減去池化窗口高度再加 1,寬度同理,這和卷積操作中計算輸出尺寸的邏輯類似,因為池化窗口也是通過滑動來覆蓋輸入的。然后通過兩層循環遍歷輸出特征圖的每個位置,對輸入中對應池化窗口覆蓋的局部區域進行聚合計算,得到輸出特征圖的每個元素。

最大池化(Max Pooling)是池化層中最常用的一種方式,它的計算邏輯是在每個池化窗口覆蓋的局部區域內,選取數值最大的元素作為該區域的代表值。比如在測試用例中,輸入X是一個 3×3 的張量[[0, 1, 2], [3, 4, 5], [6, 7, 8]],使用 2×2 的池化窗口進行最大池化時,第一個窗口覆蓋的區域是[[0, 1], [3, 4]],其中最大的值是 4;第二個窗口覆蓋[[1, 2], [4, 5]],最大值是 5;第三個窗口覆蓋[[3, 4], [6, 7]],最大值是 7;第四個窗口覆蓋[[4, 5], [7, 8]],最大值是 8,所以輸出的最大池化結果是[[4., 5.], [7., 8.]]。最大池化的優勢在于能夠突出局部區域中最顯著的特征,比如圖像中亮度最高的像素點,適合保留邊緣、紋理等關鍵信息。

平均池化(Average Pooling)則是另一種常見的池化方式,它在每個池化窗口覆蓋的局部區域內,計算所有元素的平均值作為該區域的代表值。同樣以測試用例為例,2×2 池化窗口下,第一個窗口[[0, 1], [3, 4]]的平均值是(0+1+3+4)/4 = 2;第二個窗口[[1, 2], [4, 5]]的平均值是(1+2+4+5)/4 = 3;第三個窗口[[3, 4], [6, 7]]的平均值是(3+4+6+7)/4 = 5;第四個窗口[[4, 5], [7, 8]]的平均值是(4+5+7+8)/4 = 6,所以平均池化的輸出結果是[[2., 3.], [5., 6.]]。平均池化的特點是能夠平滑局部區域的特征,保留區域的整體趨勢,避免個別極端值對特征的過度影響。

  • 無參數:不需要訓練參數
  • 降維:減小特征圖尺寸,降低計算復雜度
  • 特征提取:保留主要特征,增強模型魯棒性

模型示例

LeNet

LeNet 是由深度學習先驅 Yann LeCun 于 1998 年提出的卷積神經網絡,專門用于手寫數字識別任務。作為早期卷積神經網絡的經典代表,LeNet 展示了卷積操作在圖像處理中的強大能力,為后續深度學習的發展奠定了重要基礎。

LeNet 采用了卷積層 + 池化層 + 全連接層的經典組合結構,其核心思想是利用卷積操作提取圖像局部特征,通過池化層降低特征維度,最后通過全連接層完成分類。標準 LeNet-5 結構包含 7 層(不含輸入層),分為特征提取和分類兩個部分:

  • 特征提取部分:由 2 個卷積層和 2 個池化層交替組成
  • 分類部分:由 3 個全連接層組成

一個神經網絡的典型訓練過程如下:

  1. 定義包含一些可學習參數(或者叫權重)的神經網絡

  2. 在輸入數據集上迭代

  3. 通過網絡處理輸入

  4. 計算 loss (輸出和正確答案的距離)

  5. 將梯度反向傳播給網絡的參數

  6. 更新網絡的權重,一般使用一個簡單的規則:weight?=?weight?-?learning_rate?*?gradient

Net((conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1))  # 第一個卷積層(conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1)) # 第二個卷積層(fc1): Linear(in_features=400, out_features=120, bias=True) # 第一個全連接層(fc2): Linear(in_features=120, out_features=84, bias=True)  # 第二個全連接層(fc3): Linear(in_features=84, out_features=10, bias=True)   # 第三個全連接層
)

網絡初始化(__init__?方法)

import torch
import torch.nn as nn
import torch.nn.functional as Fclass Net(nn.Module):def __init__(self):super(Net, self).__init__()# 輸入圖像channel:1;輸出channel:6;5x5卷積核self.conv1 = nn.Conv2d(1, 6, 5)self.conv2 = nn.Conv2d(6, 16, 5)# 全連接層:y = Wx + bself.fc1 = nn.Linear(16 * 5 * 5, 120)self.fc2 = nn.Linear(120, 84)self.fc3 = nn.Linear(84, 10)
  • conv1:輸入通道數 = 1(灰度圖像),輸出通道數 = 6,卷積核大小 = 5×5
  • conv2:輸入通道數 = 6(上一層輸出),輸出通道數 = 16,卷積核大小 = 5×5
  • fc1:輸入特征數 = 16×5×5(上一層輸出展平后),輸出特征數 = 120
  • fc2:輸入特征數 = 120,輸出特征數 = 84
  • fc3:輸入特征數 = 84,輸出特征數 = 10(對應 10 個類別)

前向傳播(forward?方法)

def forward(self, x):# 第一層:卷積 → ReLU激活 → 2x2最大池化x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))# 第二層:卷積 → ReLU激活 → 2x2最大池化(方陣可簡化參數)x = F.max_pool2d(F.relu(self.conv2(x)), 2)# 展平特征圖:將多維特征轉為一維向量x = x.view(-1, self.num_flat_features(x))# 第三層:全連接 → ReLU激活x = F.relu(self.fc1(x))# 第四層:全連接 → ReLU激活x = F.relu(self.fc2(x))# 輸出層:全連接(無激活函數,通常配合softmax使用)x = self.fc3(x)return x
輸入圖像                  [batch_size, 3, 224, 224]
↓ 第一層卷積+池化          [batch_size, 16, 112, 112]
↓ 第二層卷積+池化          [batch_size, 32, 56, 56]
↓ 展平                    [batch_size, 100352]
↓ 全連接層1               [batch_size, 1024]
↓ 全連接層2               [batch_size, 512]
↓ 輸出層                  [batch_size, 10]

輔助函數:特征展平計算

def num_flat_features(self, x):size = x.size()[1:]  # 除去批處理維度的其他所有維度num_features = 1for s in size:num_features *= sreturn num_features

在卷積神經網絡中,當我們從卷積層過渡到全連接層時,需要將多維的特征圖(例如[batch_size, channels, height, width])展平為一維向量。這個函數就是用來計算展平后的向量長度的。

LeNet 的參數與計算特性

params = list(net.parameters())
print(f"參數總數: {len(params)}")
print(f"conv1權重維度: {params[0].size()}")  # conv1的權重參數

輸出:

參數總數: 10
conv1權重維度: torch.Size([6, 1, 5, 5])

每個卷積層包含:權重參數(out_channels × in_channels × kH × kW)+ 偏置參數(out_channels)
每個全連接層包含:權重參數(out_features × in_features)+ 偏置參數(out_features)
總參數計算:卷積層參數 + 全連接層參數 = 10 組參數(5 層 ×2 組參數 / 層)

前向傳播測試

# 創建隨機輸入:batch_size=1,通道=1,高=32,寬=32
input = torch.randn(1, 1, 32, 32)
# 前向傳播計算
out = net(input)
print(out)  # 輸出10個類別的原始分數(logits)

輸出:

tensor([[ 0.0672, -0.0743,  0.1058, -0.0181,  0.0536,  0.0736, -0.0764, -0.0423,0.0332, -0.0425]], grad_fn=<AddmmBackward>)

反向傳播

# 清零所有參數的梯度緩存
net.zero_grad()
# 隨機創建梯度張量,模擬反向傳播
out.backward(torch.randn(1, 10))

torch.nn包對輸入數據的處理要求 —— 它只支持小批量(mini-batches)樣本輸入,不直接接受單個樣本。這意味著無論是卷積層、全連接層還是其他網絡層,輸入張量都需要包含批量維度。例如nn.Conv2d要求輸入是 4 維張量,形狀為nSamples x nChannels x Height x Width,其中nSamples就是批量大小。如果只有單個樣本,需要用input.unsqueeze(0)在第 0 維添加一個 “假的” 批量維度,把形狀從nChannels x Height x Width變成1 x nChannels x Height x Width,這樣才能被網絡層正確處理。

AlexNet

AlexNet 是由 Alex Krizhevsky、Ilya Sutskever 和 Geoffrey Hinton 在 2012 年提出的卷積神經網絡,它在當年的 ImageNet 大規模視覺識別挑戰賽 (ILSVRC) 中以顯著優勢奪冠,標志著深度學習在計算機視覺領域的突破性進展。AlexNet 的成功開啟了深度學習的黃金時代,其架構設計理念深刻影響了后續神經網絡的發展。

AlexNet 由 5 個卷積層和 3 個全連接層組成,總參數超過 6000 萬個。網絡結構分為兩部分:

  1. 特征提取部分:由卷積層和池化層構成,負責提取圖像特征
  2. 分類部分:由全連接層構成,負責基于提取的特征進行分類

層操作輸入維度操作細節輸出維度
conv1(1, 1, 224, 224)11×11 卷積,步長 4,96 通道(1, 96, 54, 54)
ReLU + 池化(1, 96, 54, 54)3×3 池化,步長 2(1, 96, 26, 26)
conv2(1, 96, 26, 26)5×5 卷積,步長 1,填充 2,256 通道(1, 256, 26, 26)
ReLU + 池化(1, 256, 26, 26)3×3 池化,步長 2(1, 256, 12, 12)
conv3(1, 256, 12, 12)3×3 卷積,步長 1,填充 1,384 通道(1, 384, 12, 12)
conv4(1, 384, 12, 12)3×3 卷積,步長 1,填充 1,384 通道(1, 384, 12, 12)
conv5(1, 384, 12, 12)3×3 卷積,步長 1,填充 1,256 通道(1, 256, 12, 12)
ReLU + 池化(1, 256, 12, 12)3×3 池化,步長 2(1, 256, 5, 5)
展平(1, 256, 5, 5)多維轉一維(1, 6400)
fc1(1, 6400)全連接到 4096 維(1, 4096)
fc2(1, 4096)全連接到 4096 維(1, 4096)
fc3(1, 4096)全連接到 10 維(1, 10)
特性LeNetAlexNet
網絡深度5 層(2 卷積 + 3 全連接)8 層(5 卷積 + 3 全連接)
激活函數Sigmoid/TanhReLU
正則化Dropout(丟棄率 0.5)
卷積核大小5×511×11、5×5、3×3
通道數6→1696→256→384→384→256
全連接層維度120→84→104096→4096→10
數據增強有(隨機裁剪、水平翻轉等)
計算平臺CPUGPU

?

參考文章

datawhalechina/thorough-pytorch: PyTorch入門教程,在線閱讀地址:https://datawhalechina.github.io/thorough-pytorch/https://github.com/datawhalechina/thorough-pytorch

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91033.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91033.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91033.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

QML QtCharts坐標軸系統

QtCharts是Qt框架中強大的數據可視化模塊&#xff0c;它提供了豐富的圖表類型和靈活的坐標軸系統&#xff0c;能夠滿足各種數據展示需求。本文將全面介紹QML中QtCharts的坐標軸系統&#xff0c;包括數值坐標軸(ValueAxis)、對數坐標軸(LogValueAxis)、分類坐標軸(CategoryAxis)…

TI 2025全國電賽猜題

本科組可能的題目方向本科組器材更側重高頻信號處理、復雜控制系統、精密測量及多設備協同&#xff0c;可能涉及以下題目&#xff1a;四旋翼飛行器相關任務題目示例&#xff1a;設計 “基于四旋翼的 UV 光控自主導航系統”任務要求&#xff1a;利用四旋翼飛行器&#xff08;最大…

Python自動化運維實戰指南

什么是自動化運維定義與背景自動化運維是指利用工具和腳本自動執行傳統上需要人工操作的IT運維任務&#xff0c;包括但不限于服務器配置管理、軟件部署、監控告警、日志分析等日常工作。隨著互聯網業務規模的擴大&#xff0c;傳統手工運維方式已無法滿足快速部署、規模化管理等…

k8s的csi對接GPFS

在 Kubernetes&#xff08;k8s&#xff09;集群中&#xff0c;通過 CSI&#xff08;Container Storage Interface&#xff09;對接 GPFS&#xff08;General Parallel File System&#xff0c;現為 IBM Spectrum Scale&#xff09;是實現高性能共享存儲的重要方案。GPFS 作為并…

HTB賽季8靶場 - era

nmap掃描 └─$ nmap -p- --min-rate 1000 -T4 10.129.137.201 -oA nmapfullscan Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-07-27 21:19 EDT Warning: 10.129.137.201 giving up on port because retransmission cap hit (6). …

Bug貓學習史#1:面向對象

在Java編程中&#xff0c;掌握幾個核心概念對深入學習至關重要&#xff1a;類屬性建議采用包裝類以提升靈活性&#xff1b;建造者模式中this關鍵字能有效簡化對象構建過程&#xff1b;static關鍵字涉及類的加載機制&#xff1b;接口默認使用public修飾符并支持默認方法實現&…

優測推出HarmonyOS全場景測試服務,解鎖分布式場景應用卓越品質!

隨著HarmonyOS NEXT“純血鴻蒙”的全面商用&#xff0c;生態正以前所未有的速度重構終端操作系統格局。對于APP廠商而言&#xff0c;應用測試需要從單一設備思維向場景化服務驗證轉變。優測云服務平臺正式推出 HarmonyOS全場景測試解決方案&#xff0c;針對鴻蒙系統提供功能測試…

二層環路與三層環路:原理、區別與解決方案全解析

網絡環路是網絡運維中最常見也最具破壞性的問題之一。本文將深入淺出地解析二層環路和三層環路的核心概念&#xff0c;通過對比分析幫助讀者全面理解這兩種環路的形成機制、危害表現及解決方案。一、環路問題概述 1.1 什么是網絡環路 網絡環路是指數據包在網絡中循環傳輸無法到…

Python爬蟲庫性能與選型實戰指南:從需求到落地的全鏈路解析

目錄 一、性能基準測試&#xff1a;用數據打破認知誤區 1. 靜態頁面采集&#xff1a;效率與資源的終極對決 2. 動態頁面渲染&#xff1a;速度與真實性的博弈 二、場景化選型矩陣&#xff1a;從需求到工具的精準映射 1. 小規模快速原型開發&#xff08;≤1000頁&#xff09;…

uni-app switch(開關選擇器) BUG

uni-app switch&#xff08;開關選擇器&#xff09; BUGBUG&#xff1a;uni-app中的switch的checked屬性并不能根據根據綁定的動態數據進行調整switch開關選擇器&#xff08;BUG&#xff09;switch開關選擇器&#xff08;BUG&#xff09; - 我的使用用途switch開關選擇器&#…

微服務架構中的資源調度與負載均衡實踐

更多云服務器知識&#xff0c;盡在hostol.com在今天這個快速發展的數字化時代&#xff0c;微服務架構已經成為了現代企業系統開發的主流。隨著技術的不斷進步&#xff0c;企業的業務需求也在不斷地變化&#xff0c;傳統的單體架構已經無法滿足日益復雜的應用需求。微服務架構&a…

Rust Web 全棧開發(十一):WebAssembly 嘗鮮

Rust Web 全棧開發&#xff08;十一&#xff09;&#xff1a;WebAssembly 嘗鮮Rust Web 全棧開發&#xff08;十一&#xff09;&#xff1a;WebAssembly 嘗鮮什么是 WebAssembly&#xff1f;安裝 wasm-pack 和 cargo-generate使用項目模板構建項目生成網頁安裝依賴項在 www 中使…

Thymeleaf實戰:SpringBoot用戶管理系統

Thymeleaf 示例代碼下面是完整代碼示例&#xff0c;幫助理解 Thymeleaf 語法和后端代碼的配合&#xff1a;1. 用戶實體類 (User.java)/*** 用戶實體類*/ public class User {private Long id; // 用戶IDprivate String name; // 用戶名private String email; /…

mysql查找數據庫表中某幾個連續的編號中中斷的編號

在MySQL中查找表中連續編號中斷的位置,可以通過以下幾種方法實現: 基于范圍的查詢方法 通過自連接查詢找出ID序列中的斷點,例如查找1-100范圍內缺失的ID: SELECT a.id + 1 AS start, MIN(b.id) - 1 AS end FROM

《劍指offer》-數據結構篇-樹

題目重建二叉樹樹的子結構二叉樹的鏡像從上往下打印二叉樹&#xff08;層序遍歷&#xff09;把二叉樹打印成多行按之字形順序打印二叉樹二叉搜索樹的第k個結點&#xff08;中序遍歷&#xff09;二叉搜索樹的后序遍歷序列&#xff08;后序遍歷&#xff09;二叉樹中和為某一值的路…

系統定時任務擴展開發指南

適用場景當系統內置定時任務類型無法滿足業務需求時&#xff0c;開發者可通過本教程快速掌握自定義定時任務的擴展方法。本指南以"定時檢測服務"為例&#xff0c;演示完整開發流程。我想添加一個定時任務 ,而這里沒有我需要的,我怎么來添加比如我想添加一個定時檢測用…

R語言簡介(附電子書資料)

概述 R語言是一種專為統計計算和數據分析設計的編程語言&#xff0c;自誕生以來&#xff0c;憑借其強大的統計分析能力和豐富的可視化功能&#xff0c;成為數據科學、統計學、機器學習等領域的重要工具。電子書資料&#xff1a;https://pan.quark.cn/s/23050825f2be 一、核心特…

關于前端的性能優化

性能優化主要涵蓋了以下四個方面: (tip:僅代表個人總結,如有不當,還希望看到的大佬多多指示) 減少網絡請求:合并文件、使用 CDN、啟用緩存。 優化資源加載:代碼分割、懶加載、圖片壓縮。 提升渲染性能:減少重繪回流、防抖節流、使用 Web Worker。 監控和迭代:定期使用工…

用 FFmpeg 把視頻輸出為圖片序列

用 FFmpeg 把視頻輸出為圖片序列 【推薦】輸出為PNG圖片序列&#xff08;無損&#xff09; mkdir "D:\Downloads\Recording" ffmpeg -i "C:\Users\33589\Videos\1.mp4" "D:\Downloads\Recording\Recording_%05d.png" 參數含義-i輸入視頻路徑&am…

【linux】高可用集群Keepalived

Keepalived簡介Keepalived 是一個基于 VRRP&#xff08;虛擬路由冗余協議&#xff09;的高可用解決方案&#xff0c;主要用于實現 Linux 服務器的負載均衡和故障轉移。它通過檢測服務器狀態并自動切換服務&#xff0c;確保系統在單點故障時仍能保持可用性Keeplived安裝啟用及配…