從零開始:用PyTorch構建CIFAR-10圖像分類模型達到接近1的準確率

為了增強代碼可讀性,代碼均使用Chatgpt給每一行代碼都加入了注釋,方便大家在本文代碼的基礎上進行改進優化。

本文是搭建了一個稍微優化了一下的模型,訓練200個epoch,準確率達到了99.74%,簡單完成了一下CIFAR-10數據集的實驗,再調調參可能就到100%了吧,算是一個入門學習吧 ~

完整代碼鏈接: MachineLearningCourseWork
數據: data5 - CIFAR10
完整代碼ipynb格式文件: work5-CIFAR10.ipynb

【本文參考資料】

  1. CIFAR-10 官方網站:由數據集創建者 Alex Krizhevsky 維護,提供了數據集的下載鏈接、格式說明等詳細信息。
  2. Deep Learning with Python:由 Francois Chollet 撰寫的深度學習書籍,其中使用 CIFAR-10 數據集作為案例講解圖像分類模型的構建和訓練方法。
  3. CS231n: Convolutional Neural Networks for Visual Recognition:斯坦福大學的CV課。

文章目錄

    • 1. 數據集介紹
      • 1.1 數據集概述
      • 1.2 數據集結構
      • 1.3 數據集格式
      • 1.4 數據集應用場景
      • 1.5 數據集特點
    • 2. 實驗流程
      • 2.1 導包
      • 2.2 數據獲取與加載
      • 2.3 定義網絡
      • 2.4 增強的數據預處理
      • 2.5 模型訓練
      • 2.6 測試準確率
      • 2.7 收集所有樣本的預測概率
      • 2.8 評價一下
        • 2.8.1 混淆矩陣
        • 2.8.2 精確 - 召回
        • 2.8.3 ROC曲線


1. 數據集介紹

1.1 數據集概述

數據集名稱:CIFAR-10
官方鏈接:https://www.cs.toronto.edu/~kriz/cifar.html
數據集簡介:
CIFAR-10 數據集是一個廣泛用于圖像分類任務的基準數據集,由 Alex Krizhevsky 在 2009 年創建,是計算機視覺領域最常用的數據集之一。它包含 60000 張 32x32 彩色圖像,分為 10 個不同的類別,每個類別有 6000 張圖片,其中 50000 張用于訓練模型,10000 張用于測試模型性能。

在這里插入圖片描述

1.2 數據集結構

  • 訓練集:包含 5 個批次,每個批次有 10000 張圖像。雖然訓練批次內圖像順序是隨機的,但各批次間圖像分布可能存在不均衡,即某些批次可能包含某一類別更多的圖片,但總體來說所有訓練批次合起來每個類別有 5000 張圖片。
  • 測試集:包含 1 個批次,有 10000 張圖像,每個類別在測試集中正好有 1000 張隨機選擇的圖片。
    數據集示例:
    CIFAR-10 的圖像涵蓋了多種常見的物體類別,具體類別包括:
  • plane(飛機):例如各種型號的飛機在不同場景下的圖片,如在天空飛行、停在機場等。
  • car(汽車):涵蓋不同品牌、款式和顏色的汽車,可能在道路上行駛或停在停車場。
  • bird(鳥):包含多種鳥類的圖片,如麻雀、鴿子等,可能處在飛翔或棲息狀態。
  • cat(貓):有不同品種、毛色和姿態的貓的圖像,比如家貓、波斯貓等。
  • deer(鹿):展示在野外環境中的鹿,如梅花鹿等。
  • dog(狗):包含各種品種的狗,如金毛犬、哈士奇等在不同場景下的圖片。
  • frog(蛙類):有不同種類青蛙的圖片,可能在水中、岸邊等環境。
  • horse(馬):展示不同品種馬的圖片,如在草原上奔跑或被飼養的場景。
  • ship(船):包含各種船只,如貨船、游輪等在水中的圖片。
  • truck(卡車):有不同類型的卡車,如貨運卡車、油罐車等的圖片。

1.3 數據集格式

  • 圖像像素:每個圖像都是 32x32 像素的彩色圖像,具有 RGB 三個通道(數據集中本身是 BGR 通道,但在使用時通常會轉換為 RGB 通道)。
  • 存儲格式:數據以 Python 拾取(pickle)文件的形式存儲,包含字典對象,其中包含圖像數據和標簽等信息。在使用時,通常需要通過 Python 的 pickle 庫加載數據,并將其轉換為 NumPy 數組等常用數據格式以便進行處理和訓練模型。

1.4 數據集應用場景

  • 圖像分類:CIFAR-10 最常見的應用場景是作為圖像分類任務的數據集,用于訓練和測試各種卷積神經網絡(CNN)模型,如 LeNet、AlexNet、ResNet 等,評估模型對不同類別圖像的識別準確率。
  • 模型評估與比較:作為標準數據集,方便研究者和開發者對比不同模型的性能,推動圖像識別技術的發展。
  • 遷移學習:可以作為預訓練模型的基礎數據集,通過在 CIFAR-10 上訓練得到的模型參數,遷移到其他類似的圖像分類任務中,減少新任務的數據量需求和計算資源消耗。
  • 深度學習研究:為深度學習算法的研究提供實驗平臺,例如研究新的網絡架構、優化算法、正則化方法等在 CIFAR-10 數據集上的效果。

1.5 數據集特點

優勢:

  • 典型性和代表性:涵蓋了多種常見的物體類別,能夠反映日常生活中的一些基本圖像分類場景,適用于研究和測試基礎的圖像識別模型。
  • 規模適中:60000 張圖像的數量對于現代計算資源來說既足夠大以提供有代表性的數據集,又不至于過于龐大而難以處理,適合在個人計算機或小型服務器上進行實驗和研究。
  • 數據多樣性:雖然圖像尺寸較小,但包含不同類別、顏色、姿態和背景的圖片,具有一定的數據多樣性,有助于模型學習到更通用的特征。

局限性:

  • 圖像尺寸較小:32x32 像素的圖像尺寸可能限制了模型對圖像細節的捕捉能力,對于一些需要精細識別的任務來說,可能不夠精確,例如對于圖像中一些微小特征或復雜紋理的識別。
  • 類別相對簡單:相較于一些更復雜的圖像數據集(如 ImageNet),CIFAR-10 的類別較為基礎,可能無法充分測試模型在面對高度復雜、多樣化的圖像內容時的性能。
  • 背景簡單:圖像中的物體通常具有相對簡單的背景,這可能使模型在處理更復雜背景或具有遮擋的圖像時表現不佳。

2. 實驗流程

2.1 導包

import torch  # 導入 PyTorch 框架,用于構建和訓練深度學習模型
import torch.nn as nn  # 導入 PyTorch 的神經網絡模塊,用于定義神經網絡結構
import torch.optim as optim  # 導入 PyTorch 的優化器模塊,用于定義優化算法(如 SGD、Adam 等)
import torchvision  # 導入 torchvision 庫,提供圖像處理和預訓練模型等功能
import torchvision.transforms as transforms  # 導入 torchvision 的數據預處理模塊,用于對圖像數據進行變換(如歸一化、裁剪等)
from torch.utils.data import DataLoader  # 導入 PyTorch 的數據加載器模塊,用于批量加載和管理數據集
from datetime import datetime 
import time 
# 畫圖相關
from sklearn.metrics import confusion_matrix
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np # 數據計算
from torch.nn.functional import softmax #softmax函數

2.2 數據獲取與加載

# 定義一個數據預處理的組合操作
transform = transforms.Compose([transforms.ToTensor(),  # 將圖像數據從 PIL 圖像格式轉換為 PyTorch 張量(Tensor),并將其值歸一化到 [0, 1] 范圍transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))  # 對圖像的每個通道進行標準化處理,均值為 0.5,標準差為 0.5
])# 加載 CIFAR-10 訓練數據集
trainset = torchvision.datasets.CIFAR10(root='./data4',  # 數據集存儲的根目錄路徑train=True,  # 指定加載訓練集download=False,  # 不從網絡下載數據集(假設數據已經下載到本地)transform=transform  # 應用上面定義的預處理操作
)# 加載 CIFAR-10 測試數據集
testset = torchvision.datasets.CIFAR10(root='./data4',  # 數據集存儲的根目錄路徑train=False,  # 指定加載測試集download=False,  # 不從網絡下載數據集(假設數據已經下載到本地)transform=transform  # 應用上面定義的預處理操作
)
# 定義每個批次的大小
batch_size = 64  # 每個批次包含 64 張圖像# 創建訓練數據的 DataLoader
trainloader = DataLoader(trainset,  # 指定加載的訓練數據集batch_size=batch_size,  # 每個批次的大小shuffle=True,  # 在每個 epoch 開始時隨機打亂數據順序num_workers=2  # 使用 2 個子進程加載數據,加速數據讀取
)# 創建測試數據的 DataLoader
testloader = DataLoader(testset,  # 指定加載的測試數據集batch_size=batch_size,  # 每個批次的大小shuffle=False,  # 測試時不需要打亂數據順序num_workers=2  # 使用 2 個子進程加載數據,加速數據讀取
)

2.3 定義網絡

這里我定義的是一個比較簡單的卷積神經網絡模型,包含特征提取層和分類器層,但是整體的效果也還行了,可以改成ResNet18或ResNet34

# 定義一個簡單的卷積神經網絡模型
class TestNet(nn.Module):def __init__(self, dropout_rate=0.5):super(TestNet, self).__init__()  # 調用父類的初始化方法# 特征提取部分self.features = nn.Sequential(  # 定義特征提取層的序列nn.Conv2d(3, 64, kernel_size=3, padding=1),  # 第一層卷積,輸入通道數為3,輸出通道數為64,卷積核大小為3x3,邊緣填充為1nn.BatchNorm2d(64),  # 對64個通道進行批量歸一化nn.ReLU(inplace=True),  # ReLU激活函數,inplace=True表示直接在原變量上操作,節省內存nn.Conv2d(64, 64, kernel_size=3, padding=1),  # 第二層卷積,輸入輸出通道數均為64nn.BatchNorm2d(64),  # 批量歸一化nn.ReLU(inplace=True),  # ReLU激活nn.MaxPool2d(2, 2),  # 最大池化,池化窗口大小為2x2,步長為2nn.Dropout2d(p=dropout_rate/2),  # 二維Dropout,隨機丟棄一半的特征圖,防止過擬合nn.Conv2d(64, 128, kernel_size=3, padding=1),  # 第三層卷積,輸入通道數為64,輸出通道數為128nn.BatchNorm2d(128),  # 批量歸一化nn.ReLU(inplace=True),  # ReLU激活nn.Conv2d(128, 128, kernel_size=3, padding=1),  # 第四層卷積,輸入輸出通道數均為128nn.BatchNorm2d(128),  # 批量歸一化nn.ReLU(inplace=True),  # ReLU激活nn.MaxPool2d(2, 2),  # 最大池化nn.Dropout2d(p=dropout_rate),  # Dropoutnn.Conv2d(128, 256, kernel_size=3, padding=1),  # 第五層卷積,輸入通道數為128,輸出通道數為256nn.BatchNorm2d(256),  # 批量歸一化nn.ReLU(inplace=True),  # ReLU激活nn.Conv2d(256, 256, kernel_size=3, padding=1),  # 第六層卷積,輸入輸出通道數均為256nn.BatchNorm2d(256),  # 批量歸一化nn.ReLU(inplace=True),  # ReLU激活nn.MaxPool2d(2, 2),  # 最大池化)# 分類器部分self.classifier = nn.Sequential(  # 定義分類器層的序列nn.Linear(256 * 4 * 4, 512),  # 全連接層,輸入特征數為256*4*4,輸出特征數為512nn.BatchNorm1d(512),  # 一維批量歸一化nn.ReLU(inplace=True),  # ReLU激活nn.Dropout(p=dropout_rate),  # Dropoutnn.Linear(512, 256),  # 全連接層,輸入特征數為512,輸出特征數為256nn.BatchNorm1d(256),  # 批量歸一化nn.ReLU(inplace=True),  # ReLU激活nn.Dropout(p=dropout_rate/2),  # Dropoutnn.Linear(256, 10)  # 最后一層全連接層,輸出10個類別)def forward(self, x):x = self.features(x)  # 將輸入數據通過特征提取層x = torch.flatten(x, 1)  # 將特征圖展平為一維向量,從第1維開始展平x = self.classifier(x)  # 將展平后的特征通過分類器層return x  # 返回最終的輸出

2.4 增強的數據預處理

# 定義訓練集的數據預處理操作
transform_train = transforms.Compose([transforms.RandomCrop(32, padding=4),  # 隨機裁剪,裁剪大小為32x32,邊緣填充為4transforms.RandomHorizontalFlip(),  # 隨機水平翻轉transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),  # 隨機調整亮度、對比度和飽和度transforms.ToTensor(),  # 將圖像轉換為張量transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),  # 標準化,均值和標準差分別為CIFAR-10數據集的均值和標準差
])# 定義測試集的數據預處理操作
transform_test = transforms.Compose([transforms.ToTensor(),  # 將圖像轉換為張量transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),  # 標準化
])
net = TestNet() # 初始化
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") # GPU
net.to(device)

2.5 模型訓練

# 開始訓練模型
start_time = time.time()  # 記錄訓練開始時間
for epoch in range(10):  # 訓練 10 個 epochrunning_loss = 0.0  # 初始化每輪的累計損失for i, data in enumerate(trainloader, 0):  # 遍歷訓練數據加載器inputs, labels = data[0].to(device), data[1].to(device)  # 將輸入數據和標簽移動到指定設備(如 GPU)optimizer.zero_grad()  # 清零梯度,避免梯度累積outputs = net(inputs)  # 前向傳播,計算模型輸出loss = criterion(outputs, labels)  # 計算損失值loss.backward()  # 反向傳播,計算梯度optimizer.step()  # 更新模型參數running_loss += loss.item()  # 累加損失值# 每 100 批次打印一次詳細信息if i % 100 == 99:  avg_loss = running_loss / 100  # 計算平均損失print(f'[Epoch {epoch + 1}/{10}, Batch {i + 1}/{len(trainloader)}] 'f'Average Loss: {avg_loss:.4f} | 'f'Current Batch Loss: {loss.item():.4f} | 'f'Running Loss: {running_loss:.4f}')running_loss = 0.0  # 重置累計損失scheduler.step()  # 更新學習率end_time = time.time()  # 記錄訓練結束時間
elapsed_time = end_time - start_time  # 計算總耗時
print(f'Finished Training. Total time taken: {elapsed_time:.2f} seconds')# 保存模型
timestamp = datetime.now().strftime("%y-%m-%d-%H-%M-%S")  # 獲取當前時間戳
model_name = f"CIFAR10Net-{timestamp}.pth"
torch.save(net.state_dict(), model_name)
print(f"Model saved successfully as {model_name}")

2.6 測試準確率

# 初始化正確預測的數量和測試數據的總數
correct_predictions = 0
total_samples = 0# 禁用梯度計算,節省內存和計算資源
with torch.no_grad():for data in testloader:  # 遍歷測試數據加載器images, labels = data[0].to(device), data[1].to(device)  # 將圖像和標簽移動到指定設備outputs = net(images)  # 前向傳播,獲取模型的輸出_, predicted_labels = torch.max(outputs.data, 1)  # 獲取預測的類別(概率最高的類別)total_samples += labels.size(0)  # 累加測試數據的總數correct_predictions += (predicted_labels == labels).sum().item()  # 累加正確預測的數量# 計算準確率
accuracy = 100 * correct_predictions / total_samples
print(f'Accuracy: {accuracy:.2f}%')  # 打印準確率

2.7 收集所有樣本的預測概率

import numpy as np
from torch.nn.functional import softmax# 初始化兩個列表,用于保存所有樣本的預測概率和真實標簽
all_preds = []  # 保存所有樣本的預測概率
all_labels = []  # 保存所有真實標簽# 使用torch.no_grad()上下文管理器,這可以暫時禁用計算圖中的梯度計算,節省內存和計算資源
with torch.no_grad():for data in testloader:  # 遍歷測試數據加載器testloaderimages, labels = data[0].to(device), data[1].to(device)  # 將圖像和標簽數據移動到指定的設備(如GPU)outputs = net(images)  # 通過神經網絡模型net獲取預測輸出probabilities = softmax(outputs, dim=1)  # 將輸出轉換為概率分布,dim=1表示在類別維度上進行softmax操作all_preds.append(probabilities.cpu().numpy())  # 將概率分布轉移到CPU并轉換為numpy數組,然后添加到all_preds列表中all_labels.append(labels.cpu().numpy())  # 將標簽數據轉移到CPU并轉換為numpy數組,然后添加到all_labels列表中# 合并所有批次的結果,使用numpy的concatenate函數沿著第一個軸(axis=0)合并數組
all_preds = np.concatenate(all_preds, axis=0)  # 形狀 [N, 10],其中N是樣本總數,10是類別數
all_labels = np.concatenate(all_labels, axis=0)  # 形狀 [N, ],其中N是樣本總數

2.8 評價一下

2.8.1 混淆矩陣
from sklearn.metrics import confusion_matrix  # 導入混淆矩陣計算函數
import seaborn as sns  # 導入seaborn庫,用于繪制熱圖
import matplotlib.pyplot as plt  # 導入matplotlib庫,用于繪圖# 初始化兩個列表,用于存儲模型預測的標簽和真實標簽
all_preds, all_labels = [], []# 使用torch.no_grad()來禁用梯度計算,因為在測試階段不需要計算梯度
with torch.no_grad():# 遍歷測試數據加載器for data in testloader:# 將圖像數據和標簽數據移動到設備上(如GPU)images, labels = data[0].to(device), data[1].to(device)# 將圖像數據輸入模型進行預測outputs = net(images)# 獲取模型輸出中概率最大的索引,即預測的類別_, predicted = torch.max(outputs, 1)# 將預測的類別和真實類別添加到列表中all_preds.extend(predicted.cpu().numpy())all_labels.extend(labels.cpu().numpy())# 計算混淆矩陣
cm = confusion_matrix(all_labels, all_preds)# 設置圖形的大小
plt.figure(figsize=(10, 8))
# 使用seaborn庫繪制熱圖,顯示混淆矩陣
# annot=True表示在每個單元格中顯示數值,fmt='d'表示數值格式為整數
# cmap='viridis'指定使用viridis配色方案
sns.heatmap(cm, annot=True, fmt='d', cmap='viridis')
plt.title('Confusion Matrix')
plt.xlabel('Predicted Labels')
plt.ylabel('True Labels')
plt.show()

在這里插入圖片描述

2.8.2 精確 - 召回
from sklearn.metrics import precision_recall_curve, auc
import matplotlib.pyplot as plt
import numpy as npn_classes = 10  # CIFAR10數據集有10個類別# 初始化字典來存儲每個類別的精確度、召回率和平均精確度
precision = dict()
recall = dict()
average_precision = dict()# 遍歷所有類別
for i in range(n_classes):# 提取第i類的概率作為預測分數,并生成對應的二分類標簽precision[i], recall[i], _ = precision_recall_curve((all_labels == i).astype(int), all_preds[:, i])average_precision[i] = auc(recall[i], precision[i])plt.figure(figsize=(12, 10), dpi=100)
colors = plt.cm.viridis(np.linspace(0, 1, n_classes))for i in range(n_classes):plt.plot(recall[i], precision[i], color=colors[i], lw=2, label=f'Class {i} (AP = {average_precision[i]:.2f})')
plt.xlabel('Recall', fontsize=14, fontfamily='serif')
plt.ylabel('Precision', fontsize=14, fontfamily='serif')
plt.title('Precision-Recall Curve for CIFAR10', fontsize=16, fontfamily='serif')
plt.legend(loc='best', fontsize=12, frameon=True)
plt.grid(True, linestyle='--', alpha=0.6)
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.savefig('precision_recall_curve.png', bbox_inches='tight')
plt.show()

在這里插入圖片描述

2.8.3 ROC曲線
from sklearn.preprocessing import label_binarize
from sklearn.metrics import roc_curve, auc
import matplotlib.pyplot as plt
import numpy as np# ROC曲線
all_labels_binarized = label_binarize(all_labels, classes=np.arange(n_classes))
all_preds_binarized = all_preds
fpr = dict()
tpr = dict()
roc_auc = dict()
for i in range(n_classes):fpr[i], tpr[i], _ = roc_curve(all_labels_binarized[:, i], all_preds_binarized[:, i])roc_auc[i] = auc(fpr[i], tpr[i])plt.figure(figsize=(12, 10), dpi=100)plt.gca().set_facecolor('#ADD8E6') 
colors = plt.cm.Reds(np.linspace(0.3, 1, n_classes))for i in range(n_classes):plt.plot(fpr[i], tpr[i], color=colors[i], lw=2, label=f'Class {i} (AUC = {roc_auc[i]:.2f})')plt.plot([0, 1], [0, 1], 'k--', lw=2, label='Random Guessing')plt.xlabel('False Positive Rate', fontsize=14, fontfamily='serif')
plt.ylabel('True Positive Rate', fontsize=14, fontfamily='serif')plt.title('ROC Curve for CIFAR10', fontsize=16, fontfamily='serif')plt.legend(loc='best', fontsize=12, frameon=True)plt.grid(True, linestyle='--', alpha=0.6, color='white')plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])plt.savefig('roc_curve_red.png', bbox_inches='tight')plt.show()

在這里插入圖片描述

在這里插入圖片描述

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

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

相關文章

C++復習類與對象基礎

類的成員函數為什么需要在類外定義 1.1 代碼組織與可讀性? ?類內定義?:適合 ?短小簡單的函數?(如 getter/setter),能直觀體現類的接口設計。 ?類外定義?:當函數體較復雜時,將實現移到類外&#xf…

【計算機網絡】Cookie、Session、Token之間有什么區別?

大家在日常使用瀏覽器時可能會遇到:是否清理Cookie?這個問題。 那么什么是Cookie呢?與此相關的還有Session、Token這些。這兩個又是什么呢? 本文將對這三個進行講解區分,如果對小伙伴有幫助的話,也請點贊、…

Python 3.x 內置裝飾器 (4) - @dataclass

dataclass 是Python 3.7 引入的一個裝飾器,用來簡化創建數據類(主要存儲數據的類)的過程。它會自動為類生成一些常用的方法,比如: __init__: 對象的初始化 __repr__: 定義類的官方字符串表示。 __eq__: 定義兩個對象…

第一次被AI指點出文章的問題

二十年,幾乎從未收到過這種程度的反饋。大部分意見都是有效的批評。 1.前言 關于鏈家左暉的一篇評論稿 這篇文章有什么問題嗎?所有方面都可以談,包括敘述,用詞,重復,真實性,偏見,…

var、let、const三者之間的區別和使用

var、let、const 都是用于聲明變量的關鍵字,可以通過作用域、可變性、變量提升幾個方面進行區分; 1,作用域 1)var的屬于函數作用域,只能在函數內使用。若在函數外部聲明變量,會變為全局變量; …

Consumer Group的作用是什么?Rebalance的觸發條件有哪些? (實現消費者負載均衡;消費者加入/離開、訂閱Topic變化等)

好的,我現在需要回答用戶關于Kafka Consumer Group和Rebalance的問題。首先,用戶問的是Consumer Group的作用以及Rebalance的觸發條件。根據之前的對話歷史,用戶已經了解了Kafka的基本組件、消息保留策略、順序性保證等,現在的問題…

出一期Source Insigned的使用教程

1. 創建新項目 打開 Source Insight,點擊菜單欄的 Project > New Project。在彈出的窗口中,輸入項目名稱(建議與項目內容相關,便于識別)。指定項目數據文件的存儲路徑(即 Source Insight 配置文件保存的…

A. Row GCD(gcd的基本性質)

Problem - 1458A - Codeforces 思路: 首先得知道gcd的兩個基本性質: (1) gcd(a,b)gcd(a,|b-a|) (2) gcd(a,b,c)gcd(a,gcd(b,c)) 結合題目所給的a1bj,a2bj...... anbj 根據第一條性質得到: gcd(a1bj,a2bj)gcd(…

ES6入門---第三單元 模塊三:async、await

async function fn(){ //表示異步:這個函數里面有異步任務 let result await xxx //表示后面結果需要等待 } 讀取文件里數據實例: const fs require(fs);//簡單封裝 fs封裝成一個promise const readFile function (fileName){return…

如何在 C# 和 .NET 中打印 DataGrid

DataGrid 是 .NET 架構中一個功能極其豐富的組件,或許也是最復雜的組件之一。寫這篇文章是為了回答“我到底該如何打印 DataGrid 及其內容”這個問題。最初即興的建議是使用我的屏幕截圖文章來截取表單,但這當然無法解決打印 DataGrid 中虛擬顯示的無數行…

C語言 指針(5)

目錄 1.冒泡排序 2.二級指針 3.指針數組 4.指針數組模擬二級數組 1.冒泡排序 1.1 基本概念 冒泡排序(Bubble Sort) 是一種簡單的排序算法,它重復地遍歷要排序的數列,一次比較兩個元 素,如果它們的順序錯誤就把它…

15前端項目----用戶信息/導航守衛

登錄/注冊 持久存儲用戶信息問題 退出登錄導航守衛解決問題 持久存儲用戶信息 本地存儲:(在actions中請求成功時) 添加localStorage.setItem(token,result.data.token);獲取存儲:(在user倉庫中,state中tok…

RSS 2025|斯坦福提出「統一視頻行動模型UVA」:實現機器人高精度動作推理

導讀 在機器人領域,讓機器人像人類一樣理解視覺信息并做出精準行動,一直是科研人員努力的方向。今天,我們要探討的統一視頻行動模型(Unified Video Action Model,UVA),就像給機器人裝上了一個“…

基于論文的大模型應用:基于SmartETL的arXiv論文數據接入與預處理(四)

上一篇介紹了基于SmartETL框架實現arxiv采集處理的基本流程,通過少量的組件定制開發,配合yaml流程配置,實現了復雜的arxiv采集處理。 由于其業務流程復雜,在實際應用中還存在一些不足需要優化。 5. 基于Kafka的任務解耦設計 5.…

Fiori學習專題三十五:Device Adaptation

由于在類似于手機的小面板上顯示時&#xff0c;我們為了留出更多空間展示數據&#xff0c;可以將一些控件折疊。 1.修改HelloPanel.view.xml&#xff0c;加入expandable“{device>/system/phone}” expanded"{ !${device>/system/phone} <mvc:ViewcontrollerNam…

【記錄】HunyuanVideo 文生視頻工作流

HunyuanVideo 文生視頻工作流指南 概述 本指南詳細介紹如何在ComfyUI中使用騰訊混元HunyuanVideo模型進行文本到視頻生成的全流程操作&#xff0c;包含環境配置、模型安裝和工作流使用說明。 參考&#xff1a;https://comfyui-wiki.com/zh/install/install-comfyui/install-c…

統一返回JsonResult踩坑

定義了一個統一返回類&#xff0c;但是沒有給Data 導致沒有get/set方法&#xff0c;請求一直報錯 public class JsonResult<T> {private int code;private String message;private T data;public JsonResult() {}public JsonResult(int code, String message, T data) {…

dubbo-token驗證

服務提供者過濾器 import java.util.Map; import java.util.Objects;/*** title ProviderTokenFilter* description 服務提供者 token 驗證* author zzw* version 1.0.0* create 2025/5/7 22:17**/ Activate(group CommonConstants.PROVIDER) public class ProviderTokenFilt…

沃倫森電氣高壓動態無功補償裝置助力企業電能優化

在工業生產的復雜電能環境中&#xff0c;電能質量直接影響企業的生產效率和運營成本。XX光伏科技有限公司作為一家快速發展的制造企業&#xff0c;隨著生產規模的不斷擴大&#xff0c;其內部電網面臨功率因數過低、電壓波動頻繁等問題&#xff0c;導致供電部門罰款增加、設備故…

基于EFISH-SCB-RK3576工控機/SAIL-RK3576核心板的網絡安全防火墻技術方案?(國產化替代J1900的全棧技術解析)

?基于EFISH-SCB-RK3576/SAIL-RK3576的網絡安全防火墻技術方案? &#xff08;國產化替代J1900的全棧技術解析&#xff09; ?一、硬件架構設計? ?流量處理核心模塊? ?多核異構架構?&#xff1a; ?四核Cortex-A72&#xff08;2.3GHz&#xff09;?&#xff1a;處理深度…