基于MNIST數據集的手寫數字識別(CNN)

目錄

一,模型訓練

1.1 數據集介紹

1.2 CNN模型層結構

1.3 定義CNN模型

1.4 神經網絡的前向傳播過程

1.5 數據預處理

1.6 加載數據

1.7 初始化

1.8 模型訓練過程

1.9 保存模型

二,模型測試

2.1?定義與訓練時相同的CNN模型架構

2.2 圖像的預處理

2.3 預測

三,測試

3.1 測試方法

3.2 測試結果

四 ,總結

五,完整代碼

5.1 模型訓練部分代碼

5.2 模型測試部分代碼


本實驗直觀地體現了CNN對比全連接對于圖像處理的優勢

全連接網絡實現MNIST數字識別實驗如下鏈接:

基于MNIST數據集的手寫數字識別(簡單全連接網絡)-CSDN博客


一,模型訓練

1.1 數據集介紹

????????MNIST 數據集由 60,000 張圖像構成的訓練集和 10,000 張圖像組成的測試集構成,其中的圖像均為 28×28 像素的灰度圖,涵蓋 0 - 9 這 10 個阿拉伯數字,且數字書寫風格、大小、位置多樣。它源于美國國家標準與技術研究所(NIST)的數據集,經過歸一化和中心化處理。MNIST 數據集是圖像識別研究領域的經典數據集,常用于開發和評估圖像識別算法與模型,也是機器學習課程中常用的教學案例,許多高性能卷積神經網絡模型在該數據集測試集上準確率可達 99% 以上,充分展現出其在機器學習領域的重要價值和廣泛應用。

1.2 CNN模型層結構

1.3 定義CNN模型

def __init__(self):super(CNN, self).__init__()  # 調用父類的初始化方法self.conv1 = nn.Conv2d(1, 32, kernel_size=3)  # 定義第一個卷積層,輸入通道1,輸出通道32,卷積核大小3x3self.conv2 = nn.Conv2d(32, 64, kernel_size=3)  # 定義第二個卷積層,輸入通道32,輸出通道64,卷積核大小3x3self.pool = nn.MaxPool2d(2, 2)  # 定義最大池化層,池化核大小2x2self.dropout1 = nn.Dropout2d(0.25)  # 定義第一個Dropout層,隨機丟棄25%的神經元self.fc1 = nn.Linear(64 * 12 * 12, 128)  # 定義第一個全連接層,輸入維度64*12*12,輸出維度128self.dropout2 = nn.Dropout(0.5)  # 定義第二個Dropout層,隨機丟棄50%的神經元self.fc2 = nn.Linear(128, 10)  # 定義輸出層,輸入維度128,輸出維度10(對應10個數字類別)

????????定義了一個用于手寫數字識別的卷積神經網絡(CNN)架構,專為 MNIST 等單通道圖像分類任務設計。網絡包含兩個卷積層(Conv1 和 Conv2)進行特征提取,每個卷積層后接 ReLU 激活函數和最大池化層(MaxPool2d)進行下采樣,逐步將 28×28 的輸入圖像轉換為更高層次的抽象特征。為防止過擬合,在卷積層后添加了 Dropout2d (0.25),在全連接層前使用 Dropout (0.5) 增強模型泛化能力。特征提取完成后,通過兩次全連接層(FC1 和 FC2)將卷積輸出的多維特征映射到 10 個類別,最終輸出對應 0-9 數字的分類得分。

1.4 神經網絡的前向傳播過程

    def forward(self, x):# 第一層卷積+ReLU激活x = torch.relu(self.conv1(x))# 第二層卷積+ReLU激活+池化x = self.pool(torch.relu(self.conv2(x)))# 應用Dropoutx = self.dropout1(x)# 將多維張量展平為一維向量(64*12*12)x = x.view(-1, 64 * 12 * 12)# 第一個全連接層+ReLU激活x = torch.relu(self.fc1(x))# 應用Dropoutx = self.dropout2(x)# 輸出層,得到未歸一化的預測分數x = self.fc2(x)return x

1.5 數據預處理

transform = transforms.Compose([transforms.ToTensor(),  # 將圖像轉換為張量transforms.Normalize((0.1307,), (0.3081,))  # 使用MNIST數據集的均值和標準差進行歸一化
])

1.6 加載數據

train_dataset = datasets.MNIST('data', train=True, download=True, transform=transform)  # 加載MNIST訓練數據集
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)  # 創建數據加載器,批次大小為64,打亂數據

1.7 初始化

model = CNN()  # 創建CNN模型實例
criterion = nn.CrossEntropyLoss()  # 定義交叉熵損失函數
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 定義Adam優化器,學習率為0.001

1.8 模型訓練過程

def train(epochs):model.train()  # 設置模型為訓練模式for epoch in range(epochs):  # 進行指定輪數的訓練running_loss = 0.0  # 初始化本輪的損失累加器for batch_idx, (data, target) in enumerate(train_loader):  # 遍歷數據加載器中的每個批次optimizer.zero_grad()  # 梯度清零output = model(data)  # 前向傳播,計算模型輸出loss = criterion(output, target)  # 計算損失loss.backward()  # 反向傳播,計算梯度optimizer.step()  # 更新模型參數running_loss += loss.item()  # 累加當前批次的損失if batch_idx % 100 == 0:  # 每100個批次打印一次損失print(f'Epoch {epoch + 1}, Batch {batch_idx}, Loss: {loss.item():.6f}')print(f'Epoch {epoch + 1} completed, Average Loss: {running_loss / len(train_loader):.6f}')  # 打印本輪平均損失

1.9 保存模型

if __name__ == '__main__':train(epochs=5)  # 調用訓練函數,訓練5輪torch.save(model.state_dict(),'mnist_cnn_model.pth')  # 保存模型的參數print("模型已保存為: mnist_cnn_model.pth")  # 打印保存模型的信息

二,模型測試

2.1?定義與訓練時相同的CNN模型架構

class CNN(nn.Module):def __init__(self):# 調用父類初始化方法super(CNN, self).__init__()# 第一個卷積層:輸入1通道(灰度圖),輸出32通道,卷積核3x3self.conv1 = nn.Conv2d(1, 32, kernel_size=3)# 第二個卷積層:輸入32通道,輸出64通道,卷積核3x3self.conv2 = nn.Conv2d(32, 64, kernel_size=3)# 最大池化層:核大小2x2,步長2self.pool = nn.MaxPool2d(2, 2)# Dropout層:訓練時隨機丟棄25%的神經元,防止過擬合self.dropout1 = nn.Dropout2d(0.25)# 第一個全連接層:輸入維度64*12*12,輸出128self.fc1 = nn.Linear(64 * 12 * 12, 128)# Dropout層:訓練時隨機丟棄50%的神經元self.dropout2 = nn.Dropout(0.5)# 輸出層:輸入128,輸出10個類別(對應0-9數字)self.fc2 = nn.Linear(128, 10)def forward(self, x):# 第一層卷積+ReLU激活x = torch.relu(self.conv1(x))# 第二層卷積+ReLU激活+池化x = self.pool(torch.relu(self.conv2(x)))# 應用Dropoutx = self.dropout1(x)# 將多維張量展平為一維向量(64*12*12)x = x.view(-1, 64 * 12 * 12)# 第一個全連接層+ReLU激活x = torch.relu(self.fc1(x))# 應用Dropoutx = self.dropout2(x)# 輸出層,得到未歸一化的預測分數x = self.fc2(x)return x

2.2 圖像的預處理

def preprocess_image(image_path):"""預處理自定義圖像,使其符合模型輸入要求"""# 打開圖像并轉換為灰度圖(單通道)image = Image.open(image_path).convert('L')# 調整圖像大小為28x28像素(如果不是)if image.size != (28, 28):image = image.resize((28, 28), Image.Resampling.LANCZOS)# 將PIL圖像轉換為numpy數組以便處理img_array = np.array(image)# 預處理:二值化和顏色反轉# MNIST數據集中數字為白色(255),背景為黑色(0)if img_array.mean() > 127:  # 如果平均像素值大于127,說明可能是黑底白字img_array = 255 - img_array  # 顏色反轉# 將numpy數組轉換為PyTorch張量并添加批次維度img_tensor = transforms.ToTensor()(img_array).unsqueeze(0)# 使用MNIST數據集的均值和標準差進行歸一化img_tensor = transforms.Normalize((0.1307,), (0.3081,))(img_tensor)return image, img_tensor  # 返回原始圖像和處理后的張量

2.3 預測

def predict_digit(image_path):"""預測自定義圖像中的數字"""# 創建模型實例model = CNN()# 加載預訓練模型權重model.load_state_dict(torch.load('mnist_cnn_model.pth'))# 設置模型為評估模式(關閉Dropout等訓練特有的層)model.eval()# 預處理輸入圖像original_img, img_tensor = preprocess_image(image_path)# 預測過程,不計算梯度以提高效率with torch.no_grad():# 前向傳播,得到模型輸出output = model(img_tensor)# 應用softmax將輸出轉換為概率分布probabilities = torch.softmax(output, dim=1)# 獲取最高概率及其對應的數字類別confidence, predicted = torch.max(probabilities, 1)

三,測試

3.1 測試方法

如上文代碼所示,我這里用的測試圖片是自己定義圖片,使用電腦自帶的paint繪圖軟件,設置畫布為28*28像素,黑底白字,手動寫入一個字進行預測

3.2 測試結果

????????預測5的置信度為99.94%

????????預測0的置信度為99.99%

????????預測7的置信度為92.33%(盡管這個“7”寫的很不好但是并不影響預測結果)


四 ,總結

????????卷積神經網絡(CNN)在圖像分類中相比全連接網絡(FNN)具有顯著優勢:通過局部連接權重共享機制,CNN 大幅減少參數量,避免全連接網絡因輸入維度高導致的參數爆炸問題,計算效率更高且不易過擬合;CNN 通過卷積核逐層提取圖像的局部特征(如邊緣、紋理),結合池化層的平移不變性,能自動學習從低級到高級的層級化語義特征,而全連接網絡將圖像展平為向量,完全忽略像素空間關系,需依賴人工特征或大量數據學習;此外,CNN 的卷積結構天然具備正則化效果,對數據量需求更低,訓練速度更快,且通過可視化卷積核和特征圖可直觀解釋其對圖像模式的捕捉過程,而全連接網絡的特征表示缺乏可解釋性。


五,完整代碼

5.1 模型訓練部分代碼

import torch  # 導入PyTorch庫,用于深度學習
import torch.nn as nn  # 導入PyTorch的神經網絡模塊
import torch.optim as optim  # 導入PyTorch的優化器模塊
from torchvision import datasets, transforms  # 從torchvision導入數據集和數據變換模塊
from torch.utils.data import DataLoader  # 導入數據加載器模塊# 定義CNN模型
class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()  # 調用父類的初始化方法self.conv1 = nn.Conv2d(1, 32, kernel_size=3)  # 定義第一個卷積層,輸入通道1,輸出通道32,卷積核大小3x3self.conv2 = nn.Conv2d(32, 64, kernel_size=3)  # 定義第二個卷積層,輸入通道32,輸出通道64,卷積核大小3x3self.pool = nn.MaxPool2d(2, 2)  # 定義最大池化層,池化核大小2x2self.dropout1 = nn.Dropout2d(0.25)  # 定義第一個Dropout層,隨機丟棄25%的神經元self.fc1 = nn.Linear(64 * 12 * 12, 128)  # 定義第一個全連接層,輸入維度64*12*12,輸出維度128self.dropout2 = nn.Dropout(0.5)  # 定義第二個Dropout層,隨機丟棄50%的神經元self.fc2 = nn.Linear(128, 10)  # 定義輸出層,輸入維度128,輸出維度10(對應10個數字類別)def forward(self, x):x = torch.relu(self.conv1(x))  # 對第一個卷積層的輸出應用ReLU激活函數x = self.pool(torch.relu(self.conv2(x)))  # 對第二個卷積層的輸出應用ReLU激活函數,然后進行最大池化x = self.dropout1(x)  # 應用第一個Dropout層x = x.view(-1, 64 * 12 * 12)  # 將張量展平為一維向量,-1表示自動推斷批次維度x = torch.relu(self.fc1(x))  # 對第一個全連接層的輸出應用ReLU激活函數x = self.dropout2(x)  # 應用第二個Dropout層x = self.fc2(x)  # 通過輸出層return x  # 返回模型的輸出# 數據預處理
transform = transforms.Compose([transforms.ToTensor(),  # 將圖像轉換為張量transforms.Normalize((0.1307,), (0.3081,))  # 使用MNIST數據集的均值和標準差進行歸一化
])# 加載數據
train_dataset = datasets.MNIST('data', train=True, download=True, transform=transform)  # 加載MNIST訓練數據集
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)  # 創建數據加載器,批次大小為64,打亂數據# 初始化模型、損失函數和優化器
model = CNN()  # 創建CNN模型實例
criterion = nn.CrossEntropyLoss()  # 定義交叉熵損失函數
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 定義Adam優化器,學習率為0.001# 訓練模型
def train(epochs):model.train()  # 設置模型為訓練模式for epoch in range(epochs):  # 進行指定輪數的訓練running_loss = 0.0  # 初始化本輪的損失累加器for batch_idx, (data, target) in enumerate(train_loader):  # 遍歷數據加載器中的每個批次optimizer.zero_grad()  # 梯度清零output = model(data)  # 前向傳播,計算模型輸出loss = criterion(output, target)  # 計算損失loss.backward()  # 反向傳播,計算梯度optimizer.step()  # 更新模型參數running_loss += loss.item()  # 累加當前批次的損失if batch_idx % 100 == 0:  # 每100個批次打印一次損失print(f'Epoch {epoch + 1}, Batch {batch_idx}, Loss: {loss.item():.6f}')print(f'Epoch {epoch + 1} completed, Average Loss: {running_loss / len(train_loader):.6f}')  # 打印本輪平均損失# 執行訓練并保存模型
if __name__ == '__main__':train(epochs=5)  # 調用訓練函數,訓練5輪torch.save(model.state_dict(),'mnist_cnn_model.pth')  # 保存模型的參數print("模型已保存為: mnist_cnn_model.pth")  # 打印保存模型的信息

5.2 模型測試部分代碼

# 導入PyTorch深度學習框架及其神經網絡模塊
import torch
import torch.nn as nn
# 導入torchvision的圖像變換工具
from torchvision import transforms
# 導入PIL庫用于圖像處理
from PIL import Image
# 導入matplotlib用于可視化
import matplotlib.pyplot as plt
# 導入numpy用于數值計算
import numpy as np
# 導入os模塊用于文件和路徑操作
import os# 設置matplotlib的字體,確保中文正常顯示
plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC']
plt.rcParams['axes.unicode_minus'] = False  # 解決負號顯示問題# 定義與訓練時相同的CNN模型架構
class CNN(nn.Module):def __init__(self):# 調用父類初始化方法super(CNN, self).__init__()# 第一個卷積層:輸入1通道(灰度圖),輸出32通道,卷積核3x3self.conv1 = nn.Conv2d(1, 32, kernel_size=3)# 第二個卷積層:輸入32通道,輸出64通道,卷積核3x3self.conv2 = nn.Conv2d(32, 64, kernel_size=3)# 最大池化層:核大小2x2,步長2self.pool = nn.MaxPool2d(2, 2)# Dropout層:訓練時隨機丟棄25%的神經元,防止過擬合self.dropout1 = nn.Dropout2d(0.25)# 第一個全連接層:輸入維度64*12*12,輸出128self.fc1 = nn.Linear(64 * 12 * 12, 128)# Dropout層:訓練時隨機丟棄50%的神經元self.dropout2 = nn.Dropout(0.5)# 輸出層:輸入128,輸出10個類別(對應0-9數字)self.fc2 = nn.Linear(128, 10)def forward(self, x):# 第一層卷積+ReLU激活x = torch.relu(self.conv1(x))# 第二層卷積+ReLU激活+池化x = self.pool(torch.relu(self.conv2(x)))# 應用Dropoutx = self.dropout1(x)# 將多維張量展平為一維向量(64*12*12)x = x.view(-1, 64 * 12 * 12)# 第一個全連接層+ReLU激活x = torch.relu(self.fc1(x))# 應用Dropoutx = self.dropout2(x)# 輸出層,得到未歸一化的預測分數x = self.fc2(x)return xdef preprocess_image(image_path):"""預處理自定義圖像,使其符合模型輸入要求"""# 打開圖像并轉換為灰度圖(單通道)image = Image.open(image_path).convert('L')# 調整圖像大小為28x28像素(如果不是)if image.size != (28, 28):image = image.resize((28, 28), Image.Resampling.LANCZOS)# 將PIL圖像轉換為numpy數組以便處理img_array = np.array(image)# 預處理:二值化和顏色反轉# MNIST數據集中數字為白色(255),背景為黑色(0)if img_array.mean() > 127:  # 如果平均像素值大于127,說明可能是黑底白字img_array = 255 - img_array  # 顏色反轉# 將numpy數組轉換為PyTorch張量并添加批次維度img_tensor = transforms.ToTensor()(img_array).unsqueeze(0)# 使用MNIST數據集的均值和標準差進行歸一化img_tensor = transforms.Normalize((0.1307,), (0.3081,))(img_tensor)return image, img_tensor  # 返回原始圖像和處理后的張量def predict_digit(image_path):"""預測自定義圖像中的數字"""# 創建模型實例model = CNN()# 加載預訓練模型權重model.load_state_dict(torch.load('mnist_cnn_model.pth'))# 設置模型為評估模式(關閉Dropout等訓練特有的層)model.eval()# 預處理輸入圖像original_img, img_tensor = preprocess_image(image_path)# 預測過程,不計算梯度以提高效率with torch.no_grad():# 前向傳播,得到模型輸出output = model(img_tensor)# 應用softmax將輸出轉換為概率分布probabilities = torch.softmax(output, dim=1)# 獲取最高概率及其對應的數字類別confidence, predicted = torch.max(probabilities, 1)# 創建可視化窗口plt.figure(figsize=(12, 4))# 子圖1:顯示原始輸入圖像plt.subplot(1, 3, 1)plt.imshow(original_img, cmap='gray')plt.title('原始圖像')plt.axis('off')  # 關閉坐標軸顯示# 子圖2:顯示模型實際輸入(歸一化后的圖像)plt.subplot(1, 3, 2)plt.imshow(img_tensor[0][0], cmap='gray')plt.title('模型輸入')plt.axis('off')# 子圖3:顯示預測結果和置信度條形圖plt.subplot(1, 3, 3)plt.bar(range(10), probabilities[0].numpy())plt.xticks(range(10))  # 設置x軸刻度為0-9plt.title(f'預測結果: {predicted.item()} (置信度: {confidence.item() * 100:.2f}%)')plt.xlabel('數字')plt.ylabel('概率')# 自動調整子圖布局plt.tight_layout()# 顯示圖像plt.show()# 返回預測結果和置信度return predicted.item(), confidence.item() * 100if __name__ == '__main__':# 指定要測試的圖像路徑,請替換為實際路徑image_path = r"C:\Users\10532\Desktop\Study\test\Untitled.png"# 檢查文件是否存在if not os.path.exists(image_path):print(f"錯誤:文件 '{image_path}' 不存在")else:# 執行預測digit, confidence = predict_digit(image_path)print(f"預測結果: {digit},置信度: {confidence:.2f}%")

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

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

相關文章

centos中postfix的作用

/usr/libexec/postfix/master 是 Postfix 郵件服務器的主進程,qmgr 和 pickup 是 Postfix 的子進程。這些進程本身是正常的,但如果你懷疑服務器被用于釣魚活動,需要進一步檢查 Postfix 的配置和日志,確保它沒有被濫用。 1. 檢查 P…

藍牙耳機什么牌子好?倍思值得沖不?

最近總被問“藍牙耳機什么牌子好”,作為踩過無數坑的資深耳機黨,必須安利剛入手的倍思M2s Pro主動降噪藍牙耳機!降噪、音質、顏值全都在線,性價比直接拉滿。 -52dB降噪,通勤摸魚神器 第一次開降噪就被驚到&#xff01…

游戲引擎學習第285天:“Traversables 的事務性占用”

回顧并為當天的工作做準備 我們有一個關于玩家移動的概念,玩家可以在點之間移動,而且當這些點移動時,玩家會隨之移動。現在這個部分基本上已經在工作了。我們本來想實現的一個功能是:當玩家移動到某個點時,這個點能“…

java中的包機制

包機制 為了更好地組織類,java提供了包機制,用于區分類名的命名空間 包語句的語法格式為 package pkg1[. pkg2[. pkg3...]]一般利用公司域名倒置作為包名 : 公司域名:www.baidu.com 包名:com.baidu.www 為了能夠…

python打卡DAY22

##注入所需庫 import pandas as pd import seaborn as sns import matplotlib.pyplot as plt import random import numpy as np import time import shap # from sklearn.svm import SVC #支持向量機分類器 # # from sklearn.neighbors import KNeighborsClassifier …

CodeBuddy 開發 JSON 可視化工具實錄:JsonVision 的誕生之旅

我正在參加CodeBuddy「首席試玩官」內容創作大賽,本文所使用的 CodeBuddy 免費下載鏈接:騰訊云代碼助手 CodeBuddy - AI 時代的智能編程伙伴 🧭 項目起點:一個靈光一現的念頭 在日常的前端開發中,我時常需要調試復雜的…

Redis學習專題(一)配置和持久化

目錄 一.配置Redis 1.配置application.properties 2. 配置Config 3.測試連接redis 二、Redis持久化 持久化方案 RDB: 1、RDB基礎認識 1、具體流程如下: 3、小結: 3、Fork&Copy-On-Write 4、RDB的配置 5、默認快照的配置 6、…

[ctfshow web入門] web77

信息收集 上一題的讀取flag方式不能用了,使用后的回顯是:could not find driver 解題 同樣的查目錄方法 cvar_export(scandir("glob:///*"));die();cforeach(new DirectoryIterator("glob:///*") as $a){echo($a->__toString…

每日算法刷題Day8 5.16:leetcode定長滑動窗口4道題,用時1h

5. 2379.得到k個黑塊的最少涂色次數(簡單) 2379. 得到 K 個黑塊的最少涂色次數 - 力扣(LeetCode) 思想 1.返回至少出現 一次 連續 k 個黑色塊的 最少 操作次數 2.還是定長k,統計量就是把白色變成黑色的操作次數,無需記錄當前有…

很啰嗦,再次總結 DOM

DOM (文檔對象模型) 詳解 一、DOM 基礎概念 1. 定義與作用 DOM(Document Object Model)即文檔對象模型,是一種用于 HTML 和 XML 文檔的編程接口。它將文檔解析為一個由節點和對象組成的樹狀結構,允許程序和腳本動態訪問、修改文…

ES6 (ECMAScript 2015) 詳解

文章目錄 一、ES6簡介1.1 什么是ES6?1.2 為什么要學習ES6?1.3 瀏覽器支持情況 二、let和const關鍵字2.1 let關鍵字2.2 const關鍵字2.3 var、let和const的選擇 三、箭頭函數3.1 基本語法3.2 箭頭函數的特點3.3 何時使用箭頭函數 四、模板字符串4.1 基本語…

LeetCode 746 使用最小花費爬樓梯

當然可以!LeetCode 746 是一道經典的動態規劃入門題,我來用 C 為你詳細解釋。 題目描述 給定一個整數數組 cost,其中每個元素 cost[i] 表示從第 i 個臺階向上爬需要支付的費用。一旦支付費用,你可以選擇向上爬 1 步 或 2 步。 你…

6.1.1圖的基本概念

基本概念 圖: 頂點集邊集 頂點集:所有頂點的集合,不能為空(因為圖是頂點集和邊集組成,其中一個頂點集不能為空,則圖肯定不為空) 邊集:所有邊的集合,邊是由頂點集中的2…

WeakAuras Lua Script [TOC BOSS 5 - Anub‘arak ]

WeakAuras Lua Script [TOC BOSS 5 - Anubarak ] 阿努巴拉克 - 小強中蟲范圍 插件 !WA:2!DE1B0Xrvv8UmuRmIqZwiaXQmgKycwsYUPjPLZPTz3nBYULKnBNDtlYP6o)7T7mMzNz6BMnnBefBqGacIUOsXIkSIki)rCbLkIhLi6h8t3to6h9G2dXt4R9d(rR33mt2MyepQ75KSV3BUZ9FV7VF37g54rDvgU)yX7)GrRgvlQ2Y…

【C/C++】深度探索c++對象模型_筆記

1. 對象內存布局 (1) 普通類(無虛函數) 成員變量排列:按聲明順序存儲,但編譯器會根據內存對齊規則插入填充字節(padding)。class Simple {char a; // 1字節(偏移0)int b; …

湖北理元理律師事務所:債務優化中的雙維支持實踐解析

在債務壓力與生活質量失衡的社會議題下,法律服務機構的功能邊界正在從單一的法律咨詢向復合型支持延伸。湖北理元理律師事務所通過“法律心理”雙維服務模式,探索債務優化與生活保障的平衡路徑,其方法論或為行業提供實踐參考。 法律框架&…

Python uv包管理器使用指南:從入門到精通

Python uv包管理器使用指南:從入門到精通 作為一名Python開發者,你是否曾經為虛擬環境管理和依賴包安裝而頭疼?今天我要向大家介紹一個強大的工具——uv包管理器,它將徹底改變你的Python開發體驗。 什么是uv包管理器&#xff1f…

Windows系統安全加固

掌握的加固點: 用戶系統檢查 口令策略檢查 日志審計檢查 安全選項檢查 信息保護檢查 2.2.1 用戶系統檢查 #檢查系統版本內核 判斷依據:無 檢查方式:命令 msinfo32 dxdiag查看 #檢查Administrator賬號是否停用 判斷依據:禁…

小蝸牛撥號助手用戶使用手冊

一、軟件簡介 小蝸牛撥號助手是一款便捷實用的撥號輔助工具,能自動識別剪貼板中的電話號碼,支持快速撥號操作。最小化或關閉窗口后,程序將在系統后臺運行,還可設置開機自啟,方便隨時使用,提升撥號效率。 …

c/c++消息隊列庫RabbitMQ的使用

RabbitMQ C 消息隊列組件設計與實現文檔 1. 引言 1.1. RabbitMQ 簡介 RabbitMQ 是一個開源的消息代理軟件(也稱為面向消息的中間件),它實現了高級消息隊列協議(AMQP)。RabbitMQ 服務器是用 Erlang 語言編寫的&#…