# ISpan - AIML ## 課程內容 * [講義]( https://www.dropbox.com/scl/fi/gxap5x1y21fg7huhq16yn/ML_tutorial_v2023.11.pdf?rlkey=9whcce7uyesw1jtl2etkvrxoh&dl=1) * [資料集]( https://www.dropbox.com/scl/fi/3142w9biv0e3oah7ceb78/AIEN_ML_v2023.11.tar.gz?rlkey=mx40qg71nc1q58677til19jpv&dl=) * [Bad Smells](https://hackmd.io/@chweng/SJGYx4SNp) * [SOLID](https://hackmd.io/@chweng/HyQcnEHNa) ## 補充資訊 (2023/11/26) * 何謂Gini * ![IMG_0154](https://hackmd.io/_uploads/SkAHhQeBa.jpg) * 目標: 做好的決策 (選擇能夠最大化Gini的決策) * ![IMG_0155](https://hackmd.io/_uploads/rJAr37lS6.jpg) * 資料檢索 * `dfTest[dfTest["AgeInfo"] == 'children'].head(3) # 選擇是小孩的樣本` * PCA看單位向量於水平方向夾角 ```python= for j in range(2): x, y = pca.components_[j] print( f"unit vector degree= {np.degrees(np.arctan2(y, x))}" ) print( f"unit vector= {pca.components_[j]}\n" ) ``` * DBSCAN調參數使得群數可以自行決定 ```python= for eps in np.linspace(1, 0.01, 100): db = DBSCAN(eps=eps, min_samples=5, metric='euclidean') y_db = db.fit_predict(X) unique_labels = np.unique(y_db) # [-1(outlier), 0, 1, ...] num_unique_labels = len(unique_labels) if num_unique_labels >= 3: break print(eps, unique_labels) colors = ['yellow', 'red', 'black'] for j in unique_labels: plt.scatter( X[y_db == j, 0], X[y_db == j, 1], color=colors[j], ) plt.show() ``` ## 補充資訊 (2023/11/25) * 套件追加mlxtend (用於畫決策邊界) * `poetry lock --no-update` # 追加新套件的時候,不要順便把其他的套件更新到允許的最新版本 * `np.stack`, `np.concatenate`操作 ```python= # np.vstack([a, b]) # stack at vertical axis (axis=0); Shape=[ [m, n], [m, n] ] -> [2m, n] # np.hstack([a, b]) # stack at horizontal axis (axis=1); Shape=[ [m, n], [m, n] ] -> [m, 2n] # np.stack([a, b], axis=-1) # (用於超過兩個維度的張量; 不太好用; 先不要用) # 若覺得stack API太複雜,用concatenate就好: # np.concatenate([a, b], axis=0) # Shape=[ [m, n], [m, n] ] -> [2m, n] # np.concatenate([a, b], axis=1) # Shape=[ [m, n], [m, n] ] -> [m, 2n] ``` * SVM ![](https://static.javatpoint.com/tutorial/machine-learning/images/support-vector-machine-algorithm.png) * predict_proba ```python= classifier = SVC(kernel='rbf', probability=True) model = classifier.fit(X, y) pred_prob = model.predict_proba(X) # [num_samples, num_classes] assert np.all(pred_prob.argmax(axis=-1) == model.predict(X)) thresh = 0.1 # 想要recall高 (寧可錯抓不可漏抓);換句話說: 模型稍微有點相信是1, 就讓他預測是1 (pred_prob[:, 1] >= thresh).astype(int) thresh = 0.9 # 想要precision高 (寧可漏抓不可錯抓);換句話說: 模型非常相信是1, 才讓他預測是1 (pred_prob[:, 1] >= thresh).astype(int) ``` * LogisticRegression的multi_class * multi_class=`ovr` * 建立多個二元分類模型(Logistic classifier)做多元分類 * multi_class=`multinomial` * 建立單一模型(Softmax classifier)做多元分類 * LogisticRegression的class_weight * 預設是 None (不做Loss加權) * 'balanced' (將比較少見的樣本, 其樣本Loss放大. 可使優化器更加關注較少見的樣本, 將較少見的樣本的Loss降低) * 使用pathlib找檔案 ```python= from pathlib import Path paths = [(path.parent.stem, str(path)) for path in Path('../datasets/mnist/').glob("**/*.jpg")] ``` * Data Imbalance 怎麼辦? * Loss * 使用class_weight對較少見的樣本其樣本Loss加權 -> 讓優化器更加關注於該類樣本誤差優化. * 嘗試[focal loss](https://arxiv.org/abs/1708.02002) -> 置信度較高的, 易學樣本, 將其樣本Loss降低. 使得模型關注較難的(較低置信度的)樣本. * 一些常見也好學的樣本, 於訓練過程, 模型會對其屬於某個類別的置信度慢慢提升(例: `>0.8`). * 不常見或不好學的樣本, 即使訓練到接近末期, 模型還是難以判斷它應該是屬於哪個類別(有低置信度) * Data * 製作Dataloader (資料抽樣器). 使得每次取出一個批次的數據量時, 該批次的樣本盡量每個類別數量都差不多. * 資料若切三分 * train: 訓練模型 * validation: 選擇模型(調參); model selection, hyperparameter fine-tuning * test: * 測試最終選出的模型表現如何 * 若測試資料集有額外挑選過, 放入一些較複雜或是較接近真實應用場景的資料, 則有助於驗證模型的泛化(generalizability)能力 * 選出最好模型看分類報告 ```python= predY = dfSorted["classifier"].iloc[0].predict(testX) print(classification_report(testY, predY)) ``` * 到底GridSearchCV建立了幾個模型呢? * cv=5 (5 fold) * grid: {'penalty': ['l1', 'l2'], 'c': [0.01, 0.1, 1, 10]} (8 model settings) * 總共建立了 8 x 5 + 1(最後拿最佳模型設定在整個5-fold上面去訓練出來的一個模型) = 41個模型 * 當你使用model.predict的時候,會拿最佳模型(看過整個5-fold訓練/驗證用資料集)來做預測 ## 補充資訊 (2023/11/19) * 煉丹心法 * Bag of tricks * https://arxiv.org/abs/1812.01187 (提及Learning rate該如何排程) * Bag of specials (有價的提升技巧) * Bag of freebies (免費的提升技巧) * https://arxiv.org/abs/1902.04103v3 * https://arxiv.org/pdf/2207.02696.pdf * 建立寫`assert`的習慣, 未來可替自己開發的class/function寫測試(利用[pytest](https://docs.pytest.org/en/7.4.x/)或類似框架) * 一直做隕石開發的話, 有可能很難從早期的職業生涯開始累積軟工實力, 因為一直應付上級, 疲於奔命(https://disp.cc/b/Soft_Job/aEhO) * TensorFlow裡面有L1或L2可以用 (https://www.tensorflow.org/api_docs/python/tf/keras/regularizers/L1) * 01筆記本建議練習(回家作業): 1. 去掉房價離群值, 所有特徵欄位都給予, 看R2表現 2. 去掉房價離群值, 所有特徵欄位都給予, 並追加所有特徵欄位的平方當作額外的特徵欄位, 看R2表現 ## 補充資訊 (2023/11/18) * ![截圖 2023-11-18 上午9.07.25](https://hackmd.io/_uploads/SyyuRtSVp.png) * 五種壞味道 * 第一個 過於攏長的類 -> 可能包含很多特製業務邏輯 -> 不好復用 (用一次就丟 不夠精實 對別人沒啥幫助) * 第二個 不正確的繼承 -> 多了一些不恰當的, 父類別給予的方法可以使用. (但其實不是真的能用 -> 導致使用此物件的人要非常小心/要很注意 -> 不好用) * 第三個 程式碼有防止改動的特性 -> 牽一髮動全身(舉例來說, 改一個網路層會影響另一個完全不相干的"優化器"類別. 那不確定性太大了. 誰敢改?) * 第四個 過多的不必要耦合性(coupling). 會導致難以修改或復用. * 第五個 過多垃圾(例如說含有沒必要的屬性), 或是過多的不必要開發(未雨綢繆不一定是好事) * if-else區塊可用其他架構替代 (https://www.youtube.com/shorts/psu7LYIyQAo) * 資料表通常有兩個索引來描述. $X_{i}^{(j)}$, 其中i是第i個特徵欄位, j是第j筆資料. X的形狀: `[batch_size, num_features]`. * Dense層的輸入/輸出張量形狀是`[batch_size, num_features]`. * 2D捲積層(`Conv2D`)的輸入/輸出張量, 其形狀為何? `[batch_size, height, width, num_channels]` * 1D捲積層(`Conv1D`)的輸入/輸出張量, 其形狀為何? `[batch_size, width, num_channels]` * RNN層(`LSTM`)的輸入/輸出張量, 其形狀為何? `[batch_size, num_time_steps, num_features]` * Likelihood function和 Loss的關係 * $\hat{y} = wx + b$ * $\xi^{(i)} = \hat{y}^{(i)} - y^{(i)} \sim N(0, 1) \sim exp(-\frac{1}{2}( \hat{y}^{(i)} - y^{(i)})^2)$ * $Likelihood \sim \xi^{(1)}\xi^{(2)}...\xi^{(N)} \sim exp(-\frac{1}{2}( \hat{y}^{(1)} - y^{(1)})^2)exp(-\frac{1}{2}( \hat{y}^{(2)} - y^{(2)})^2)...exp(-\frac{1}{2}( \hat{y}^{(N)} - y^{(N)})^2)$ * $Likelihood \sim exp(-\frac{1}{2} \sum_j ( \hat{y}^{(j)} - y^{(j)})^2)$ * 目標: 調整w, b去最大化Likelihood使得所有樣本誤差於0附近跳動(都很接近0; 符合標準常態分布) <=> 調整w, b去最大化Log Likelihood使得所有樣本誤差於0附近跳動(都很接近0; 符合標準常態分布) * $Log~Likelihood \sim -\frac{1}{2} \sum_j ( \hat{y}^{(j)} - y^{(j)})^2$ * Let $Loss = -Log~Likelihood$後, 可發現: * 調整$w$, $b$去**最大化** $Log~Likelihood$ 使得所有樣本誤差於0附近跳動(都很接近0; 符合標準常態分布) <=> * 調整w, b去**最小化** $Loss(=\frac{1}{2} \sum_j ( \hat{y}^{(j)} - y^{(j)})^2)$使得所有樣本誤差於0附近跳動(都很接近0; 符合標準常態分布) -> 得到 **Mean Square Error Loss **. ## 環境設置 ### 建置 virtualenv 開啟anaconda prompt終端機. 執行以下指令, 以使用Anaconda建置本次課程使用的虛擬環境(virtualenv): ```python= conda create -n ml python=3.10 ``` ### Poetry 設置 * [Poetry 網站](https://python-poetry.org/docs/#installing-with-the-official-installer) 1. 安裝Poetry ```bash= (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py - ``` 2. 設定Poetry 依照Poetry建議, 將`C:\Users\Student\AppData\Roaming\Python\Scripts` 加入PATH.加好後重啟終端機, 執行`poetry`, 看是否生效. ```bash= poetry config virtualenvs.path C:\Users\Student\anaconda3\envs\ml poetry config virtualenvs.create false ``` 3. 安裝課程相關套件 ![未命名](https://hackmd.io/_uploads/H1NgzirEp.png) ### Python Coding Style * Linter: `pylance` * Formatter: `black`, `isort` * 設置Black (format on save) ![未命名.png](https://hackmd.io/_uploads/S17227Q7a.png) * 設置isort (sort on save) 將下述設定加到`settings.json`: ```json "editor.codeActionsOnSave": { "source.organizeImports": true } ``` ![未命名2.png](https://hackmd.io/_uploads/rkOLAmX7p.png) * 加強自己程式碼的易讀性 * 善用`docstring`, `type hint` * follow, e.g., [Google's Python Coding Style Guide](https://google.github.io/styleguide/pyguide.html) * vscode常用套件? * `even better toml`, `reload`, `remote ssh`, `Docker`, ... * jupyter notebook: * 搜尋notebook format on save, 把它打勾 * type hint: * 搜尋type hint, 開啟python analysis -> inlay hint (將function return types那一行打勾) --- ## 參考連結 * Code Refactor: https://refactoring.guru/refactoring/how-to * Design Pattern, Python basics: https://www.youtube.com/@ArjanCodes * Find state-of-art model implementations (if papers are with codes :arrow_right: :100:): https://paperswithcode.com * Understand CNN basics (:100: you must read this, understand every lines of words): https://cs231n.github.io * karparthy: https://www.youtube.com/results?search_query=karparthy * Learn Deep Learning basics (Wow! Learning by doing! :100:): https://zh.d2l.ai * Machine Learning basic theories (:100: for those who wants to understand every general bits of maths in Machine Learning): https://cs229.stanford.edu/notes2022fall/main_notes.pdf * Understand Backpropagation: https://www.cs.toronto.edu/~hinton/absps/NatureDeepReview.pdf * Python Machine Learning (Sebastian Raschka) * Keras book: https://www.manning.com/books/deep-learning-with-python --- wengchihung@gmail.com