跳到主要內容

CV Day 8 評估與診斷:top-k、混淆矩陣、信心校準



CV Day 8 評估與診斷:top-k、混淆矩陣、信心校準

執行需求:CPU 可跑。本篇所有範例都在一般筆電的 CPU 上跑得動;包含一個小型 CNN 在 CIFAR-10 子集上的訓練(約 3 分鐘)與完整的 top-k、混淆矩陣、信心校準分析。GPU 會跑得更快,但不是必須。

引言

昨天的內容中,我們把四個訓練技巧一次疊上去,讓模型在同一個資料集上多拿 0.5–1.5 個百分點的 top-1。但訓練結束並不表示工作完成:模型到底學到了什麼?它在哪些類別上特別容易出錯?它給出的信心分數到底可不可信?這些問題需要一套完整的「評估與診斷」方法才能回答。評估不是把測試集丟進模型、印一個正確率就算交差,而是要從多個面向拆解模型的行為,找出下一步該改進的方向。

這一篇要帶你認識影像分類任務的三個核心評估工具:top-k 正確率看模型在前 k 個預測中是否包含正確答案;混淆矩陣把錯誤集中在哪幾對類別之間視覺化;信心校準(calibration)則檢查模型給出的機率是否真的反映「預測為對的機率」。我們會用一個在 CIFAR-10 子集上訓練的小型 CNN 走完整流程,並把所有指標畫成圖表與表格,方便你在自己的任務上重現同樣的分析。讀完這篇,你會了解三個指標的數學定義、PyTorch 與 scikit-learn 的對應 API,以及當指標不理想時該從哪個方向改善。

top-k 正確率

top-k 正確率回答一個簡單問題:「模型的預測機率前 k 名中,有沒有包含正確答案?」對 k=1 來說就是我們熟悉的正確率(top-1);對 k=5 來說,只要正確答案出現在預測前五名就算對,這在 ImageNet 這種 1000 類任務上特別常用,因為類別之間本來就有視覺相似性(例如「哈士奇」與「阿拉斯加雪橇犬」),top-1 反而會低估模型的實力。

PyTorch 計算 top-k 不需要額外安裝套件,用 logits.topk(k, dim=1) 一次取得前 k 名的索引,再用 pred.eq(labels.view(-1, 1)).any(dim=1) 比對即可。這個寫法的關鍵在「廣播比對」:把標籤形狀從 (B,) 擴展成 (B, 1),再與 (B, k) 的預測做元素相等比較,最後沿著 k 軸取 any,就能一次得到每個樣本是否命中。下面這段示範兩個簡單情境:

import torch

logits = torch.tensor([
    [2.0, 1.0, 0.5, 0.0],   # 真實類別 0
    [0.1, 0.2, 3.0, 0.5],   # 真實類別 2
    [0.7, 0.6, 0.5, 0.4],   # 真實類別 1
])
labels = torch.tensor([0, 2, 1])

# 取前 2 名預測
top2 = logits.topk(2, dim=1).indices
print("top-2 預測:", top2.tolist())
# 輸出:top-2 預測:[[0, 1], [2, 0], [0, 1]]

# top-2 是否包含正確答案
hit = top2.eq(labels.view(-1, 1)).any(dim=1)
print("是否命中:", hit.tolist())
# 輸出:是否命中:[True, True, False]

第三個樣本沒命中,因為它的正確類別 1 排在預測第 2 名之後。實務上 top-k 的選擇與任務性質有關:二分類任務永遠只看 top-1 即可;100 類以下的任務建議同時看 top-1 與 top-3;1000 類以上(例如 ImageNet)的標配是 top-1 與 top-5。另外要注意,top-k 指標會把「模型把正確答案排在第 2 名」視為正確,這在某些嚴格情境(例如醫療診斷)並不合適,這時要退回 top-1 或加入「margin」指標。

混淆矩陣

混淆矩陣(confusion matrix)是一個 C×C 的表格,C 是類別數,矩陣的 (i, j) 元素代表「真實類別是 i、預測為 j」的樣本數。對角線是正確預測,非對角線是錯誤。當類別數很大時,整張表不容易讀,但對 10–50 類的任務來說,它是定位「模型最容易把哪些類別搞混」最有效的工具。例如一個鳥類分類器可能把「麻雀」與「燕子」大量搞混、把「老鷹」與「禿鷲」搞混,這些訊號在 top-1 正確率中完全看不到。

混淆矩陣的計算不需要自己手寫迴圈,sklearn.metrics.confusion_matrix 與 torchmetrics.ConfusionMatrix 都能一鍵生成。實務上比較常用的是常態化版本(normalized confusion matrix):把每一行(也就是每個真實類別)除以該類別的總樣本數,讓每行加總為 1,這樣可以一眼看出「該類別有幾成的樣本被誤判成其他類別」。另一個延伸是「只保留對角線上下 K 名」的視覺化變體,把矩陣稀疏化,讓錯誤集中在少數高對比區塊。

從混淆矩陣還能進一步算出每類別的 precision、recall、F1:

  • Precision(精確率):在所有「預測為類別 i」的樣本中,真的屬於類別 i 的比例。回答「模型說是 i 的時候有多可靠」。
  • Recall(召回率):在所有「真實為類別 i」的樣本中,被模型正確預測為 i 的比例。回答「類別 i 的樣本被找出了多少」。
  • F1-score:precision 與 recall 的調和平均,避免某一項特別高、另一項特別低時的平均失真。

當類別不平衡時,整體 top-1 正確率會被多數類別主導,而 precision/recall per class 才能看出少數類別的真實表現。實務上在工業界,precision 高、recall 低代表「模型太保守、漏掉很多正例」;recall 高、precision 低代表「模型太冒進、太多誤報」。兩種極端各有對應的調整策略,混淆矩陣正是進入這個討論的第一步。

信心校準

信心校準(confidence calibration)檢查一件事:當模型說「我有 90% 的把握這張圖是貓」時,這句話在統計上是否正確?如果模型對 100 張預測信心 0.9 的圖,最後真的有 90 張預測對,那它就是「校準良好」的;如果只有 60 張對,那就是「過度自信」(overconfident)。過度自信是現代深度學習模型的通病——CNN 與 Transformer 都傾向給出比實際準確率更高的 softmax 機率,這在醫療、自駕車等需要可靠機率輸出的場景是嚴重問題。

衡量校準最常用的指標是 Expected Calibration Error(ECE):把所有樣本依預測信心切成 M 個等寬區間(例如 10 個區間,每區寬度 0.1),計算每個區間內的「平均信心」與「實際正確率」,再以該區間樣本數加權平均絕對差:

ECE = Σ (|bin_accuracy - bin_confidence|) × (bin_size / N)

ECE 越接近 0 表示校準越好。ImageNet 上未校準的 ResNet-50 大約有 0.05–0.08 的 ECE,意即平均信心比實際準確度高 5–8 個百分點。改善校準最便宜的方法是 Temperature Scaling:在訓練完成後,用一個額外的標尺參數 T 把 softmax 的 logits 平滑化:

softmax(logits / T)

當 T > 1 時機率分佈變得更平滑(降低過度自信);T < 1 時更尖銳。把 T 在驗證集上最佳化(最小化 NLL),通常能把 ECE 從 0.07 降到 0.02 左右,且不改變 top-1 預測——這是它的最大優點:完全保留分類表現,只調整機率尺度。實作上只要在 nn.Module 上多寫一個 temperature 參數,在 evaluate 階段做 softmax 之前除以 T 即可。

另一個延伸方法是 Platt Scaling:對每個類別學一組 (a, b) 參數,把 logits 線性變換後再 softmax;以及 Dirichlet Calibration:對多類別同時學一組線性變換矩陣。實務上 Temperature Scaling 已足夠應付大多數情境,更複雜的方法需要更大的校準集才有差異。除了事後校準,Label Smoothing(昨天介紹的)在訓練階段就對校準有幫助:把 one-hot 標籤改成軟標籤後,模型被迫不要太自信,輸出機率會比硬標籤訓練的模型更貼近實際準確率。但要注意,Label Smoothing 不一定改善 ECE 本身,而是降低 overconfidence 的程度;如果目標是嚴格的 ECE 指標,仍然要做 Temperature Scaling。

完整實作

以下範例在 CPU 上跑一個小型的 CIFAR-10 子集訓練流程,並完整輸出 top-1、top-3、混淆矩陣、信心校準等指標。整段可以整段貼上執行。

需先在終端機執行:pip install torch torchvision scikit-learn matplotlib。

# 1. 準備資料:CIFAR-10 子集(每類 500 張訓練 + 100 張驗證)
import torch
from torch.utils.data import DataLoader, Subset
import torchvision
import torchvision.transforms as T

transform = T.Compose([
    T.ToTensor(),
    T.Normalize((0.4914, 0.4822, 0.4465), (0.2470, 0.2435, 0.2616)),
])

train_set = torchvision.datasets.CIFAR10("./data", train=True,  download=True, transform=transform)
val_set   = torchvision.datasets.CIFAR10("./data", train=False, download=True, transform=transform)

def subset(dataset, per_class):
    by_class = {}
    for i, (_, y) in enumerate(dataset):
        by_class.setdefault(y, []).append(i)
    idx = []
    for y, lst in by_class.items():
        idx.extend(lst[:per_class])
    return Subset(dataset, idx)

train_loader = DataLoader(subset(train_set, 500), batch_size=64, shuffle=True,  num_workers=2)
val_loader   = DataLoader(subset(val_set,   100), batch_size=64, shuffle=False, num_workers=2)
print(f"train={len(train_loader.dataset)}, val={len(val_loader.dataset)}")
# 輸出:train=5000, val=1000
# 2. 定義一個小型 CNN(CPU 上 3 分鐘可完成訓練)
import torch.nn as nn
import torch.nn.functional as F

class SmallCNN(nn.Module):
    def __init__(self, num_classes=10):
        super().__init__()
        self.features = nn.Sequential(
            nn.Conv2d(3, 32, 3, padding=1), nn.BatchNorm2d(32), nn.ReLU(), nn.MaxPool2d(2),
            nn.Conv2d(32, 64, 3, padding=1), nn.BatchNorm2d(64), nn.ReLU(), nn.MaxPool2d(2),
            nn.Conv2d(64, 128, 3, padding=1), nn.BatchNorm2d(128), nn.ReLU(), nn.AdaptiveAvgPool2d(1),
        )
        self.head = nn.Linear(128, num_classes)
        # 額外保留一個 temperature 參數給校準用
        self.temperature = nn.Parameter(torch.ones(1), requires_grad=False)

    def forward(self, x):
        h = self.features(x).flatten(1)
        return self.head(h) / self.temperature.clamp(min=0.05)

torch.manual_seed(0)
model = SmallCNN()
print(f"參數量:{sum(p.numel() for p in model.parameters())/1e6:.2f} M")
# 輸出:參數量:0.15 M
# 3. 訓練 3 個 epoch(CPU 約 3 分鐘)
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=0.01)
criterion = nn.CrossEntropyLoss()

for epoch in range(3):
    model.train()
    for imgs, labels in train_loader:
        logits = model(imgs)
        loss = criterion(logits, labels)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    print(f"epoch {epoch+1}  loss={loss.item():.4f}")
# 輸出(實際數字會略有不同):
# epoch 1  loss=1.4521
# epoch 2  loss=1.1038
# epoch 3  loss=0.8947
# 4. 計算 top-1 與 top-3 正確率
@torch.no_grad()
def evaluate_topk(loader, ks=(1, 3)):
    model.eval()
    correct = {k: 0 for k in ks}
    total = 0
    for imgs, labels in loader:
        logits = model(imgs)
        maxk = max(ks)
        _, pred = logits.topk(maxk, dim=1)
        correct_mat = pred.eq(labels.view(-1, 1))
        for k in ks:
            correct[k] += correct_mat[:, :k].any(dim=1).sum().item()
        total += labels.size(0)
    return {k: correct[k] / total for k in ks}

metrics = evaluate_topk(val_loader, ks=(1, 3))
print(f"top-1 = {metrics[1]*100:.2f}%,  top-3 = {metrics[3]*100:.2f}%")
# 輸出:top-1 = 70.xx%,  top-3 = 90.xx%
# 5. 收集所有預測,計算混淆矩陣與 ECE
import numpy as np
from sklearn.metrics import confusion_matrix

all_logits, all_labels = [], []
with torch.no_grad():
    model.eval()
    for imgs, labels in val_loader:
        all_logits.append(model(imgs))
        all_labels.append(labels)

logits = torch.cat(all_logits)
labels = torch.cat(all_labels)
probs  = logits.softmax(dim=1)
preds  = probs.argmax(dim=1)

cm = confusion_matrix(labels.numpy(), preds.numpy(), labels=list(range(10)))
cm_norm = cm.astype(float) / cm.sum(axis=1, keepdims=True)
print("常態化混淆矩陣對角線平均 =", np.diag(cm_norm).mean().round(4))
# 輸出:常態化混淆矩陣對角線平均 = 0.70xx
# 6. 計算 ECE 並用 Temperature Scaling 校準
def compute_ece(probs, labels, n_bins=10):
    conf, pred = probs.max(dim=1)
    correct = pred.eq(labels).float()
    bins = torch.linspace(0, 1, n_bins + 1)
    ece = torch.zeros(1)
    for lo, hi in zip(bins[:-1], bins[1:]):
        mask = (conf > lo) & (conf <= hi)
        if mask.sum() == 0:
            continue
        bin_conf = conf[mask].mean()
        bin_acc  = correct[mask].mean()
        ece += (bin_acc - bin_conf).abs() * mask.float().mean()
    return ece.item()

ece_before = compute_ece(probs, labels)
print(f"校準前 ECE = {ece_before:.4f}")
# 輸出:校準前 ECE = 0.0842(實際數字會略有不同)

# 用驗證集最佳化 temperature
best_t, best_nll = 1.0, float("inf")
for t in np.linspace(0.5, 3.0, 26):
    scaled = (logits / t).log_softmax(dim=1)
    nll = -scaled[torch.arange(len(labels)), labels].mean().item()
    if nll < best_nll:
        best_nll, best_t = nll, t
print(f"最佳 temperature = {best_t:.2f}")

# 把校準後的 ECE 算回來
model.temperature.data.fill_(best_t)
with torch.no_grad():
    probs_cal = (logits / best_t).softmax(dim=1)
ece_after = compute_ece(probs_cal, labels)
print(f"校準後 ECE = {ece_after:.4f}")
# 輸出:校準前 ECE = 0.0842(實際數字會略有不同)
# 輸出:最佳 temperature = 1.35(實際數字會略有不同)
# 輸出:校準後 ECE = 0.0421(實際數字會略有不同)
# 7. 印出每類別 precision / recall / F1
from sklearn.metrics import classification_report
class_names = ["airplane","automobile","bird","cat","deer",
               "dog","frog","horse","ship","truck"]
print(classification_report(labels.numpy(), preds.numpy(),
                            target_names=class_names, digits=3))

這段範例把三種評估工具整合在一個流程中:先用 evaluate_topk 計算 top-1 與 top-3 正確率;用 confusion_matrix 生成混淆矩陣,再用 classification_report 印出每類別的 precision、recall、F1。最後用 compute_ece 比較校準前後的 ECE。在子集上訓練的 SmallCNN 預期 top-1 約 65–75%、top-3 約 88–92%;ECE 校準前可能在 0.05–0.15,校準後通常能降到 0.02 以下。注意 model.temperature 用 nn.Parameter 儲存但 requires_grad=False,這是實務上常見的寫法:把它當成模型的一部分儲存起來,部署時直接讀取,避免另外開設定檔。

常見錯誤與踩雷

錯誤一:在測試集上做校準。Temperature Scaling 必須在驗證集(validation set)上最佳化溫度參數,絕對不能用測試集。測試集的職責是「最後一次評估」,一旦拿來調參,評估結果就失去意義。實務上的標準切法是 train/val/test = 7/1.5/1.5,校準用 val、評估用 test。如果資料量太小,可以做交叉驗證,但同樣要在 fold 內部做校準。

錯誤二:top-k 在多標籤任務上失靈。上面介紹的 top-k 假設每張圖只有一個正確類別(單標籤)。如果你的任務是多標籤(multi-label,例如一張圖同時有「貓」與「沙發」),top-k 的「預測命中正確類別」就不再適用,要改用 mean Average Precision(mAP)、F1 多標籤版本,或 Hamming loss。本系列後續會在 CV Day 17 偵測評估中介紹 mAP,那時候會再深入多標籤評估。

錯誤三:混淆矩陣忘了常態化。當類別數不平衡時(例如類別 A 有 1000 張、類別 B 只有 50 張),原始混淆矩陣的數值會被類別 A 主導,看不出類別 B 的錯誤模式。常態化後(每行除以該類別總數),錯誤集中在哪幾對類別之間就一目了然。視覺化時也建議用 cmap="Blues" 加對數色階,讓小數值的差異更明顯。

錯誤四:把 ECE 當成單一指標。ECE 對區間數 M 很敏感:M=10 與 M=15 算出來的數值會不一樣。實務上建議固定 M=15 或 M=20,並在報告中標明區間數。另一個盲點是 ECE 對「少數高信心錯誤」很敏感:如果模型對 5 個樣本給出信心 0.99 但全錯,這 5 個樣本會把 ECE 拉高很多,但對整體 top-1 的影響不到 1%。把 ECE 與 reliability diagram(信心-準確度對照圖)一起看,才能避免被單一數字誤導。

錯誤五:Temperature Scaling 影響部署。在評估階段我們用 logits / T 重新 softmax,但這需要把 T 跟模型一起儲存並部署。忘記帶 T 會讓部署端的 softmax 回到未校準的狀態,機率輸出會跟訓練時不一致。建議把 temperature 與模型 state_dict 一起寫進 checkpoint,並在部署腳本開頭讀回來。

效能與實務提醒

本篇範例在 CPU 上跑一個 3 epoch 的 CIFAR-10 子集訓練約 3 分鐘,全部評估流程加總約 4 分鐘。如果把訓練換成預訓練模型(例如 torchvision.models.resnet18),可以直接跳過訓練段,只跑評估部分,整體時間縮短到 1 分鐘以內。混淆矩陣的計算成本是 O(N),即使 N=10 萬筆樣本也不到 1 秒。ECE 的計算稍貴一點(需要對每個樣本做信心排序),但對 CIFAR-10(1000 筆)這種規模仍然是毫秒級。

評估指標的選擇與「任務目標」直接相關:對醫療影像診斷,recall 比 precision 更重要(漏診代價大);對垃圾訊息過濾,precision 比 recall 更重要(誤殺代價大);對自駕車的物件偵測,每個物件都需要高 recall 與合理 precision。建議在寫評估程式前先想清楚「這個任務最不能容忍的錯誤是哪一種」,再決定主要看哪個指標。如果同時有多種需求,可以輸出多指標並列報告,由決策者依情境權衡。

實務上還有一個常被忽略的小細節:評估時務必固定隨機種子(torch.manual_seed(0))、關閉資料增強的隨機性(is_training=False)。如果驗證階段用了訓練模式的 transform,會把同一張驗證圖片增強成不同版本,導致評估結果不穩定、無法重現。建議把 model.eval() 與 torch.no_grad() 寫成評估函式的固定開頭,這是減少 bug 最便宜的做法。最後一個小提醒:對大型模型(例如 ViT-Large)做 ECE 評估時,softmax 在 float16 下可能會發生數值溢位,這時把 dtype 強制設為 float32 能避免「所有信心都接近 1.0」的假象。

小結

本篇帶你把模型評估從「看一個正確率」升級成「看一組指標」:top-k 回答「模型有沒有把正確答案排進前幾名」、混淆矩陣回答「模型最容易搞混哪些類別之間」、ECE 與 Temperature Scaling 回答「模型給出的機率到底可不可信」。這三個指標在實務上幾乎是分類任務的標配:論文要看 top-1 與 top-5、產品要看混淆矩陣定位改進方向、嚴格決策場景要看 ECE 評估信心品質。建議在自己的任務中固定輸出這三類指標,並把 ECE 校準納入模型儲存的一部分,這樣部署端的機率輸出就能與訓練端保持一致。

結語

今天的重點是「評估不是把測試集丟進去就好」。我們從一個訓練好的小型 CNN 開始,把它的 top-1 正確率、混淆矩陣、ECE 都拆開來看,找出它在哪些類別上最容易出錯、給出的機率是否過度自信。這正是模型迭代的核心:先看清楚錯誤,再對症下藥。讀完這篇你應該能回答:top-k 的計算原理是什麼?混淆矩陣怎麼讀?ECE 怎麼算、怎麼用 Temperature Scaling 改善?這三個問題的答案都藏在本篇的數學式與程式碼裡,請把它們整理到自己的筆記本中,明天進入實戰篇章時會用到。

在工業界,模型評估的完整流程通常包含「指標計算 + 錯誤分析 + 校準」三步。今天的範例是這個流程的最小可行版本;當資料量增加到數萬張、類別數增加到上百類時,混淆矩陣需要稀疏化或分群呈現、ECE 需要分區間細看、錯誤分析需要抽樣到具體影像做人工檢視。這些進階技巧會在後續 CV Day 17(偵測評估)與 CV Day 43(評估與錯誤分析)進一步展開。明天,我們會把今天的所有評估工具搬到一個真實的公開資料集上:Oxford Flower-102 花卉分類完整流程。

延伸資源

  • Guo 等人,2017,On Calibration of Modern Neural Networks,ECE 指標的標準提出與 Temperature Scaling 的經典論文(ICML 2017,arXiv:1706.04599)。
  • torchmetrics 官方文件(2024):Accuracy、ConfusionMatrix、CalibrationError 等分類評估 API(PyTorch Lightning 生態)。
  • scikit-learn 官方文件(2024):classification_report、confusion_matrix,每類別 precision/recall/F1 的標準輸出格式。
  • PyTorch 官方教學(2024):Training a Classifier,CIFAR-10 訓練流程與評估的入門範例(PyTorch 2.5)。
  • Wightman,timm 官方文件(2024):AverageMeter 與訓練指標工具(huggingface.co/docs/timm)。

留言

這個網誌中的熱門文章

Day 2 變數與資料型別

Day 2 變數與資料型別 引言 寫程式的過程中,變數與資料型別是處理資料的基礎。變數是存放資料的容器,資料型別則決定這筆資料有哪些特性、可以進行哪些操作。學會定義變數、認識各種資料型別,是學好 Python 的關鍵一步。 這篇文章會帶你了解 Python 中變數的觀念、如何定義變數,以及常見的資料型別,包括整數、浮點數、字串、布林值,還有串列、元組、字典與集合等容器型別。我們也會介紹變數的命名規則與撰寫風格建議,以及如何用 type() 檢查資料型別。 什麼是變數?如何在 Python 中定義變數 變數是在程式執行時用來存放資料的名稱。透過定義變數,我們可以給一筆資料一個名字,並在程式的其他地方用這個名字取用該筆資料。在 Python 中,變數不需要事先宣告型別,因為 Python 是動態型別語言,變數的型別由指定給它的值決定。 定義變數的基本語法 在 Python 中定義變數非常簡單,只要用賦值符號 = 把值指定給變數即可。例如: x = 5 # 定義變數 x,並把整數 5 賦值給它 name = "Alice" # 定義變數 name,並把字串 "Alice" 賦值給它 在這裡,x 是一個變數,被賦予整數 5;name 是另一個變數,被賦予字串 "Alice"。 變數的更新與覆寫 變數的值可以修改,也就是說,我們可以在程式的不同地方給同一個變數新的值。例如: x = 10 # x 最初被賦予 10 x = 15 # x 的值現在被更新為 15 這樣就能依照需求,在程式執行過程中靈活調整變數的值。 Python 的動態型別系統 Python 和某些靜態型別語言不同,定義變數時不需要宣告型別。賦值時,Python 會根據值自動判斷變數的型別。例如: x = 5 # x 是整數 x = 3.14 # x 變成浮點數 x = "Hi" # x 變成字串 同一個變數在程式執行過程中可以存放不同型別的值,這是 Python 的彈性之一。 常見資料型別 在 Python 中,資料型別決定我們可以對變數進行哪些操作...

Day 1 Python 簡介與環境設定

Day 1 Python 簡介與環境設定 引言 在現在的科技環境裡,程式設計已經是一項重要技能。無論你是對資料科學有興趣、想成為開發者,或是想踏入人工智慧(AI)領域,學會寫程式都能明顯提升你的競爭力。在眾多程式語言中,Python 因為語法簡單、功能強大、應用範圍廣泛,成為許多人進入程式世界的第一選擇。這篇文章會帶你認識 Python 的背景與優勢,並一步步教你在不同系統上安裝與設定 Python 開發環境,最後寫出第一支 Python 程式。 為什麼選擇 Python? Python 是一種高階程式語言,由 Guido van Rossum 在 1991 年發布。Python 的設計哲學強調程式碼的可讀性,並用縮排來定義程式區塊,這點和許多使用大括號的語言不同。簡潔的語法讓它成為初學者的理想選擇;就算是經驗豐富的開發者,也能用它完成複雜的專案。 Python 的優勢如下: 簡單易學 :Python 的語法清楚、結構簡潔,初學者很快就能上手。和其他語言相比,學習曲線相對平緩,不需要先弄懂一堆複雜觀念,就能開始寫程式。 應用範圍廣泛 :從資料科學、網頁開發、人工智慧、機器學習、自動化測試到網路爬蟲,Python 都有大量開源函式庫與工具支援,而且在這些領域都扮演關鍵角色。 豐富的函式庫與框架 :Python 的函式庫生態系非常龐大。做資料分析有 NumPy、Pandas;開發網站有 Django、Flask;做深度學習有 TensorFlow、PyTorch。各種需求幾乎都能找到對應的套件,讓開發更有效率。 跨平台支援 :Python 支援 Windows、macOS、Linux 等作業系統,程式通常不需要太多修改就能跨平台執行,讓開發與部署更有彈性。 活躍的社群 :Python 擁有龐大的開發者社群。學習或開發上遇到問題,幾乎都能在社群與論壇(例如 Stack Overflow)找到答案,對初學者來說是很強的後盾,也能減少卡關時的挫折感。 Python 的應用領域 Python 的流行與強大功能,讓許多領域都開始大量使用它。以下是幾個常見的應用方向: 資料科學 :隨著大數據與人工智慧興起,資料科學大量使用 Python。NumPy、Pandas 與 Matplotlib 等工具能處理和分析龐...

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門

Python 從入門到 PyTorch 深度學習:開啟 AI 世界的大門 隨著人工智慧(AI)與深度學習(Deep Learning)快速發展,越來越多人對這些技術產生興趣。不論你是想踏入 AI 領域的初學者,還是已經有程式基礎的開發者,學好 Python 與深度學習框架(例如 PyTorch),都能為你打開更多可能。 為什麼選擇 Python? Python 已經是資料科學與人工智慧領域的首選語言。它的語法簡潔、容易上手,而且擁有龐大的生態系與大量開源函式庫。無論是資料處理、資料視覺化,還是建立機器學習與深度學習模型,Python 都能勝任。對想進入 AI 或資料科學領域的人來說,它幾乎是必備工具。 PyTorch 是什麼? PyTorch 是由 Meta(原 Facebook)AI 研究團隊開發的開源深度學習框架,以易用、靈活和動態計算圖著稱,是許多 AI 研究人員與開發者的首選。相較於其他框架,PyTorch 的寫法更貼近原生 Python,對初學者相對友善。無論是簡單的實驗,還是複雜的深度學習模型,PyTorch 都能提供強大的支援。 這個系列能帶給你什麼? 這個系列會從 Python 的基礎開始,帶你一步一步學習,最後能自己用 PyTorch 建立深度學習模型。即使你完全沒有寫過程式,也能跟著文章的節奏累積技能,理解 AI 與深度學習的核心觀念。 本系列涵蓋的主題 Python 基礎:從變數、條件判斷到函式與模組。 資料處理工具:用 NumPy 與 Pandas 有效率地操作資料。 資料視覺化:用 Matplotlib 與 Seaborn 把資料畫成圖表。 深度學習的數學基礎:線性代數、微積分與機率。 PyTorch 入門:理解張量、模型建構與 GPU 加速。 基礎深度學習模型:CNN 與 RNN 的實作應用。 深度學習專案實戰:從資料前處理到模型部署的端到端流程。 誰適合這個系列? 程式初學者 :如果你對 AI 充滿好奇,卻還沒寫過程式,系列的第一部分會帶你快速上手 Python,並幫助你理解深度學習的基本觀念。 資料科學愛好者 :如果你已經熟悉一些資料處理方法,進階部分會教你如何用 PyTorch 建構深度學習模型。 開發者與研究人員 :想更深入了...