Pytorch | 從零構建MobileNet對CIFAR10進行分類

Pytorch | 從零構建MobileNet對CIFAR10進行分類

  • CIFAR10數據集
  • MobileNet
    • 設計理念
    • 網絡結構
    • 技術優勢
    • 應用領域
  • MobileNet結構代碼詳解
    • 結構代碼
    • 代碼詳解
      • DepthwiseSeparableConv 類
        • 初始化方法
        • 前向傳播 forward 方法
      • MobileNet 類
        • 初始化方法
        • 前向傳播 forward 方法
  • 訓練過程和測試結果
  • 代碼匯總
    • mobilenet.py
    • train.py
    • test.py

前面文章我們構建了AlexNet、Vgg、GoogleNet對CIFAR10進行分類:
Pytorch | 從零構建AlexNet對CIFAR10進行分類
Pytorch | 從零構建Vgg對CIFAR10進行分類
Pytorch | 從零構建GoogleNet對CIFAR10進行分類
Pytorch | 從零構建ResNet對CIFAR10進行分類
這篇文章我們來構建MobileNet.

CIFAR10數據集

CIFAR-10數據集是由加拿大高級研究所(CIFAR)收集整理的用于圖像識別研究的常用數據集,基本信息如下:

  • 數據規模:該數據集包含60,000張彩色圖像,分為10個不同的類別,每個類別有6,000張圖像。通常將其中50,000張作為訓練集,用于模型的訓練;10,000張作為測試集,用于評估模型的性能。
  • 圖像尺寸:所有圖像的尺寸均為32×32像素,這相對較小的尺寸使得模型在處理該數據集時能夠相對快速地進行訓練和推理,但也增加了圖像分類的難度。
  • 類別內容:涵蓋了飛機(plane)、汽車(car)、鳥(bird)、貓(cat)、鹿(deer)、狗(dog)、青蛙(frog)、馬(horse)、船(ship)、卡車(truck)這10個不同的類別,這些類別都是現實世界中常見的物體,具有一定的代表性。

下面是一些示例樣本:
在這里插入圖片描述

MobileNet

MobileNet是由谷歌在2017年提出的一種輕量級卷積神經網絡,主要用于移動端和嵌入式設備等資源受限的環境中進行圖像識別和分類任務,以下是對其的詳細介紹:

設計理念

  • 深度可分離卷積:其核心創新是采用了深度可分離卷積(Depthwise Separable Convolution)來替代傳統的卷積操作。深度可分離卷積將標準卷積分解為一個深度卷積(Depthwise Convolution)和一個逐點卷積(Pointwise Convolution),大大減少了計算量和模型參數,同時保持了較好的性能。

網絡結構

  • 標準卷積層:輸入層為3通道的彩色圖像,首先經過一個普通的卷積層conv1,將通道數從3變為32,同時進行了步長為2的下采樣操作,以減小圖像尺寸。
  • 深度可分離卷積層:包含了一系列的深度可分離卷積層dsconv1dsconv13,這些層按照一定的規律進行排列,通道數逐漸增加,同時通過不同的步長進行下采樣,以提取不同層次的特征。
  • 池化層和全連接層:在深度可分離卷積層之后,通過一個自適應平均池化層avgpool將特征圖轉換為1x1的大小,然后通過一個全連接層fc將特征映射到指定的類別數,完成分類任務。

技術優勢

  • 模型輕量化:通過深度可分離卷積的使用,大大減少了模型的參數量和計算量,使得模型更加輕量化,適合在移動設備和嵌入式設備上運行。
  • 計算效率高:由于減少了計算量,MobileNet在推理時具有較高的計算效率,可以快速地對圖像進行分類和識別,滿足實時性要求較高的應用場景。
  • 性能表現較好:盡管模型輕量化,但MobileNet在圖像識別任務上仍然具有較好的性能表現,能夠在保持較高準確率的同時,大大降低模型的復雜度。

應用領域

  • 移動端視覺任務:廣泛應用于各種移動端設備,如智能手機、平板電腦等,用于圖像分類、目標檢測、人臉識別等視覺任務。
  • 嵌入式設備視覺:在嵌入式設備,如智能攝像頭、自動駕駛汽車等領域,MobileNet可以為這些設備提供高效的視覺處理能力,實現實時的圖像分析和決策。
  • 物聯網視覺應用:在物聯網設備中,MobileNet可以幫助實現對圖像數據的快速處理和分析,為智能家居、智能安防等應用提供支持。

MobileNet結構代碼詳解

結構代碼

import torch
import torch.nn as nnclass DepthwiseSeparableConv(nn.Module):def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False):super(DepthwiseSeparableConv, self).__init__()self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size, stride, padding, groups=in_channels, bias=bias)self.bn1 = nn.BatchNorm2d(in_channels)self.relu1 = nn.ReLU6(inplace=True)self.pointwise = nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=bias)self.bn2 = nn.BatchNorm2d(out_channels)self.relu2 = nn.ReLU6(inplace=True)def forward(self, x):out = self.depthwise(x)out = self.bn1(out)out = self.relu1(out)out = self.pointwise(out)out = self.bn2(out)out = self.relu2(out)return outclass MobileNet(nn.Module):def __init__(self, num_classes):super(MobileNet, self).__init__()self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1, bias=False)self.bn1 = nn.BatchNorm2d(32)self.relu = nn.ReLU6(inplace=True)self.dsconv1 = DepthwiseSeparableConv(32, 64, stride=1)self.dsconv2 = DepthwiseSeparableConv(64, 128, stride=2)self.dsconv3 = DepthwiseSeparableConv(128, 128, stride=1)self.dsconv4 = DepthwiseSeparableConv(128, 256, stride=2)self.dsconv5 = DepthwiseSeparableConv(256, 256, stride=1)self.dsconv6 = DepthwiseSeparableConv(256, 512, stride=2)self.dsconv7 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv8 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv9 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv10 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv11 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv12 = DepthwiseSeparableConv(512, 1024, stride=2)self.dsconv13 = DepthwiseSeparableConv(1024, 1024, stride=1)self.avgpool = nn.AdaptiveAvgPool2d((1, 1))self.fc = nn.Linear(1024, num_classes)def forward(self, x):out = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.dsconv1(out)out = self.dsconv2(out)out = self.dsconv3(out)out = self.dsconv4(out)out = self.dsconv5(out)out = self.dsconv6(out)out = self.dsconv7(out)out = self.dsconv8(out)out = self.dsconv9(out)out = self.dsconv10(out)out = self.dsconv11(out)out = self.dsconv12(out)out = self.dsconv13(out)out = self.avgpool(out)out = out.view(out.size(0), -1)out = self.fc(out)return out

代碼詳解

以下是對上述代碼的詳細解釋:

DepthwiseSeparableConv 類

這是一個自定義的深度可分離卷積層類,繼承自 nn.Module

初始化方法
  • 參數說明
    • in_channels:輸入通道數,指定輸入數據的通道數量。
    • out_channels:輸出通道數,即卷積操作后輸出特征圖的通道數量。
    • kernel_size:卷積核大小,默認為3,用于定義卷積操作中卷積核的尺寸。
    • stride:步長,默認為1,控制卷積核在輸入特征圖上滑動的步長。
    • padding:填充大小,默認為1,在輸入特征圖周圍添加的填充像素數量,以保持特征圖尺寸在卷積過程中合適變化。
    • bias:是否使用偏置,默認為 False,決定卷積層是否添加偏置項。
  • 構建的層及作用
    • self.depthwise:這是一個深度卷積層(nn.Conv2d),通過設置 groups=in_channels,實現了深度可分離卷積中的深度卷積部分,它對每個輸入通道分別進行卷積操作,有效地減少了計算量。
    • self.bn1:批歸一化層(nn.BatchNorm2d),用于對深度卷積后的輸出進行歸一化處理,加速模型收斂并提升模型的泛化能力。
    • self.relu1:激活函數層(nn.ReLU6),采用 ReLU6 激活函數(輸出值限定在0到6之間),并且設置 inplace=True,意味著直接在輸入的張量上進行修改,節省內存空間,增加非線性特性。
    • self.pointwise:逐點卷積層(nn.Conv2d),卷積核大小為1,用于將深度卷積后的特征圖在通道維度上進行融合,改變通道數到指定的 out_channels
    • self.bn2:又是一個批歸一化層,對逐點卷積后的輸出進行歸一化處理。
    • self.relu2:同樣是 ReLU6 激活函數層,進一步增加非線性,處理逐點卷積歸一化后的結果。
前向傳播 forward 方法

定義了數據在該層的前向傳播過程:

  • 首先將輸入 x 通過深度卷積層 self.depthwise 進行深度卷積操作,得到輸出特征圖。
  • 然后將深度卷積的輸出依次經過批歸一化層 self.bn1 和激活函數層 self.relu1
  • 接著把經過處理后的特征圖通過逐點卷積層 self.pointwise 進行逐點卷積,改變通道數等特征。
  • 最后再經過批歸一化層 self.bn2 和激活函數層 self.relu2,并返回最終的輸出結果。

MobileNet 類

這是定義的 MobileNet 網絡模型類,同樣繼承自 nn.Module

初始化方法
  • 參數說明
    • num_classes:分類的類別數量,用于最后全連接層輸出對應類別數的預測結果。
  • 構建的層及作用
    • self.conv1:普通的二維卷積層(nn.Conv2d),輸入通道數為3(通常對應RGB圖像的三個通道),輸出通道數為32,卷積核大小為3,步長為2,用于對輸入圖像進行初步的特征提取和下采樣,減少特征圖尺寸同時增加通道數。
    • self.bn1:批歸一化層,對 conv1 卷積后的輸出進行歸一化。
    • self.relu:激活函數層,采用 ReLU6 激活函數給特征圖增加非線性。
    • 一系列的 self.dsconv 層(從 dsconv1dsconv13):都是前面定義的深度可分離卷積層 DepthwiseSeparableConv 的實例,它們逐步對特征圖進行更精細的特征提取、通道變換以及下采樣等操作,不同的 dsconv 層有著不同的輸入輸出通道數以及步長設置,以此構建出 MobileNet 網絡的主體結構,不斷提取和融合特征,逐步降低特征圖尺寸并增加通道數來獲取更高級、更抽象的特征表示。
    • self.avgpool:自適應平均池化層(nn.AdaptiveAvgPool2d),將輸入特征圖轉換為指定大小 (1, 1) 的輸出,起到全局平均池化的作用,進一步壓縮特征圖信息,同時保持特征圖的維度一致性,方便后續全連接層處理。
    • self.fc:全連接層(nn.Linear),輸入維度為1024(與前面網絡結構最終輸出的特征維度對應),輸出維度為 num_classes,用于將經過前面卷積和池化等操作得到的特征向量映射到對應類別數量的預測分數上,實現分類任務。
前向傳播 forward 方法

定義了 MobileNet 模型整體的前向傳播流程:

  • 首先將輸入 x 通過 conv1 進行初始卷積、bn1 進行歸一化以及 relu 激活。
  • 然后依次通過各個深度可分離卷積層(dsconv1dsconv13),逐步提取和變換特征。
  • 接著經過自適應平均池化層 self.avgpool,將特征圖壓縮為 (1, 1) 大小。
  • 再通過 out.view(out.size(0), -1) 操作將特征圖展平為一維向量(其中 out.size(0) 表示批量大小,-1 表示自動計算剩余維度大小使其展平)。
  • 最后將展平后的特征向量通過全連接層 self.fc 得到最終的分類預測結果并返回。

訓練過程和測試結果

訓練過程損失函數變化曲線:
在這里插入圖片描述

訓練過程準確率變化曲線:
在這里插入圖片描述

測試結果:
在這里插入圖片描述

代碼匯總

項目github地址
項目結構:

|--data
|--models|--__init__.py|-mobilenet.py|--...
|--results
|--weights
|--train.py
|--test.py

mobilenet.py

import torch
import torch.nn as nnclass DepthwiseSeparableConv(nn.Module):def __init__(self, in_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False):super(DepthwiseSeparableConv, self).__init__()self.depthwise = nn.Conv2d(in_channels, in_channels, kernel_size, stride, padding, groups=in_channels, bias=bias)self.bn1 = nn.BatchNorm2d(in_channels)self.relu1 = nn.ReLU6(inplace=True)self.pointwise = nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=bias)self.bn2 = nn.BatchNorm2d(out_channels)self.relu2 = nn.ReLU6(inplace=True)def forward(self, x):out = self.depthwise(x)out = self.bn1(out)out = self.relu1(out)out = self.pointwise(out)out = self.bn2(out)out = self.relu2(out)return outclass MobileNet(nn.Module):def __init__(self, num_classes):super(MobileNet, self).__init__()self.conv1 = nn.Conv2d(3, 32, kernel_size=3, stride=2, padding=1, bias=False)self.bn1 = nn.BatchNorm2d(32)self.relu = nn.ReLU6(inplace=True)self.dsconv1 = DepthwiseSeparableConv(32, 64, stride=1)self.dsconv2 = DepthwiseSeparableConv(64, 128, stride=2)self.dsconv3 = DepthwiseSeparableConv(128, 128, stride=1)self.dsconv4 = DepthwiseSeparableConv(128, 256, stride=2)self.dsconv5 = DepthwiseSeparableConv(256, 256, stride=1)self.dsconv6 = DepthwiseSeparableConv(256, 512, stride=2)self.dsconv7 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv8 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv9 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv10 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv11 = DepthwiseSeparableConv(512, 512, stride=1)self.dsconv12 = DepthwiseSeparableConv(512, 1024, stride=2)self.dsconv13 = DepthwiseSeparableConv(1024, 1024, stride=1)self.avgpool = nn.AdaptiveAvgPool2d((1, 1))self.fc = nn.Linear(1024, num_classes)def forward(self, x):out = self.conv1(x)out = self.bn1(out)out = self.relu(out)out = self.dsconv1(out)out = self.dsconv2(out)out = self.dsconv3(out)out = self.dsconv4(out)out = self.dsconv5(out)out = self.dsconv6(out)out = self.dsconv7(out)out = self.dsconv8(out)out = self.dsconv9(out)out = self.dsconv10(out)out = self.dsconv11(out)out = self.dsconv12(out)out = self.dsconv13(out)out = self.avgpool(out)out = out.view(out.size(0), -1)out = self.fc(out)return out

train.py

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
from models import *
import matplotlib.pyplot as pltimport ssl
ssl._create_default_https_context = ssl._create_unverified_context# 定義數據預處理操作
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.491, 0.482, 0.446), (0.247, 0.243, 0.261))])# 加載CIFAR10訓練集
trainset = torchvision.datasets.CIFAR10(root='./data', train=True,download=False, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=128,shuffle=True, num_workers=2)# 定義設備(GPU優先,若可用)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 實例化模型
model_name = 'MobileNet'
if model_name == 'AlexNet':model = AlexNet(num_classes=10).to(device)
elif model_name == 'Vgg_A':model = Vgg(cfg_vgg='A', num_classes=10).to(device)
elif model_name == 'Vgg_A-LRN':model = Vgg(cfg_vgg='A-LRN', num_classes=10).to(device)
elif model_name == 'Vgg_B':model = Vgg(cfg_vgg='B', num_classes=10).to(device)
elif model_name == 'Vgg_C':model = Vgg(cfg_vgg='C', num_classes=10).to(device)
elif model_name == 'Vgg_D':model = Vgg(cfg_vgg='D', num_classes=10).to(device)
elif model_name == 'Vgg_E':model = Vgg(cfg_vgg='E', num_classes=10).to(device)
elif model_name == 'GoogleNet':model = GoogleNet(num_classes=10).to(device)
elif model_name == 'ResNet18':model = ResNet18(num_classes=10).to(device)
elif model_name == 'ResNet34':model = ResNet34(num_classes=10).to(device)
elif model_name == 'ResNet50':model = ResNet50(num_classes=10).to(device)
elif model_name == 'ResNet101':model = ResNet101(num_classes=10).to(device)
elif model_name == 'ResNet152':model = ResNet152(num_classes=10).to(device)
elif model_name == 'MobileNet':model = MobileNet(num_classes=10).to(device)criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)# 訓練輪次
epochs = 15def train(model, trainloader, criterion, optimizer, device):model.train()running_loss = 0.0correct = 0total = 0for i, data in enumerate(trainloader, 0):inputs, labels = data[0].to(device), data[1].to(device)optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()running_loss += loss.item()_, predicted = outputs.max(1)total += labels.size(0)correct += predicted.eq(labels).sum().item()epoch_loss = running_loss / len(trainloader)epoch_acc = 100. * correct / totalreturn epoch_loss, epoch_accif __name__ == "__main__":loss_history, acc_history = [], []for epoch in range(epochs):train_loss, train_acc = train(model, trainloader, criterion, optimizer, device)print(f'Epoch {epoch + 1}: Train Loss: {train_loss:.4f}, Train Acc: {train_acc:.2f}%')loss_history.append(train_loss)acc_history.append(train_acc)# 保存模型權重,每5輪次保存到weights文件夾下if (epoch + 1) % 5 == 0:torch.save(model.state_dict(), f'weights/{model_name}_epoch_{epoch + 1}.pth')# 繪制損失曲線plt.plot(range(1, epochs+1), loss_history, label='Loss', marker='o')plt.xlabel('Epoch')plt.ylabel('Loss')plt.title('Training Loss Curve')plt.legend()plt.savefig(f'results\\{model_name}_train_loss_curve.png')plt.close()# 繪制準確率曲線plt.plot(range(1, epochs+1), acc_history, label='Accuracy', marker='o')plt.xlabel('Epoch')plt.ylabel('Accuracy (%)')plt.title('Training Accuracy Curve')plt.legend()plt.savefig(f'results\\{model_name}_train_acc_curve.png')plt.close()

test.py

import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms
from models import *import ssl
ssl._create_default_https_context = ssl._create_unverified_context
# 定義數據預處理操作
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.491, 0.482, 0.446), (0.247, 0.243, 0.261))])# 加載CIFAR10測試集
testset = torchvision.datasets.CIFAR10(root='./data', train=False,download=False, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=128,shuffle=False, num_workers=2)# 定義設備(GPU優先,若可用)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 實例化模型
model_name = 'MobileNet'
if model_name == 'AlexNet':model = AlexNet(num_classes=10).to(device)
elif model_name == 'Vgg_A':model = Vgg(cfg_vgg='A', num_classes=10).to(device)
elif model_name == 'Vgg_A-LRN':model = Vgg(cfg_vgg='A-LRN', num_classes=10).to(device)
elif model_name == 'Vgg_B':model = Vgg(cfg_vgg='B', num_classes=10).to(device)
elif model_name == 'Vgg_C':model = Vgg(cfg_vgg='C', num_classes=10).to(device)
elif model_name == 'Vgg_D':model = Vgg(cfg_vgg='D', num_classes=10).to(device)
elif model_name == 'Vgg_E':model = Vgg(cfg_vgg='E', num_classes=10).to(device)
elif model_name == 'GoogleNet':model = GoogleNet(num_classes=10).to(device)
elif model_name == 'ResNet18':model = ResNet18(num_classes=10).to(device)
elif model_name == 'ResNet34':model = ResNet34(num_classes=10).to(device)
elif model_name == 'ResNet50':model = ResNet50(num_classes=10).to(device)
elif model_name == 'ResNet101':model = ResNet101(num_classes=10).to(device)
elif model_name == 'ResNet152':model = ResNet152(num_classes=10).to(device)
elif model_name == 'MobileNet':model = MobileNet(num_classes=10).to(device)criterion = nn.CrossEntropyLoss()# 加載模型權重
weights_path = f"weights/{model_name}_epoch_15.pth"  
model.load_state_dict(torch.load(weights_path, map_location=device))def test(model, testloader, criterion, device):model.eval()running_loss = 0.0correct = 0total = 0with torch.no_grad():for data in testloader:inputs, labels = data[0].to(device), data[1].to(device)outputs = model(inputs)loss = criterion(outputs, labels)running_loss += loss.item()_, predicted = outputs.max(1)total += labels.size(0)correct += predicted.eq(labels).sum().item()epoch_loss = running_loss / len(testloader)epoch_acc = 100. * correct / totalreturn epoch_loss, epoch_accif __name__ == "__main__":test_loss, test_acc = test(model, testloader, criterion, device)print(f"================{model_name} Test================")print(f"Load Model Weights From: {weights_path}")print(f'Test Loss: {test_loss:.4f}, Test Acc: {test_acc:.2f}%')

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

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

相關文章

Electronjs+Vue如何開發PC桌面客戶端(Windows,Mac,Linux)

electronjs官網 https://www.electronjs.org/zh/ Electron開發PC桌面客戶端的技術選型非常適合已經有web前端開發人員的團隊。能夠很絲滑的過渡。 Electron是什么? Electron是一個使用 JavaScript、HTML 和 CSS 構建桌面應用程序的框架。 嵌入 Chromium 和 Node.…

【1.排序】

排序 筆記記錄 1.排序的基本概念1.1 排序的定義 2. 插入排序2.1 直接插入排序2.2 折半插入排序2.3 希爾排序 3. 交換排序3.1 冒泡排序3.2 快速排序 4. 選擇排序4.1 簡單選擇排序4.2 堆排序 5. 歸并排序、基數排序和計數排序5.1 歸并排序4.2 基數排序4.3 計數排序 6. 各種內部排…

Linux Swap: 深入解析 mkswap, mkfs.swap, 和 swapon

文章目錄 Linux Swap: 深入解析 mkswap, mkfs.swap, 和 swapon什么是 Swap?主要命令介紹1. mkswap2. mkfs.swap3. swapon 創建和管理 Swap 的步驟1. 創建 Swap 分區2. 初始化 Swap3. 激活 Swap4. 持久化配置5. 查看 Swap 狀態 刪除 Swap 分區或文件1. 停用 Swap2. 刪…

取子串(指針)

#include <stdio.h> #include <string.h>char* substr(char *s, int startloc, int len) {static char result[51]; // 定義一個足夠大的靜態數組來存儲結果static char result1[] {N,U,L,L,\0};int i, j;// 檢查startloc是否在字符串的范圍內if (startloc < 1…

「Mac暢玩鴻蒙與硬件45」UI互動應用篇22 - 評分統計工具

本篇將帶你實現一個評分統計工具&#xff0c;用戶可以對多個選項進行評分。應用會實時更新每個選項的評分結果&#xff0c;并統計平均分。這一功能適合用于問卷調查或評分統計的場景。 關鍵詞 UI互動應用評分統計狀態管理數據處理多目標評分 一、功能說明 評分統計工具允許用…

類與對象的理解

面向對象中兩個重要的概念&#xff1a;類與對象 類 簡單理解&#xff0c;它指的是類型或者分類或某個模塊 比如&#xff1a;人類、動物類……&#xff1b;入公司的入職單&#xff0c;沒寫上任何人的情況下 對象 簡單理解&#xff0c;它指的具體的個體 備注&#xff1a;對…

遞歸實現指數型枚舉(遞歸)

92. 遞歸實現指數型枚舉 - AcWing題庫 每個數有選和不選兩種情況 我們把每個數看成每層&#xff0c;可以畫出一個遞歸搜索樹 葉子節點就是我們的答案 很容易寫出每dfs函數 dfs傳入一個u表示層數 當層數大于我們n時&#xff0c;去判斷每個數字的選擇情況&#xff0c;輸出被選…

Linux相關概念和易錯知識點(25)(信號原理、操作系統的原理、volatile)

目錄 1.信號的產生 &#xff08;1&#xff09;kill &#xff08;2&#xff09;raise、abort 2.對block、pending、handler表的管理 &#xff08;1&#xff09;信號集&#xff08;sigset_t&#xff09; &#xff08;2&#xff09;block表的管理 ①操作相關的函數 ②sigpr…

opencv中的色彩空間及其轉換

在 OpenCV 中&#xff0c;色彩空間&#xff08;Color Space&#xff09;指的是表示顏色的一種方式&#xff0c;或是用數學模型對顏色的表達。不同的色彩空間采用不同的方式來描述顏色的三要素&#xff08;如亮度、飽和度、色調&#xff09;&#xff0c;因此可以在不同的應用場景…

OPPO 數據分析面試題及參考答案

如何設計共享單車數據庫的各個字段? 對于共享單車的數據庫設計,首先考慮用戶相關的字段。用戶表可以包含用戶 ID,這是一個唯一標識符,用于區分不同用戶;姓名,記錄用戶的真實姓名;聯系方式,比如手機號碼,方便在出現問題時聯系用戶;注冊時間,記錄用戶何時開始使用共享…

在Ubuntu下運行QEMU仿真FreeBSD riscv64系統

在Ubuntu下運行QEMU仿真FreeBSD riscv64系統 突發奇想&#xff0c;嘗試在Ubuntu下運行QEMU仿真FreeBSD riscv64系統&#xff0c; 參考這篇文檔&#xff1a;手把手教你在QEMU上運行RISC-V Linux_qemu 運行 .bin-CSDN博客 并參考FreeBSD的Wiki&#xff1a;riscv - FreeBSD Wik…

大模型微調---Prompt-tuning微調

目錄 一、前言二、Prompt-tuning實戰2.1、下載模型到本地2.2、加載模型與數據集2.3、處理數據2.4、Prompt-tuning微調2.5、訓練參數配置2.6、開始訓練 三、模型評估四、完整訓練代碼 一、前言 Prompt-tuning通過修改輸入文本的提示&#xff08;Prompt&#xff09;來引導模型生…

Visual Studio 、 MSBuild 、 Roslyn 、 .NET Runtime、SDK Tools之間的關系

1. Visual Studio Visual Studio 是一個集成開發環境&#xff08;IDE&#xff09;&#xff0c;為開發者提供代碼編寫、調試、測試和發布等功能。它內置了 MSBuild、Roslyn 和 SDK Tools&#xff0c;并提供圖形化界面來方便開發者進行項目管理和構建。與其他組件的關系&#xf…

Winnows基礎(2)

Target 了解常見端口及服務&#xff0c;熟練cmd命令&#xff0c;編寫簡單的 .bat 病毒程序。 Trail 常見服務及端口 80 web 80-89 可能是web 443 ssl心臟滴血漏洞以及一些web漏洞測試 445 smb 1433 mssql 1521 oracle 2082/2083 cpanel主機管理系統登陸&#xff08;國外用的…

Edge Scdn用起來怎么樣?

Edge Scdn&#xff1a;提升網站安全與性能的最佳選擇 在當今互聯網高速發展的時代&#xff0c;各種網絡攻擊層出不窮&#xff0c;特別是針對網站的DDoS攻擊威脅&#xff0c;幾乎每個行業都可能成為目標。為了確保網站的安全性與穩定性&#xff0c;越來越多的企業開始關注Edge …

通信技術以及5G和AI保障電網安全與網絡安全

摘 要&#xff1a;電網安全是電力的基礎&#xff0c;隨著智能電網的快速發展&#xff0c;越來越多的ICT信息通信技術被應用到電力網絡。本文分析了歷史上一些重大電網安全與網絡安全事故&#xff0c;介紹了電網安全與網絡安全、通信技術與電網安全的關系以及相應的電網安全標準…

梯度(Gradient)和 雅各比矩陣(Jacobian Matrix)的區別和聯系:中英雙語

雅各比矩陣與梯度&#xff1a;區別與聯系 在數學與機器學習中&#xff0c;梯度&#xff08;Gradient&#xff09; 和 雅各比矩陣&#xff08;Jacobian Matrix&#xff09; 是兩個核心概念。雖然它們都描述了函數的變化率&#xff0c;但應用場景和具體形式有所不同。本文將通過…

時間序列預測論文閱讀和相關代碼庫

時間序列預測論文閱讀和相關代碼庫列表 MLP-based的時間序列預測資料DLinearUnetTSFPDMLPLightTS 代碼庫以及論文庫&#xff1a;Time-Series-LibraryUnetTSFLightTS MLP-based的時間序列預測資料 我會定期把我的所有時間序列預測論文有關的資料鏈接全部同步到這個文章中&#…

引言和相關工作的區別

引言和相關工作的區別 引言 目的與重點 引言主要是為了引出研究的主題,向讀者介紹為什么這個研究問題是重要且值得關注的。它通常從更廣泛的背景出發,闡述研究領域的現狀、面臨的問題或挑戰,然后逐漸聚焦到論文要解決的具體問題上。例如,在這篇關于聯邦學習數據交易方案的…

GitLab分支管理策略和最佳實踐

分支管理是 Git 和 GitLab 中非常重要的部分&#xff0c;合理的分支管理可以幫助團隊更高效地協作和開發。以下是一些細化的分支管理策略和最佳實踐&#xff1a; 1. 分支命名規范 ? 主分支&#xff1a;通常命名為 main 或 master&#xff0c;用于存放穩定版本的代碼。 ? …