第 4 章:第一個神經網絡實戰——使用 PyTorch

第 4 章:第一個神經網絡實戰——使用 PyTorch

在這里插入圖片描述

經過前三章的學習,我們已經對神經網絡的理論基礎有了扎實的理解。我們知道數據如何前向傳播,如何用損失函數評估預測,以及如何通過梯度下降和反向傳播來更新網絡參數。

理論是根基,但真正的樂趣在于實踐。從本章開始,我們將走出理論的殿堂,親手用代碼構建、訓練并評估一個真正的神經網絡。

我們將使用的工具是 PyTorch,一個由 Facebook 人工智能研究院(FAIR)開發和維護的、當今最流行、最強大的深度學習框架之一。

在本章中,我們將一起完成以下任務:

  1. 環境搭建:安裝 PyTorch 并配置好我們的開發環境。
  2. 數據加載:加載并處理經典的 MNIST 手寫數字數據集。
  3. 模型構建:使用 PyTorch 的 nn 模塊定義我們的神經網絡結構。
  4. 模型訓練:編寫訓練循環,實現我們學過的"前向傳播 -> 計算損失 -> 反向傳播 -> 更新參數"的完整流程。
  5. 模型評估與預測:在測試數據上檢驗我們模型的性能,并用它來進行預測。

準備好將理論轉化為現實了嗎?讓我們開始吧!

4.1 PyTorch:優雅的深度學習利器

在我們開始編碼之前,先簡單了解一下為什么選擇 PyTorch。

PyTorch 之所以備受學術界和工業界的青睞,主要有以下幾個原因:

  • Pythonic: 它的設計哲學與 Python 高度契合,代碼直觀、易于上手,調試也相對簡單。
  • 動態計算圖: 與一些早期框架的靜態圖不同,PyTorch 的計算圖是動態的。這意味著你可以在運行時改變網絡結構,這為復雜的模型設計提供了極大的靈活性。
  • 強大的生態系統: 擁有豐富的庫(如 torchvision 用于圖像處理,torchaudio 用于音頻處理)和活躍的社區支持。
  • 無縫的 CPU/GPU 切換: 可以非常方便地將計算任務在 CPU 和 GPU 之間切換。

PyTorch 的核心是 張量(Tensor),它是一種多維數組,與我們熟知的 NumPy ndarray 非常相似,但它有一個關鍵的超能力:可以在 GPU 上進行計算以加速運算。此外,PyTorch 的 自動求導機制(Autograd) 會自動為我們處理所有與梯度相關的計算,讓我們從反向傳播的復雜數學中解放出來。

環境搭建

現在,讓我們來安裝 PyTorch。官方推薦使用 condapip進行安裝。最穩妥的方式是訪問 PyTorch 官網的 “Get Started” 頁面,根據你的操作系統(Windows/Mac/Linux)、包管理器(Conda/Pip)、計算平臺(CPU/CUDA版本)來生成最適合你系統的安裝命令。

對于大多數沒有 NVIDIA GPU 的用戶,一個典型的 CPU 版本 安裝命令如下(使用 pip):

pip install torch torchvision torchaudio

強烈建議 您訪問官網獲取最準確的命令。

安裝完成后,你可以在 Python 解釋器或腳本中通過以下代碼來驗證安裝是否成功:

import torch# 打印 PyTorch 版本
print(f"PyTorch Version: {torch.__version__}")# 創建一個張量
x = torch.rand(5, 3)
print("A random tensor:")
print(x)# 檢查是否有可用的 GPU
is_cuda_available = torch.cuda.is_available()
print(f"CUDA (GPU) Available: {is_cuda_available}")if is_cuda_available:print(f"CUDA Device Name: {torch.cuda.get_device_name(0)}")

如果代碼能夠順利運行并打印出版本號和張量,那么恭喜你,PyTorch 環境已經準備就緒!

在接下來的章節中,我們將使用 Jupyter Notebook 或類似的交互式環境進行編碼,這非常適合數據科學和機器學習的探索性工作。

4.2 數據準備:加載與變換 MNIST

在機器學習中,數據是驅動一切的燃料。對于我們的第一個項目,我們將使用 MNIST 數據集,這是一個包含了 70,000 張 28x28 像素的手寫數字灰度圖像的集合(60,000 張用于訓練,10,000 張用于測試),由美國國家標準與技術研究院整理。它是圖像分類領域的"Hello, World!"。

幸運的是,torchvision 庫讓我們可以極其方便地獲取和使用它。

1. 定義數據變換

在將圖像送入模型之前,我們通常需要進行一些預處理。最常見的兩個步驟是:

  • 轉換為張量:將 PIL 圖像或 NumPy ndarray 轉換為 PyTorch 的 Tensor 格式。
  • 歸一化 (Normalization):將張量的像素值從 [0, 255] 的范圍縮放到一個更小的、以 0 為中心的范圍,例如 [-1, 1]。這有助于加速模型收斂并提高性能。

我們可以使用 torchvision.transforms.Compose 將這些操作串聯起來。

from torchvision import datasets, transforms# 定義一個轉換流程
transform = transforms.Compose([transforms.ToTensor(),  # 將圖片轉換為張量,并將像素值從 [0, 255] 歸一化到 [0.0, 1.0]transforms.Normalize((0.5,), (0.5,))  # 將 [0.0, 1.0] 的范圍歸一化到 [-1.0, 1.0]
])

注:對于 MNIST 這樣的灰度圖,其均值(Mean)和標準差(Standard Deviation)都接近 0.5,所以我們使用 (0.5,) 作為歸一化參數。

2. 下載并加載數據集

現在我們可以使用 datasets.MNIST 來下載并創建我們的訓練集和測試集了。

# 下載訓練數據集
train_dataset = datasets.MNIST(root='./data',    # 數據存放的根目錄train=True,       # 指定這是訓練集download=True,    # 如果 `./data` 目錄下沒有數據,就自動下載transform=transform  # 應用我們剛剛定義的轉換
)# 下載測試數據集
test_dataset = datasets.MNIST(root='./data',train=False,      # 指定這是測試集download=True,transform=transform
)

3. 創建數據加載器(DataLoader)

直接在完整的數據集上進行迭代效率很低。我們通常希望分批次(mini-batch)地、并且隨機地給模型喂數據。torch.utils.data.DataLoader 正是為此而生。

DataLoader 是一個迭代器,它將數據集封裝起來,為我們提供了批處理、數據打亂、并行加載等一系列功能。

from torch.utils.data import DataLoader# 定義批次大小
batch_size = 64# 創建訓練數據加載器
train_loader = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True  # 打亂數據,這在訓練時非常重要
)# 創建測試數據加載器
test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=False # 測試時通常不需要打亂數據
)

4. 可視化我們的數據

為了更直觀地感受我們正在處理的數據,讓我們來看一下訓練集中的一些圖片。

import matplotlib.pyplot as plt
import numpy as np# 從訓練數據加載器中獲取一個批次的數據
dataiter = iter(train_loader)
images, labels = next(dataiter)# images.shape 會是 [64, 1, 28, 28],代表 (批次大小, 通道數, 高, 寬)# 創建一個 8x8 的網格來顯示圖片
fig, axes = plt.subplots(8, 8, figsize=(10, 10))
for i, ax in enumerate(axes.flat):# 顯示圖片# 我們需要將 Normalize 的效果反轉回來以便正確顯示img = images[i].numpy().squeeze() # 去掉通道維度ax.imshow(img, cmap='gray')# 顯示標簽ax.set_title(labels[i].item())ax.axis('off')plt.tight_layout()
plt.show()

運行這段代碼,你應該能看到一個 8x8 的網格,里面是各種手寫數字的圖片及其對應的標簽。

到此為止,我們已經成功地將數據準備就緒。下一步,我們將利用這些數據來構建和定義我們的第一個神經網絡模型。

4.3 模型構建:定義你的神經網絡

數據已經就位,現在是時候構建我們的大腦——神經網絡模型了。在 PyTorch 中,任何自定義的模型都是通過創建一個繼承自 torch.nn.Module 的類來實現的。這個基類為我們提供了模型追蹤、參數管理等一系列底層功能。

我們的模型需要完成以下任務:

  1. 接收一個被"壓平"的 28x28 像素圖像(即一個長度為 784 的一維向量)作為輸入。
  2. 通過幾個全連接的線性層(nn.Linear)進行變換。
  3. 在層與層之間使用非線性激活函數(例如 ReLU)來增加模型的表達能力。
  4. 最終輸出一個包含 10 個值的向量,每個值代表輸入圖像是 0 到 9 這 10 個數字中某一個的"得分"或"對數概率"(logits)。

1. 定義模型類

讓我們來創建一個名為 SimpleMLP(簡單多層感知機)的類。

import torch.nn as nn
import torch.nn.functional as Fclass SimpleMLP(nn.Module):def __init__(self):# 首先,調用父類的 __init__ 方法super(SimpleMLP, self).__init__()# 定義網絡的層次結構# 輸入層:784 個特征 (28*28)# 第一個隱藏層:128 個神經元self.fc1 = nn.Linear(28 * 28, 128)# 第二個隱藏層:64 個神經元self.fc2 = nn.Linear(128, 64)# 輸出層:10 個神經元,對應 10 個類別self.fc3 = nn.Linear(64, 10)def forward(self, x):# 定義數據在前向傳播中的流動方式# 1. 壓平輸入圖像# x 的原始 shape: [batch_size, 1, 28, 28]# x.view(-1, 28 * 28) 會將其轉換為 [batch_size, 784]x = x.view(-1, 28 * 28)# 2. 通過第一個隱藏層,并應用 ReLU 激活函數x = F.relu(self.fc1(x))# 3. 通過第二個隱藏層,并應用 ReLU 激活函數x = F.relu(self.fc2(x))# 4. 通過輸出層# 這里我們不需要應用 softmax,因為 nn.CrossEntropyLoss 會為我們處理x = self.fc3(x)return x

在這個類中:

  • __init__ 方法負責"聲明"模型中所有需要學習參數的層。我們定義了三個線性層 fc1, fc2, fc3 (fc = fully connected)。
  • forward 方法則像一張流程圖,它接收輸入張量 x,并精確地定義了 x 是如何一步步流過我們在 __init__ 中聲明的各個部分的。

2. 實例化并查看模型

現在我們可以輕松地創建這個模型的一個實例,并打印它來查看其結構。

# 創建模型實例
model = SimpleMLP()# 打印模型結構
print(model)

運行后,你將看到一個清晰的、描述我們模型結構的輸出:

SimpleMLP((fc1): Linear(in_features=784, out_features=128, bias=True)(fc2): Linear(in_features=128, out_features=64, bias=True)(fc3): Linear(in_features=64, out_features=10, bias=True)
)

這告訴我們模型由三個線性層組成,并清晰地標明了每一層的輸入和輸出特征數。PyTorch 已經自動為我們處理了每一層權重和偏置的初始化。

下面是我們剛剛定義的 SimpleMLP 模型的結構示意圖:

在這里插入圖片描述

圖 4.1: 一個全連接神經網絡的結構示意圖。我們的模型與之類似,輸入層接收壓平的圖像數據(784個節點),經過兩個隱藏層(128和64個節點),最終由輸出層(10個節點)得出分類結果。

現在,我們的模型、數據都已經準備就緒。在把它們投入訓練的熔爐之前,我們還需最后兩個關鍵組件:

  1. 損失函數(Loss Function / Criterion):定義了我們優化的"目標"。它會衡量模型輸出與真實標簽之間的差距。
  2. 優化器(Optimizer):定義了我們實現優化的"方法"。它會根據損失函數計算出的梯度,來更新模型的權重。

1. 損失函數

對于像 MNIST 這樣的多分類問題,torch.nn.CrossEntropyLoss 是最理想的選擇。它是一個非常強大的損失函數,其內部幫我們集成了兩個步驟:

  1. nn.LogSoftmax():將模型的原始輸出(logits)轉換成對數概率。
  2. nn.NLLLoss()(Negative Log Likelihood Loss):計算這些對數概率與真實標簽之間的負對數似然損失。

組合在一起,它就能非常有效地衡量我們的分類模型表現有多糟糕。我們的目標就是讓這個損失值盡可能地小。

# 定義損失函數
criterion = nn.CrossEntropyLoss()

2. 優化器

優化器負責執行梯度下降算法。PyTorch 在 torch.optim 模塊中提供了多種優化算法的實現,如 SGD, Adam, RMSprop 等。

我們將使用 Adam(Adaptive Moment Estimation),它是一種非常流行且通常表現優異的優化算法,它會為每個參數獨立地計算自適應學習率。

在創建優化器時,我們需要告訴它兩件事:

  1. 哪些參數需要被優化:我們可以通過調用 model.parameters() 來輕松獲取模型中所有需要學習的參數。
  2. 學習率(Learning Rate):這是梯度下降中最重要的超參數之一,它控制了每次參數更新的步長。我們先從一個常用的值 0.001 開始。
from torch import optim# 定義優化器,并將模型參數傳遞給它
# lr = learning rate (學習率)
optimizer = optim.Adam(model.parameters(), lr=0.001)

至此,所有零件都已準備齊全:我們有了數據(DataLoader)、有了模型(SimpleMLP),有了衡量標準(CrossEntropyLoss),也有了更新方法(Adam)。

下一節,我們將把所有這些組件組裝起來,構建最終的訓練循環,真正開始訓練我們的模型!

4.5 訓練循環:讓模型學習起來

終于,我們來到了最激動人心的部分。我們將把之前準備的所有組件——數據、模型、損失函數、優化器——全部投入到這個訓練循環中,讓模型真正地開始學習。

訓練過程通常包含多個 輪次(Epochs)。一個 Epoch 指的是我們的模型完整地看過一遍訓練集中的所有數據。我們會訓練多個 Epochs,因為模型需要反復地從數據中學習,才能逐漸優化其內部的參數。

在每一個 Epoch 內部,我們會分批次(mini-batch)地將數據喂給模型,并執行我們爛熟于心的學習五部曲。

訓練代碼

下面是完整的訓練循環代碼。它看起來可能有點長,但其核心正是我們反復強調的五個步驟。

# 定義訓練的輪次
epochs = 15# 記錄訓練過程中的損失
train_losses = []print("開始訓練...")
for e in range(epochs):running_loss = 0# 內層循環:遍歷訓練數據加載器,獲取每個批次的數據for images, labels in train_loader:# 步驟 1: 梯度清零# 這是非常重要的一步,因為PyTorch默認會累積梯度optimizer.zero_grad()# 步驟 2: 前向傳播# 將一個批次的圖像數據輸入模型,得到預測輸出(logits)output = model(images)# 步驟 3: 計算損失# 比較模型的預測輸出和真實的標簽loss = criterion(output, labels)# 步驟 4: 反向傳播# 計算損失相對于模型所有參數的梯度loss.backward()# 步驟 5: 更新參數# 優化器根據梯度更新模型的權重optimizer.step()# 累加批次損失running_loss += loss.item()# 每個 Epoch結束后,打印一次平均損失epoch_loss = running_loss / len(train_loader)train_losses.append(epoch_loss)print(f"訓練輪次 {e+1}/{epochs}.. "f"訓練損失: {epoch_loss:.3f}")print("訓練完成!")

當你運行這段代碼時,你會看到損失值隨著訓練輪次的增加而穩步下降。這表明我們的模型正在從數據中學習,它對數字的預測正變得越來越準確!

例如,你可能會看到類似這樣的輸出:

開始訓練...
訓練輪次 1/15.. 訓練損失: 0.383
訓練輪次 2/15.. 訓練損失: 0.160
訓練輪次 3/15.. 訓練損失: 0.116
...
訓練輪次 15/15.. 訓練損失: 0.026
訓練完成!

這個不斷下降的損失值,就是我們所有理論知識和代碼工作的最好回報。

我們可以將記錄下來的 train_losses 繪制成圖表,來更直觀地觀察學習過程。

import matplotlib.pyplot as pltplt.plot(train_losses, label='Training loss')
plt.title('Loss over time')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.grid(True)
plt.show()

在這里插入圖片描述

圖 4.2: 訓練損失隨訓練輪次(Epochs)變化的曲線。可以看到損失值迅速下降并逐漸趨于平穩,這表明模型正在有效地學習。

我們的模型已經學有所成。但它究竟學得怎么樣?口說無憑,我們需要在它從未見過的數據(測試集)上檢驗它的真實能力。這就是我們最后一節要做的事情:模型評估與預測。

4.6 模型評估與預測:見證成果的時刻

模型訓練完成,但它的表現如何?訓練損失低并不完全代表模型泛化能力強。我們需要在獨立的測試集上評估其性能,這才是衡量模型真實水平的黃金標準。

1. 模型評估

評估過程與訓練過程非常相似,但有幾個關鍵區別:

  1. 開啟評估模式:我們需要調用 model.eval()。這會告訴模型中的特定層(如 Dropout, BatchNorm)它們現在處于評估模式,其行為應與訓練時不同。對于我們這個簡單模型,雖然沒有這些層,但這始終是一個好習慣。
  2. 關閉梯度計算:在評估時,我們不需要計算梯度,這可以大大加快計算速度并節省內存。我們可以使用 with torch.no_grad(): 上下文管理器來包裹我們的評估代碼。

我們將計算模型在整個測試集上的準確率(Accuracy)

# 準備評估
correct_count, all_count = 0, 0
print("開始評估...")
model.eval() # 切換到評估模式with torch.no_grad(): # 關閉梯度計算for images, labels in test_loader:# 對每個批次進行預測for i in range(len(labels)):img = images[i].view(1, 784)log_ps = model(img) # 獲取 log-probabilities# 將 log-probabilities 轉換為真實概率ps = torch.exp(log_ps)# 獲取概率最高的類別作為預測結果probab = list(ps.numpy()[0])pred_label = probab.index(max(probab))# 與真實標簽比較true_label = labels.numpy()[i]if(true_label == pred_label):correct_count += 1all_count += 1print(f"測試集圖片總數: {all_count}")
print(f"模型準確率 = {(correct_count/all_count):.3f}")

運行后,你可能會看到一個非常喜人的結果,比如 模型準確率 = 0.975。這意味著我們的模型在它從未見過的 10,000 張圖片中,有 97.5% 的概率能夠正確識別出數字!對于一個如此簡單的模型來說,這是一個非常出色的成績。

除了計算總體準確率,我們還可以使用 混淆矩陣(Confusion Matrix) 來更深入地分析模型的性能。混淆矩陣可以清晰地展示出模型對于每個類別的分類情況,尤其是哪些類別之間容易被混淆。

from sklearn.metrics import confusion_matrix
import seaborn as sns# 重新獲取所有預測和標簽用于生成混淆矩陣
y_pred = []
y_true = []model.eval()
with torch.no_grad():for images, labels in test_loader:outputs = model(images)_, predicted = torch.max(outputs, 1)y_pred.extend(predicted.numpy())y_true.extend(labels.numpy())# 計算混淆矩陣
cm = confusion_matrix(y_true, y_pred)# 繪制混淆矩陣
plt.figure(figsize=(10, 8))
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=range(10), yticklabels=range(10))
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.title('Confusion Matrix')
plt.show()

在這里插入圖片描述

圖 4.3: MNIST 測試集的混淆矩陣。對角線上的數字代表該類別被正確預測的數量,顏色越深表示數量越多。非對角線上的數字則代表模型犯錯的情況(例如,將真實標簽為’9’的圖片錯誤地預測為了’4’)。

2. 單個圖像預測與可視化

數字化的準確率固然重要,但親眼看到模型的預測結果會更加震撼。讓我們編寫一小段代碼,從測試集中隨機抽取一些圖片,讓模型進行預測,并將結果可視化出來。

# 再次獲取一批測試數據
dataiter = iter(test_loader)
images, labels = next(dataiter)# 進行預測
output = model(images)
# 將 log-probabilities 轉換為概率
ps = torch.exp(output)# 獲取預測的類別 (概率最高的那個)
_, top_class = ps.topk(1, dim=1)# 創建一個 8x8 的網格來顯示圖片和預測結果
fig, axes = plt.subplots(8, 8, figsize=(12, 12))
for i, ax in enumerate(axes.flat):ax.imshow(images[i].numpy().squeeze(), cmap='gray')# 設置標題,綠色為正確,紅色為錯誤ax.set_title(f'Pred: {top_class[i].item()}\nTrue: {labels[i].item()}',color=("green" if top_class[i] == labels[i] else "red"))ax.axis('off')plt.tight_layout()
plt.show()

運行這段代碼,你會看到一個圖片網格。每張圖片的標題都顯示了模型的預測值(Pred)和真實值(True)。絕大多數情況下,它們都是綠色的(預測正確),偶爾出現一兩個紅色的(預測錯誤),讓你能直觀地感受到模型的強大,也能看到它犯錯的樣子。


祝賀你!

你已經成功地走完了從零開始構建一個神經網絡的全過程。從抽象的理論到具體的代碼實現,你親手打造并訓練了一個能夠高精度識別手寫數字的智能模型。這不僅僅是一個練習,你掌握的這套流程——數據準備、模型構建、定義損失與優化、訓練、評估——是所有更復雜、更強大的深度學習項目的基礎。

紅色為錯誤
ax.set_title(
f’Pred: {top_class[i].item()}\nTrue: {labels[i].item()}',
color=(“green” if top_class[i] == labels[i] else “red”)
)
ax.axis(‘off’)

plt.tight_layout()
plt.show()

運行這段代碼,你會看到一個圖片網格。每張圖片的標題都顯示了模型的預測值(`Pred`)和真實值(`True`)。絕大多數情況下,它們都是綠色的(預測正確),偶爾出現一兩個紅色的(預測錯誤),讓你能直觀地感受到模型的強大,也能看到它犯錯的樣子。

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

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

相關文章

MST56XXB/MST5650B/MST5033B 是一款耐高壓的LDO芯片,針對中控設備,給MCU供電,60V的耐壓,150mA

MST56XXB系列是一款高輸入電壓(60V)低靜態電流、高PSRR線性穩壓器(LDO),能夠提供150mA負載電流。LDO針對線電壓瞬變和負載電流瞬變具有非常快速的響應特性,并確保LDO啟動期間和短路恢復過程中不會出現過沖電壓。該設備具有集成的短路和熱關斷保護。該設備…

Java基礎(五):流程控制全解析——分支(if/switch)和循環(for/while)的深度指南

Java基礎系列文章 Java基礎(一):發展史、技術體系與JDK環境配置詳解 Java基礎(二):八種基本數據類型詳解 Java基礎(三):邏輯運算符詳解 Java基礎(四):位運算符詳解 Java基礎(五):if/switch與for/while - 深入理解…

面向對象概述

1 面向過程程序設計 面向過程是最為實際的一種思考方式,面向對象的方法也是含有面向過程的思想,面向過程是一種基礎的方法。它考慮的是實際的實現,一般的面向過程是從上往下步步求精。面向過程最重要的是模塊化的思想方法。對比面向對象&…

linux dts overlay

設備樹 Overlay(Device Tree Overlays, DTO),它在嵌入式Linux系統(尤其是基于ARM的設備,比如樹莓派、NanoPi等)中非常常見。它主要用于動態修改設備樹,以適配硬件的變化或擴展外設支持。 1. 設備…

ArkUI-X的聲明式語法轉換過程

以下是ArkUI-X聲明式語法轉換過程的詳細解析,結合其核心設計原理與實現機制: ?一、基礎語法轉換規則 組件聲明轉換 傳統命令式組件創建(如Android XMLJava)轉換為ArkUI-X的Component結構: // 命令式(A…

Docker 入門教程(一):從概念到第一個容器

文章目錄 🐳 Docker 入門教程(一):從概念到第一個容器1. Docker 是什么?2. Docker 的核心概念3. 安裝 Docker4. 運行你的第一個 Docker 容器 🐳 Docker 入門教程(一):從概…

如何在 Vue 應用中嵌入 ONLYOFFICE 編輯器

以下是僅包含 純前端集成 ONLYOFFICE 文檔編輯器到 Vue.js 項目 的完整代碼與說明,無需重新創建項目,可直接集成到現有 Vue 項目中: Vue.js 集成 ONLYOFFICE 文檔編輯器(純前端實現) 后端需要部署到服務器&#xff0c…

Cursor 1.0 炸裂功能:在后臺運行多個Agent,釋放雙手

Cursor 1.0 版本更新了用于代碼審查的 BugBot、對內存、一鍵式 MCP 設置、Jupyter 支持以及 Background Agent 的正式發布。 今天這篇文章主要介紹 Background Agent 的使用教程。 文章目錄 1. Background Agent 的基本概念2. 后臺 Agent 的使用方法3. 讓后臺 Agent 創造一個簡…

MLX LM - 在Apple芯片上運行大語言模型的Python工具包

文章目錄 一、關于MLX LM1、項目概覽2、相關鏈接資源3、功能特性 二、安裝配置三、使用指南1、快速開始2、Python API3、量化模型,上傳HF4、流式生成采樣 5、命令行6、長提示詞與生成 四、支持模型大模型 一、關于MLX LM 1、項目概覽 MLX LM是一個Python工具包&am…

【git學習】學習目標及課程安排

Git 是一款非常強大的版本控制工具,掌握它對編程和團隊協作都有巨大幫助。 🎯學習目標(適合個人與團隊使用) 理解 Git 和版本控制的基本概念 熟練使用 Git 進行代碼提交、分支管理、合并與沖突解決 掌握遠程倉庫協作流程&#x…

HDFS(Hadoop分布式文件系統)總結

文章目錄 一、HDFS概述1. 定義與定位2. 核心特點 二、HDFS架構核心組件1. NameNode(名稱節點)2. DataNode(數據節點)3. Client(客戶端)4. Secondary NameNode(輔助名稱節點) 三、數據…

破局與融合:破解開發與供應鏈安全的業務場景難題

數字化轉型下的安全新范式與融合挑戰 在數字化浪潮的席卷下,企業正全面擁抱云計算、微服務、容器化和開源技術。這種轉型在極大提升業務敏捷性的同時,也帶來了全新的安全挑戰:傳統網絡邊界消融,攻擊面急劇擴大,“開發安…

Centos7 安裝部署Git、創建倉庫

概述 Git版本控制,大家都不會陌生,實踐訴求是從零部署本地Git服務,在執行推送遠程分支代碼時,用Git服務自帶的hooks觸發同步代碼文件,從而做到自動同步代碼,實現自動更新,操作環境centos7.9,Gi…

【Redis原理】Redis數據結構底層原理

目錄 一、SDS 二、IntSet(整數集合) 三、雙向鏈表 四、壓縮列表 五、字典(哈希表) 七、跳表 八、QuickList 九、RedisObject 一、SDS Redis 是用 C語言實現的,但是它沒有直接使用C 語言的 char* 字符數組來實現…

C#.NET HttpClient 使用教程

簡介 HttpClient 是 .NET 中用于發送 HTTP 請求和接收 HTTP 響應的現代化 API,它取代了過時的 WebClient 和 HttpWebRequest 類。 HttpClient 是 .NET Framework 4.5 和 .NET Core/.NET 5 中提供的、基于消息處理管道(message handler pipeline&#…

Nginx常用安全配置指南

Nginx是一個輕量級的,高性能的Web服務器以及反向代理和郵箱代理服務器。它運行在UNIX、GNU、linux、BSD、Mac OS X、Solaris和Windows各種版本。根據調查統計數據顯示,當前全球超過6%的網站使用Nginx Web服務器來管理Web網站應用。 為了保證基于Nginx的…

【UniApp 日期選擇器實現與樣式優化實踐】

UniApp 日期選擇器實現與樣式優化實踐 發布時間:2025/6/26 前言 在移動端應用開發中,日期選擇器是一個常見且重要的交互組件。本文將分享我們在 UniApp 項目中實現自定義日期選擇器的經驗,特別是在樣式優化過程中遇到的問題及解決方案。通過…

推薦系統的視頻特征-視頻關鍵幀特征提取與向量生成

📌 總體流程概覽 視頻文件 (.mp4)↓ 關鍵幀抽取(FFmpeg / SceneDetect)↓ 幀圖像(.jpg)↓ 圖像模型提取特征(CLIP / CNN / ViT)↓ 多幀聚合成視頻向量(均值池化等)↓ 向…

Apache SeaTunnel Flink引擎執行流程源碼分析

目錄 1. 任務啟動入口 2. 任務執行命令類:FlinkTaskExecuteCommand 3. FlinkExecution的創建與初始化 3.1 核心組件初始化 3.2 關鍵對象說明 4. 任務執行:FlinkExecution.execute() 5. Source處理流程 5.1 插件初始化 5.2 數據流生成 6. Transform處理流程 6.1 插…

Vue 3 + Element Plus 實現「動態表單組件」詳解教程

? Vue 3 Element Plus 實現「動態表單組件」詳解教程 📌 適用場景:表單字段根據配置動態生成,支持校驗、提交、自定義組件、復雜布局等。 🧩 技術棧:Vue 3 TypeScript Element Plus 🔧 核心特性&#x…