# CS231N (2017) Lec 02 課程筆記 ###### tags: `CV` 🔷 影像分類 Image Classification 2:54 https://www.bilibili.com/video/BV1Dx411n7UE/?p=2&spm_id_from=pageDriver 📌 備註-1 > Resources 🔘 TA Justin Johnson 🔘 Python Numpy Tutorial (with Jupyter and Colab) https://cs231n.github.io/python-numpy-tutorial/ 📌 備註-2 > HW-1: 🔘 K-Nearest Neighbor 🔘 Linear classifiers: SVM, Softmax 🔘 Two-layer neural network 🔘 Image features 📌 A concept: Input & Output 🔘 Input: images (number array) + "labels" (categories) ➡️ labels: A "fixed" set of category labels ➡️ images: For example, the size is 800 x 600 x 3, representing the height is 800, the width is 600, and the depth is 3 (=> 3 channel RGB). 🔘 Output: a "predicted (estimated) label" for the specific test input image 📌 The Problem & Challenges 🔘 The Problem: Semantic Gap (語意鴻溝) 將 訓練資料集 的 影像 和 標籤 相互對應的困難性 // 「影像」一般表示為一個巨大的「數值矩陣」 // 但這個「數值矩陣」跟「標籤 (語意標籤)」之間的關係 // 對電腦而言似乎無法 "直觀地" 對映 // 這問題稱為 語意鴻溝 🔘 Challenges: Viewpoint variation (視角變化) ▫️ 姿勢改變: 細微的 (subtle) 像素變化 ▫️ 鏡頭位置改變: 目標物體的視角變化 // 挑戰: 假設要做 "貓咪辨識" // 在下列前提之下: (1) 貓的姿勢改變 (2) 鏡頭位置改變 (但貓本身不變) // (=> Every sinle grid or pixel would be different.) // 仍能得到 "相同的" 辨識結果 (=> represent as the same cat) // 才能稱在 Viewpoint variation 具有良好的 "強健性" 🔘 Challenges: Illumination (照明) // No matter the scene is "dark" or "bright", // our algorithm need to be robust to that. // 不論在夕陽下、黑暗的電影場景下 (各種照明條件), // 都能辨識出 "貓" 的結果 // 才能稱在 Illumination 具有強健性 🔘 Challenges: Deformation (形變) // 物體因自身柔軟度 (如: cat | different poses and positions) 或外力導致形變 // 形變前、形變後的不同影像,利用某演算法,能對映同一個預測的語意標籤 // 才能稱在 Deformation 具有強健性 🔘 Challenges: Occlusion (遮蔽) // 只看到物體的其中一角,仍能得到與完整呈現的物體 "相同" 的辨識結果 // 才能稱在 Occlusion 具有強健性 🔘 Challenges: Background Clutter (背景混亂) // 在不同的背景之下,針對前景物體的辨識,能得到 "相同" 的辨識結果 // 才能稱在 Background Clutter 具有強健性 🔘 Challenges: Intraclass variation (組內變化) // 例: 貓咪的組內變化 // 要素 → 形狀, 大小, 顏色, 年齡 📌 Attempts have been made // i.e., 基於傳統影像處理方法 嘗試解決 影像分類 🔘 API ▫️ classify (input_image) 輸入影像會逐一執行特徵提取的影像處理步驟, 再根據特定規則得到一個「預測標籤」輸出值 🔘 Example: 貓咪辨識 (貓咪分類器) ▫️ 特徵: 耳朵、眼睛、嘴巴、鼻子 ▫️ 特徵分析: 邊緣特徵 Hubel & Wiesel 的研究表明: 視覺辨識任務中, 「邊緣特徵」通常很重要 ▫️ 傳統影像處理方法 - 「影像分類」: 步驟 (1) Find edges 將 原始影像 提取出 邊緣特徵圖,並做二值化 => 使: 「邊緣線條」為白色,其它部分皆為黑色 => 並且邊緣線條若斷掉,能將其補起來 (2) Find corners - 檢測 (detect): 角點 (corner points) - 邊界 (boundaries) (3) Record the exclipit set of rules (記錄明確的規則組合) (4) Predict 🔘 傳統影像處理方法在「影像分類」的劣勢 廣泛性 (generalization) 差 --------------------------------------- => 不同種類的物件的規則組合間,特徵差異可能很大 若需對不同種類的物件,以傳統影像處理方法做「影像分類」 需要逐一制定 "特定的" 步驟,以辨識 "特定的" 特徵集合 📌 Data-Driven Approach 🔘 Steps 1. Collect a dataset of images and labels 2. Use Machine Learning to train a classifier 3. Evaluate the classifier on new images 🔘 API ▫️ train (train_images, train_labels) 輸出值: model ▫️ predict (model, test_images) 輸出值: predicted_labels // 過去的 10 ~ 20 年,電腦視覺研究的主要方法大致奠基於上述概念 🔘 Dataset ▫️ example: CIFAR-10 🔘 Distance Metric ▫️ example: L1 distance = Manhattan distance (曼哈頓距離) = City block distance ➡️ The sum of the absolute values of the pixels ➡️ | x1 - x2 | + | y1 - y2 | where P1 (x1,y1) and P2 (x2,y2) ➡️ 延伸意義: L1 距離取決於座標軸 ("Coordinates Dependency") => 若座標軸經旋轉,兩點間的 L1 距離會改變 => 若座標軸「有特殊意義」且有清楚定義或認識 可以採用 L1 距離;否則不要用 ▫️ example: L2 distance = Euclidean distance (歐式距離) ➡️ The sum of the absolute values of the pixels ➡️ [ ( x1 - x2 ) ^ 2 + ( y1 - y2 ) ^ 2 ] ^ 0.5 where P1 (x1,y1) and P2 (x2,y2) ➡️ 延伸意義: L2 距離不取決於座標軸 => 若座標軸經旋轉,兩點間的 L1 距離不會改變 => 若不太能區分座標軸之間有何差異或影響 採用 L2 距離比較保險 ▫️ Distance Metric 的用途 Distance Metric 不僅可用於 vectors 或 images 間的比較 甚至 (NLP 領域) 兩個段落文字,或兩個句子 皆可指定 Distance Metric 進而計算相似性 ▫️ 如何選擇 Distance Metric 及 KNN 中的 K 值 ? => Distance Metric、KNN 中的 K 值,稱為「超參數」(hyperparameters) 基本上 "無法" 從訓練資料集中學習得到 => How to choose hyperpameter in the practice ? Ans: Depending on the "problem" and the "data", trying different hyper-parameters, and finally choose the best. 🔷 KNN Classifier 📌 KNN (K-Nearest Neighbor) Classifier 🔘 Introduction 某個點的「預測標籤」會針對 K 個距離最近的點,採「多數決」方式決定 🔘 KNN 視覺化: 繪製其決策區域 (decision region) (1) 高維度平面的散佈圖 (2) 對應回資料集的實際影像 (concrete images) 一般使用 KNN 做影像分類,會將上述兩種方式來回/交替使用 📌 設定超參數: 拆分資料集 (train, val, test) Problem: How to choose the hyperparemeters? (1) Idea 1: 不拆分資料集 (皆為訓練資料) >> 取 perforamce 或 accuracy 表現最好的超參數 --- ( ❌ ) 🔘 永遠不建議採用此方法 🔘 原因: 會 Overfitting, KNN 分類器選到的總會是 K = 1 (殘差最小, 最佳擬合) 🔘 即: 「以『訓練資料』的表現作為評估超參數的依據」 會導致: 訓練資料外的資料「無從評估」 因此選擇出的超參數不能推廣、泛化到非訓練資料 (2) Idea 2: 拆分資料集為 train、test 兩堆 >> 取在 test data 上,perforamce 或 accuracy 表現最好的超參數 --- ( ❌ ) 🔘 永遠不建議採用此方法 🔘 原因: 每個 test data 用來評估超參數後,test data 會失去代表性 🔘 即: 「以『測試資料』的表現作為評估超參數的依據」 會導致: 測試資料外的資料「無從評估」 因此選擇出的超參數不能推廣、泛化到非測試資料 (3) Idea 3: 拆分資料集為 train、test、validation 三堆 >> 取在 test data 上,perforamce 或 accuracy 表現最好的超參數 --- ( ⭕ ) 🔘 建議採用此方法 🔘 做法: Step 1. 採用「不同的超參數」,以「訓練集」訓練模型 Step 2. 選擇在「驗證集」表現最佳的超參數 Step 3. 最後在「測試集」上以 Step 2. 選擇的超參數跑一次 // 通常測試集是「最後跑的」 // 測試集被視為 unseen data,論文的最終資料也只列出測試集結果 // // 測試資料的順位放在 "最後" 並且 "只跑一次" 很重要! // 確保沒有洩漏「測試資料」(偷看答案) 進而對模型或超參數作弊 (4) Cross Validation 交叉驗證 也可用來設定超參數 常用於小型資料集 但大型資料集的深度學習較不常用 (因為計算量較大,計算成本較昂貴) -------- 做法: (以 5-fold 為例) 總共執行五輪: 每一輪取其中一個 fold 與其它四個 folds 比較 >> 可決定一個最佳的 fold,將最佳 fold 設定為 validation set >> 拆分 train, val, test 資料集 (5) 問題: training set 和 validation set 的最大差異 ? training set ➡️ 分類器中,用來 "記憶"「標籤 (Y)」與 影像特徵 (X) 間對應關係的資料集 validation set ➡️ 分類器中,用來選擇「超參數」的資料集 ➡️ 與 training set 最大差異是: 標籤 在 validation set 中並非用來更新權重 (最佳化目標函數) 而是單純用來選擇表現更好的超參數 (6) 問題: test set 的資料是否可能不夠具有代表性, 造成在 test set 表現好、但在 data in the wild 表現差? Ans: 實務上有可能,主要是資料的問題 (責任來自 data collector) 而 test set 對於 unseen data 有代表性的前提是: (1) dataset 服從 "獨立且相同分佈" (i.i.d.) (2) dataset 來自 "隨機抽樣" // 可能會因為蒐集資料的時間順序不同 // 導致如: 較早的資料多數分佈在 training set、較晚的資料多數分佈在 test set // 這樣可能影響 "隨機性" // => 減輕上述影響的一種策略: // Make sure the partition (拆分) is random of your entire set of data points 📌 設定超參數: K - Cross Validation Acc 圖表 (1) 水平軸: K 繪製分割線 => range(-20, 140, 20) (2) 垂直軸: Cross Validation Accuracy (3) 5-fold cross validation: 對於每個 K 值,都在五個相異的 validation folds 各自執行 📌 KNN on images "never used" (1) 測試時間 (test time) 非常慢 (2) 像素間的 distance metrics 資訊量不充足 (not informative) ➡️ 感知距離 (perceptual similarity) 是更好的方法 // 但投影片講授的範例使用 L1 (city block) 距離、歐式距離 // 這兩種 distance metric 不太適合用來描述兩張影像的相似性 (3) 維度詛咒 (the curse of dimensionality) // 主要是說明 KNN 的基礎架構 在資料分佈上沒有包含太多假設, // 因此對高維度資料使用 KNN 分類, 可能因為 高維資料的分佈不理想 導致效果不彰 ➡️ 1. 訓練樣本點之間距離太遠 >> 樣本資料點無法密集覆蓋樣本空間 >> KNN 抓的測試資料(相近的鄰居) 與 input img 實際上不相似 ➡️ 2. 嘗試著蒐集 "大量樣本": 試圖讓樣本資料點密集覆蓋樣本空間 >> 在低維度所需樣本數還不大, 但高維空間的所需樣本數隨維度增加,呈 "指數型上升" // => 可能的改善方法: 對訓練資料分佈做些調整 (如: curved shape) 📌 KNN: Summary (1) 訓練集 (training set) ➡️ 利用 "大量影像" 和 "大量標籤" 訓練模型 測試集 (test set) ➡️ 用於 "預測出一個標籤" (2) 「預測」主要基於 "最相近的幾個訓練樣本" (3) 超參數: (a) K (b) distance metric (4) 驗證集 (validation set) ➡️ 用於選擇超參數 🔷 Linear Classification // 前面介紹的 KNN 分類器保留原始 "訓練資料 X" 而此處介紹的 線性分類器 最大的不同是多了 "權重 W" => 優勢: "測試階段" 只需「載入權重」即可 預測,省下空間、可在行動裝置執行 📌 Parametric Appraoch: Linear Classification (1) input 🔘 X 🔘 shape Array of "32 x 32 x 3" numbers ( 3072 numbers total ) 🔘 classes 10 classes (2) operation 🔘 f ( X , W ) 🔘 shape of f ( X , W ) : "10 x 1" 🔘 denotes: W : weight (權重,如: 一個數值矩陣) // W 有時會用 θ 代替,取決於不同文獻的符號表示 X: input data (輸入資料,如: 一個數值向量,代表: 經平坦化的像素強度數值) b: bias (偏誤,如: 一個常數構成的數值向量) f : output (輸出,如: 一個數值向量,代表: 各類別的預測機率值) 🔘 functional form: f ( X , W ) = W X + b ➡️ shape of f : 30 x 1 ➡️ shape of W : 30 x 3072 ➡️ shape of X : 3072 x 1 ➡️ shape of b : 30 x 1 🔘 analog: 1. 輸出預測標籤 通常是一個 行向量 (column vector) 2. 「權重」通常是一個矩陣,扮演關鍵角色 3. 線性分類器 的 數值運算: W X + b 就類似傳統影像處理中的「模板匹配」: 權重矩陣 的每一列 (row) 可看作一個「模板」 (過程: 模板與原始影像的對應元素相乘後,加上偏誤向量的對應元素) 最後「輸出」向量中每一列的元素,代表屬於某類別的機率,與特定「模板」對應 // 實際上可以把每一列數值做視覺化 4. 「與特定『模板』對應」: 指的是「單一類別」只對權重矩陣中對應的「一個模板」進行學習 // 模板視覺化後,看起來像個模糊化的輪廓圖 // ➡️ 更複雜的模型可允許單一類別對超過一個模板進行學習, // 這裡的線性分類器只針對一個模板 (3) output 🔘 10 x 1 number array = 10 numbers giving class scores (probabilities) 📌 Hard cases for a linear classifier e.g.1 左圖 如: 計算物體出現數量是奇數或偶數,可能會有左圖的資料分佈 那麼使用單純的線性分類器,失敗機率很高,因為很難用一條直線 (作為決策邊界) 分成兩區 e.g.2 右圖 即 Multi-modal Situation,多峰資料 (multimodal data) 分佈在不同區域,就很難用一條直線區分 📌 Linear Classifier 優勢: 易於解釋 (interpret)、易於理解 劣勢: 資料分佈比較奇怪:難以用一條直線區分的資料