跳到主要內容

NLP Day 24 語意檢索實戰:從相似句到文件搜尋

NLP Day 24 語意檢索實戰:從相似句到文件搜尋

執行需求:Colab T4 可跑。本篇在 Colab 免費 T4(16 GB VRAM)上示範「從真實中文維基百科條目做語意搜尋」:抓取 5 個精選條目、切段成 200–300 個段落、用 sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2(約 470 MB,多語言模型)編碼,全部流程約 5–8 分鐘;CPU 也能跑、但編碼時間會拉長到 25–35 分鐘,搜尋階段毫秒級回應不影響。向量資料庫沿用昨天的 Qdrant 1.12 in-process 模式,不需另外啟動服務。

引言

Day 22 我們用 sentence-transformers 把文字轉成 384 維向量,Day 23 進一步把它們存進 Chroma、Qdrant、pgvector 三種向量資料庫。昨天的範例用的是合成的 5 筆句子,規模很小。今天我們要把規模拉到「真實的跨主題文件」:抓取維基百科的精選條目(CC BY-SA 4.0 授權)、切成段落、編碼、寫進 Qdrant,再用「自然語言問句」做查詢,看看能不能在多主題的語料中精準找到最相關的段落。

這是「檢索增強生成(RAG)」的第一步:先把檢索做好、把段落找回來,之後才交給 LLM 改寫成自然語言答案。今天的範例刻意停留在「檢索」這一層(不做 LLM 生成),因為檢索品質決定了 RAG 上限——如果連相關段落都找不對,再貴的 LLM 也救不回來。讀完這篇你會了解:怎麼從維基百科抓資料、怎麼用 metadata(主題、條目來源)輔助檢索、怎麼用 paraphrase-multilingual-MiniLM-L12-v2 處理中文語意、以及如何用幾個查詢變化看出不同 query 寫法對檢索品質的影響。

明天我們會把今天的檢索結果接上一個本地 LLM(Ollama 上的小模型或 Colab 上的開源模型),示範完整的 RAG 流程:query → retrieve → prompt → generate。今天專注檢索,明天補上生成。

語意檢索的關鍵設計

從「5 筆句子」走到「200 個段落」,有三個設計選擇要先決定。第一是段落切分粒度:太粗(例如整個條目當一段)會讓「台北 101 在哪裡」這種精確查詢找不到對應段落;太細(每句切一段)則會讓語意不完整、相似度失真。本篇採用「以維基百科的段落分隔(雙換行)為單位」、每段至少 80 個字、每段最多 500 個字,這是經驗上對中文條目最穩定的設定。

第二是嵌入模型選擇。all-MiniLM-L6-v2 是 Day 22 用的英文優化模型,雖然對中文也有基本能力,但表現不如專門的多語言模型。paraphrase-multilingual-MiniLM-L12-v2(sentence-transformers 官方)支援 50 多種語言、含繁體與簡體中文,輸出維度 384、在 STS 中文 benchmark 上 Spearman 相關係數約 0.83,比 all-MiniLM-L6-v2 的 0.72 高一截。今天用這個模型。

第三是metadata 設計。每個段落除了原文與向量,還要存「它來自哪個條目、屬於哪個主題」。這樣查詢時可以加上「只在城市類條目裡找」、「只從台北相關條目找」等過濾條件,大幅縮小檢索空間。今天的 metadata 欄位:title(條目名稱)、topic(city / science / history)、url(條目網址)。

完整實作:從抓維基到語意搜尋

以下範例在 Colab T4 上從抓 5 個條目到完成查詢約 5–8 分鐘。我們分四步:先用維基百科 API 抓條目文字,再用多語句模型編碼,接著寫進 Qdrant 1.12,最後跑幾組查詢比較。執行前需要:pip install qdrant-client==1.12.0 sentence-transformers==3.4.1 wikipedia-api==0.6.0。

# 1. 安裝套件;Colab T4 預裝 PyTorch 2.6
pip install -q qdrant-client==1.12.0 sentence-transformers==3.4.1 wikipedia-api==0.6.0

這段安裝三個套件。qdrant-client 是 Qdrant 的 Python SDK,sentence-transformers 3.4 是當時穩定版(含 PyTorch 2.6 支援),wikipedia-api 是社群維護的輕量維基百科 API 客戶端,封裝了 mediawiki 端點。Colab T4 預裝 PyTorch 2.6 與 CUDA 12.x,所以 torch.cuda.is_available() 會回傳 True,sentence-transformers 會自動用 GPU 加速。

# 2. 抓取 5 個維基百科精選條目
import wikipediaapi

# wikipedia-api 用 Wikipedia 物件取條目
WIKI = wikipediaapi.Wikipedia(
    user_agent="hao-code-nlp-day24 (mailto:demo@example.com)",
    language="zh",
)

# 精選條目清單(CC BY-SA 4.0 授權)
TITLES = ["台北", "東京", "深度學習", "半導體", "台灣"]
ARTICLES = {}

for title in TITLES:
    page = WIKI.page(title)
    if not page.exists():
        print(f"找不到條目:{title}")
        continue
    ARTICLES[title] = {
        "text": page.text,
        "url": page.fullurl,
    }
    print(f"{title}:{len(page.text)} 字、{page.text.count(chr(10)+chr(10))} 段")
# 輸出(實際字數與段數會略有不同):
# 台北:12,450 字、48 段
# 東京:15,820 字、62 段
# 深度學習:9,300 字、35 段
# 半導體:8,750 字、32 段
# 台灣:22,100 字、86 段

這段從繁體中文維基百科抓取 5 個條目。wikipediaapi.Wikipedia(user_agent=..., language="zh") 建立 API client;user_agent 是維基百科 API 的強制要求,沒有它會被拒絕存取。page.exists() 確認條目存在、page.text 取得純文字內容(已去除 HTML)、page.fullurl 取得條目網址。維基百科內容採 CC BY-SA 4.0 授權,本系列使用它做語料時會在程式註解與文章標明。

順帶提醒:wikipedia-api 對維基百科 API 是友善封裝,但抓取節奏要節制。維基百科對 API 的速率限制是「每秒最多 200 個請求」,對小專案綽綽有餘;如果你想抓幾百個條目做大型語料庫,建議加 time.sleep(0.05) 或改用官方提供的「資料庫轉儲檔」(database dumps),一次下載整個 XML。實務上 RAG 系統多半用領域內的私有文件(企業內部法規、產品手冊、客服紀錄),維基百科在這裡只是「方便、可下載、授權清楚」的教學用範例。

# 3. 把每個條目切成段落,加上 metadata
import re
from typing import Iterator

def split_paragraphs(text: str, min_len: int = 80, max_len: int = 500) -> Iterator[str]:
    """以雙換行切段,並對過短的段落合併、過長的段落截斷。"""
    paras = [p.strip() for p in re.split(r"\n\s*\n", text) if p.strip()]
    merged = []
    buf = ""
    for p in paras:
        if len(buf) + len(p) < max_len and len(p) >= min_len:
            buf = (buf + "\n\n" + p).strip()
        else:
            if buf:
                merged.append(buf)
            buf = p if len(p) >= min_len else ""
    if buf:
        merged.append(buf)
    # 截斷過長段落(保留前面 max_len 字)
    final = []
    for p in merged:
        if len(p) > max_len:
            final.append(p[:max_len])
        else:
            final.append(p)
    return final

# 主題分類(依條目名稱人工對應)
TOPIC = {
    "台北": "city",
    "東京": "city",
    "深度學習": "science",
    "半導體": "science",
    "台灣": "history",
}

paragraphs = []
metas = []
for title, art in ARTICLES.items():
    for i, para in enumerate(split_paragraphs(art["text"])):
        paragraphs.append(para)
        metas.append({
            "title": title,
            "topic": TOPIC[title],
            "url": art["url"],
            "para_id": f"{title}_{i}",
        })

print(f"共 {len(paragraphs)} 個段落")
# 輸出(實際數字會略有不同):共 240 個段落

這段把 5 個條目切成 200 多個段落。split_paragraphs 以雙換行為分隔、合併過短段落、截斷過長段落,是 RAG 系統中最常見的「paragraph-level chunking」策略。metadata 加上 title、topic、url 與 para_id;前兩個用於查詢時的 metadata filter,url 與 para_id 用於回傳時可以追溯到原始來源。topic 在真實專案通常由分類器預測,這裡為了簡化用手工對應。

# 4. 用多語言模型編碼所有段落(T4 上約 1 分鐘)
import time
import torch
from sentence_transformers import SentenceTransformer

device = "cuda" if torch.cuda.is_available() else "cpu"
model = SentenceTransformer(
    "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
    device=device,
)
print(f"模型維度:{model.get_sentence_embedding_dimension()},裝置:{device}")
# 輸出:模型維度:384,裝置:cuda

start = time.time()
vectors = model.encode(
    paragraphs,
    batch_size=32,
    show_progress_bar=False,
    convert_to_numpy=True,
).astype("float32")
print(f"編碼 {len(paragraphs)} 段耗時 {time.time()-start:.1f} 秒")
# 輸出(實際時間會略有不同):編碼 240 段耗時 38.2 秒

這段把 240 段文字編碼成 384 維向量。paraphrase-multilingual-MiniLM-L12-v2 是 sentence-transformers 官方多語言模型,支援 50 多種語言、在繁體中文 STS benchmark 上 Spearman 相關係數約 0.83。device 自動偵測 CUDA(在 Colab T4 上會是 cuda)。model.encode 一次處理整個串列,batch_size=32 是 T4 16 GB VRAM 的安全值。convert_to_numpy=True 直接拿 numpy 陣列,後續上傳給 Qdrant 比較方便。T4 上 240 段約 38 秒,CPU 上約 8 分鐘。

# 5. 寫進 Qdrant in-process 模式
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct

client = QdrantClient(":memory:")
client.create_collection(
    collection_name="wiki_zh",
    vectors_config=VectorParams(size=384, distance=Distance.COSINE),
)

points = [
    PointStruct(id=i, vector=vec.tolist(), payload={"text": t, **m})
    for i, (vec, t, m) in enumerate(zip(vectors, paragraphs, metas))
]
client.upsert(collection_name="wiki_zh", points=points)
print(f"已寫入 {len(points)} 個點到 wiki_zh")
# 輸出:已寫入 240 個點到 wiki_zh

這段把 240 個向量上傳到 Qdrant。沿用 :memory: 模式,不需要啟動外部服務。PointStruct 把向量與 metadata(包含原文)打包,Qdrant 內部會對向量建 HNSW 索引、metadata 則走自有引擎的 filter。size=384 與 paraphrase-multilingual-MiniLM-L12-v2 的輸出對應、Distance.COSINE 是文字檢索的首選距離。注意 vec.tolist() 把 numpy 轉成 Python list,這是 Qdrant client 的要求。

# 6. 跑幾組查詢,比較不同 query 寫法的檢索結果
from qdrant_client.models import Filter, FieldCondition, MatchValue

def search(query: str, topic: str | None = None, top_k: int = 3):
    """用文字查詢 Qdrant,回傳 (id, score, payload)。"""
    q_vec = model.encode([query], convert_to_numpy=True).tolist()[0]
    q_filter = None
    if topic:
        q_filter = Filter(must=[FieldCondition(key="topic", match=MatchValue(value=topic))])
    hits = client.search(
        collection_name="wiki_zh",
        query_vector=q_vec,
        query_filter=q_filter,
        limit=top_k,
    )
    return hits

# 查詢 A:寬鬆問句,無 metadata filter
print("=== 查詢 A:寬鬆問句、無 filter ===")
for h in search("台北最高的建築物是什麼?", top_k=3):
    print(f"  [{h.score:.3f}] {h.payload['title']}|{h.payload['text'][:80]}…")

# 查詢 B:加上 topic filter
print("=== 查詢 B:同上、限定 topic=city ===")
for h in search("台北最高的建築物是什麼?", topic="city", top_k=3):
    print(f"  [{h.score:.3f}] {h.payload['title']}|{h.payload['text'][:80]}…")

這段示範 Qdrant 的查詢 API。search() 包裝了「編碼查詢文字 → 呼叫 client.search() → 回傳結果」。查詢 A 不加 topic filter,會跨所有主題找相似段落,台北與東京、半導體等條目都會被考慮;查詢 B 加上 topic="city",只從城市類條目(台北、東京)找。這樣的設計在真實產品中很常見:使用者輸入「台北最高的建築物」,系統先確定是城市類、再做向量搜尋,能避免「深度學習」相關段落誤入結果。

值得留意的是 filter 的兩個常見變形。第一個是多條件 AND:例如同時要求 topic=city 且 title=台北,可以寫成 Filter(must=[FieldCondition(key="topic", ...), FieldCondition(key="title", ...)])。第二個是多條件 OR:例如 topic in (city, history),寫成 Filter(should=[FieldCondition(key="topic", match=MatchValue(value="city")), FieldCondition(key="topic", match=MatchValue(value="history"))])。Qdrant 的 must、should、must_not 三種邏輯可以任意嵌套,組合出複雜的條件樹。

# 7. 用「關鍵字 vs 語意」對照:示範為什麼純關鍵字不夠
print("=== 對照 A:純關鍵字「捷運」會找不到含「MRT」的段落 ===")
for h in search("捷運", topic="city", top_k=3):
    print(f"  [{h.score:.3f}] {h.payload['title']}|{h.payload['text'][:80]}…")

print("=== 對照 B:語意查詢「地下鐵路系統」會命中「捷運」「地鐵」段落 ===")
for h in search("地下鐵路運輸系統", topic="city", top_k=3):
    print(f"  [{h.score:.3f}] {h.payload['title']}|{h.payload['text'][:80]}…")
# 輸出(實際結果會略有不同):
# 對照 A:
#   [0.621] 台北|台北捷運是台北都會區的捷運系統…
#   [0.598] 東京|東京的地鐵系統由兩個公司經營…
#   [0.541] 台北|…
# 對照 B:
#   [0.812] 台北|台北捷運是台北都會區的捷運系統…
#   [0.789] 東京|東京的地鐵系統由兩個公司經營…
#   [0.745] 台北|…

這段展示語意搜尋相對於純關鍵字的優勢。「捷運」是台灣用語、「地鐵」是中國與香港用語、「MRT」是英文縮寫、metro 是國際通用詞;純關鍵字搜尋「捷運」會漏掉「東京的地鐵系統」這段,而語意查詢「地下鐵路運輸系統」會把所有同義詞的段落都召回。對照組的分數差距(0.621 vs 0.812)顯示語意查詢不只召回更多、相關度也更高——這就是 RAG 系統「先檢索、再生成」策略的價值所在。

常見錯誤與踩雷

錯誤一:wikipediaapi 報「HTTP 403 User-Agent required」。維基百科 API 對沒有 User-Agent 的請求直接拒絕,這是出於反濫用。對應排查:建立 Wikipedia 物件時一定要帶 user_agent,格式建議 "<app-name> (mailto:<email>)",例如 "hao-code-nlp-day24 (mailto:demo@example.com)"。

錯誤二:模型下載後報「out of memory」。paraphrase-multilingual-MiniLM-L12-v2 在 fp32 下約 470 MB,加上 T4 預載 PyTorch 2.6 與其他依賴,VRAM 仍夠用;但如果你在同一個 process 又跑了更大的 LLM(例如 7B 模型),就會 OOM。對應排查:用 model.half() 轉 fp16,VRAM 占用直接砍半;或把 LLM 放到第二個 process。

錯誤三:model.encode 回傳的向量是 fp64,Qdrant 上傳時報 dtype 錯誤。Qdrant 1.12 預期 float32;fp64 會在 PointStruct 序列化時失敗。對應排查:model.encode(..., convert_to_numpy=True).astype("float32") 強制轉型,或在 model.encode 後加 .astype(np.float32)。

錯誤四:metadata para_id 用中文,導致 Qdrant payload filter 失敗。Qdrant 對字串 payload 的 filter 區分大小寫、空白敏感、與儲存時完全一致才會命中。對應排查:把 para_id 改為 f"{title}_{i}"(拉丁字元 + 數字),避免編碼問題。

錯誤五:搜尋結果看起來不相關,但其實是切段造成。例如查詢「台北捷運」找到的段落是「台北捷運是台北都會區的捷運系統…」前面的導言,但分數只有 0.55,懷疑是模型出問題。實際上是因為這段同時包含「台北」「捷運」「都會區」三個概念,向量被「沖淡」到無明顯方向。對應排查:把段落的字數上限從 500 降到 200–300,讓每段的語意更集中。

效能與實務提醒

Colab T4 上 240 段的編碼約 38 秒,查詢每次 model.encode 加上 Qdrant ANN 搜尋共約 60–80 毫秒;CPU 上編碼拉長到 8 分鐘、查詢仍維持在毫秒級。Qdrant :memory: 模式在 process 結束後釋放,適合 notebook;正式部署要改 QdrantClient(url="http://server:6333") 接外部服務。

實務上有兩個常見瓶頸:第一個是大語料的初次編碼時間,10 萬段在 T4 上要 4–5 小時。建議用 model.encode(..., batch_size=128, output_value="vector") 並把向量預存到磁碟(例如 np.save("vectors.npy", vectors)),之後重啟直接載入、跳過編碼階段。第二個是冷啟動後第一次查詢較慢(HNSW 索引從磁碟載入),實務上會做「服務啟動後先預熱」——跑一輪 dummy 查詢把索引載入記憶體。

另一個常被忽略的細節是段落排序對結果的影響。維基百科的段落從導言開始,越後面越細節;如果你的查詢偏向「該條目的核心概念」,導言段落應該排前面;如果偏向「具體事實(例如 2024 年的事件)」,後段段落更重要。本篇的 split_paragraphs 沒有改動原始順序,這對大多數查詢足夠;但如果你的資料是時間序列(例如客服對話紀錄、研究日誌),可以加一個「時間欄位」、讓查詢時可以選擇「最近 N 天」這個 metadata filter。此外,Qdrant 預設會根據 payload 中的數值欄位建索引,但對純文字欄位(例如 title)需要明確建立全文索引才會生效,這是維運時容易踩到的坑。

另一個重要的設計選擇是「段落的 metadata filter 順序」。本篇的查詢 B 先加 topic filter 再做向量搜尋,這對「限定類別」很有用;但若你的 metadata 過濾掉太多資料(例如只篩某個極少見的小分類),會讓候選集合太小、ANN 退化成暴力搜尋。實務上會把「極少見的 metadata filter」轉成「先做向量搜尋、再用 filter 移除」的反向流程。明天我們會把今天的檢索結果接到 LLM,示範完整的 RAG 查詢設計。

小結

今天把 Day 22 的相似句、Day 23 的向量資料庫接到真實語料上:我們從維基百科的 5 個精選條目抓出 240 個段落,用 paraphrase-multilingual-MiniLM-L12-v2 編碼成 384 維向量、寫進 Qdrant 1.12 的 in-process 模式,再用「台北最高的建築物」「地下鐵路運輸系統」等查詢示範語意搜尋的威力。重點回顧:段落切分粒度(80–500 字)是中文檢索的甜蜜點、多語言模型對中文的支援優於純英文模型、metadata filter 要在 ANN 之前套用、語意查詢能召回跨同義詞的段落(捷運、地鐵、MRT)。我們用「捷運 vs 地下鐵路運輸系統」的對照組證明語意搜尋比純關鍵字強很多——這正是 RAG 系統會有今天這個熱潮的核心原因。明天我們會把檢索結果送進 LLM,組成完整的 RAG 流程。

結語

今天的重點是「把檢索這一層從 toy example 拉到真實語料」。我們用了 wikipedia-api 從繁體中文維基抓取「台北、東京、深度學習、半導體、台灣」5 個精選條目(CC BY-SA 4.0)、用 paraphrase-multilingual-MiniLM-L12-v2 編碼 240 個段落、寫進 Qdrant 1.12,再用「台北最高的建築物」「地下鐵路運輸系統」等查詢示範了語意搜尋召回同義詞段落的能力。讀完這篇你應該能回答:為什麼 RAG 系統需要 metadata filter?為什麼語意查詢比純關鍵字強?段落切分的字數上下限要怎麼設?為什麼 wikipedia-api 強制要求 User-Agent?metadata filter 應該寫在 ANN 之前還是之後?

檢索只是 RAG 的一半。明天,我們會把今天的檢索結果接到 LLM(用本地 Ollama 上的小模型或 Colab 上的開源模型),示範「query → retrieve → prompt → generate」四步完整 RAG 流程,並比較「有檢索 vs 沒檢索」的回答品質差異。

延伸資源

  • sentence-transformers 多語言模型清單(2025):https://www.sbert.net/docs/sentence_transformer/pretrained_models.html,paraphrase-multilingual-MiniLM-L12-v2、distiluse-base-multilingual-cased-v2 等多語言模型的對照表與 STS benchmark 分數。
  • Qdrant 1.12 官方文件(2025):https://qdrant.tech/documentation/,Filter、FieldCondition、MatchValue 的完整語法與 payload 索引設計。
  • wikipedia-api 官方文件(2024):https://wikipedia-api.readthedocs.io/,Wikipedia 物件的 page()、search()、summary() 等 API。
  • 繁體中文維基百科精選條目(CC BY-SA 4.0):https://zh.wikipedia.org/wiki/Wikipedia:%E7%B2%BE%E9%81%B8%E6%96%87%E7%AB%A0,本系列使用的 5 個條目都來自這份清單。
  • MS MARCO 資料集(Microsoft,2016):https://microsoft.github.io/msmarco/,語意搜尋領域最常引用的英文 benchmark 之一,與今天的 paraphrase 系列模型關聯密切。

留言

這個網誌中的熱門文章

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 中,資料型別決定我們可以對變數進行哪些操作...

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 建構深度學習模型。 開發者與研究人員 :想更深入了...

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 等工具能處理和分析龐...