DataLoader 和 Iterator 的差異

在 trace AI 課程中的訓練代碼時, 看到 iterator 和 DataLoader 同場出現時有點暈, 我想說這兩個做的事情不是一樣嗎? 所以花點時間將這個疑惑釐清.

先講結論: Iterator 是 design pattern, DataLoader 是 PyTorch 的 class.

Iterator 做為 design pattern 的好處是: 不用管 dataset 真正長什麼樣子, 每次都都抓出一包 data, 還用不到的先不抓, 等下次抓, 以節省記憶體.

那一包要抓多大呢? 透過 DataLoader 這個 class 取得 dataloader 這個 object.

然後 data_iterator 是個 iterator, iter() 把 dataloader 轉換成可迭代的 object.

first_batch 的 type 取決 Dataset, 主要就是一包 data. 而第一次呼叫 next() 拿到的是第一包, 而不是第二包.

from torch.utils.data import DataLoader, Dataset
...
dataloader = DataLoader(dataset, batch_size=32, shuffle=True)
....
data_iterator = iter(dataloader)
first_batch = next(data_iterator)

在 Tensorflow 中, 沒有 DataLoader, 但有 tf.data.Dataset. 效果也是一次抓一包.

import tensorflow as tf

# Create a basic dataset
dataset = tf.data.Dataset.range(10)

# Apply transformations (e.g., batch, shuffle)
batched_dataset = dataset.batch(2)

# Iterate through the dataset
for batch in batched_dataset:
    print(batch)

Model.pb 小註解

這個檔案是用來放 model 的 protocol buffer, 所以叫做 pb. 當我們對 input raw data 做了一些前處理, 然後才去 train model. 那使用這個 model 的天命任意人, 怎麼知道要用那些 pre-processing 的手法來處理他的真實資料呢? 沒錯! 就是去看這個 model.bp.

Model.bp 不只是記錄 metadata 這麼簡單, 它只是三個主要功能之一. 這三個功能分別是:

  1. Model Graph: 把 model 的 graph 記下來. 這個 graph 不是個圖檔, 是資料結構裡面的 graph, 它定義了 model 的資料流向.
  2. Metadata: 主要是 input 和 output 的 tensor information. 不論是做前處理或是後處理都會參考到.
  3. Portability: Model 作者最初可能是用 Tensorflow, Tensorflow Lite, 或者Tensorflow.JS 開發, 使用者 deploy 的 platform 不同於作者時, 也可以參考這個檔案獲得相容性資訊.

講到前處理, 另一個 keyword 是 tf.Transform. 這個 library 專門做 Tensorflow 的前處理用. Graph 也是它產生的. tf.Transform 整合了 Apache Beam, (Google) cloud Dataflow, 和 TensorFlow 兩種不同的處理方式 [1][2].

請留意 tf.Transform 是在 pre-process 階段做 feature engineering, 而 Apache Beam 和 Cloud Dataflow 是在 feature creation 階段. 所以後者提供 API 給 tf.Transform 使用. 第三個可以執行 feture engineering 的階段是 train model. 在 [1] 裡面寫了 1,2,3 三個圈圈, 順序和我提到的相反, 但是那沒關係, 只是做個區隔.

附帶一提 Beam 可以用更多的 programming language, 像是 Java, Python, 和 SQL. Tensorflow 基本上多了 C++, Javascript, 少了 SQL. 總之學 Python 就對了.

[REF]

  1. https://ithelp.ithome.com.tw/articles/10227075
  2. https://www.tensorflow.org/tfx/transform/get_started
  3. https://towardsdatascience.com/hands-on-apache-beam-building-data-pipelines-in-python-6548898b66a5

Feature Engineering 備忘小筆記

對 AI 有興趣的我, 其實比較喜歡研究 model 的原理, 對於資料的處理沒興趣. 不過偶爾要用到某個語法, 卻又記不起來的話, 還是會有點傷腦筋! 所以筆記一下加深印象. 以後也好查詢.

  1. dataframe 轉 dataset
def df_to_dataset(dataframe):
    dataframe = dataframe.copy()
    
    labels = dataframe.pop('your target')
    ds = tf.data.Dataset.from_tensor_slices((dict(dataframe), labels))
                            
    return ds

2. Categorical 轉 Numeral (one-hot)

from tensorflow import feature_column as fc

# invest_df is predefined dataframe

A = ['stock','bond','ETF']
B = []

for C in A:
    D = invest_df[C].unique()
    E = fc.categorical_column_with_vocabulary_list(C, D)
    F = fc.indicator_column(E)
    B.append(F)

3. Bucketized 轉 numerical

G = fc.numeric_column("net_asset")
​
# Bucketized cols
H = fc.bucketized_column(G, boundaries=[10, 20, 30, 40, 50, 60, 80, 100]) # in million USD
B.append(H)

4. Feature Cross (Bucketized + Categorical)

I = invest_df['FATFIRE_proximity'].unique()
J = fc.categorical_column_with_vocabulary_list('FATFIRE_proximity',I)
​
crossed_feature = fc.crossed_column([H, I],hash_bucket_size=1000)
crossed_feature = fc.indicator_column(crossed_feature)
B.append(crossed_feature)

5. 實際運用

# input_dim = 上述的 feature 個數, 此時 = 8
# 假設下一層是 12 nodes.
# 8 x 12 是 fully connected.

feature_layer = tf.keras.layers.DenseFeatures(B, dtype='float64')
​
model = tf.keras.Sequential([
  feature_layer,
  layers.Dense(12, input_dim=8, activation='relu'),
  layers.Dense(8, activation='relu'),
  layers.Dense(1, activation='linear',  name='your target')
])

6. 產生新的 Bucketetized feature 做成 Feature Cross


    M = np.linspace(0, 1, nbuckets).tolist()
    N = np.linspace(0, 1, nbuckets).tolist()

    OP = fc.bucketized_column(B['OPEN_PRICE'], M)
    CP = fc.bucketized_column(B['CLOSE_PRICE'], M)
    OV = fc.bucketized_column(B['OPEN_VOL'], N)
    CV = fc.bucketized_column(B['CLOSE_VOL'], N)

    OO = fc.crossed_column([OP, OV], nbuckets * nbuckets)
    CC = fc.crossed_column([CP, CV], nbuckets * nbuckets)

    new_bucket_cross_feature = fc.crossed_column([OO, CC], nbuckets ** 4)

7. 畫出酷炫流程圖並存檔

tf.keras.utils.plot_model(model, 'model.png', show_shapes=False, rankdir='LR') # or 'TB'

Give Myself a Pat on the Back

以前連假的時候, 我都會趁機讀完一兩本書. 不過這次我用它來完成我網課的最後一哩路. 這是一個 Coursera 的 AI TensorFlow Developer 學程, 裡面包括 4 個子課程.

Introduction to TensorFlow for Artificial Intelligence, Machine Learning, and Deep Learning
Convolutional Neural Networks in TensorFlow

Natural Language Processing in TensorFlow

Sequences, Time Series and Prediction

這個課程大概需要兩個月, 本來我想我好歹也算有個一知半解吧! 打算在免費試用七天的時間就把課程走完, 不過它還是有點難度, 所以我破功了. 只好為它花了註冊費. 接著我以生日前通過為目標, 失敗! 改為 2024/3/31 前通過, 又失敗! 總算在清明連假最後一天通過最後一個 Lab 了! 花了快一個月之久.

model = tf.keras.models.Sequential([ 
    tf.keras.layers.Conv1D(64, input_shape = [64, 1], kernel_size = 3, padding = 'causal', activation = "relu"),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32,return_sequences = True)),
    tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(32)),
    tf.keras.layers.Dense(32, activation = "relu"),
    tf.keras.layers.Dense(16, activation = "relu"),
    tf.keras.layers.Dense(1),
    tf.keras.layers.Lambda(lambda x: x* 25)
]) 
model.compile(loss= tf.keras.losses.Huber(),
optimizer=tf.keras.optimizers.SGD(momentum = 0.9, learning_rate = 5e-4),
metrics=["mae"])

最後一堂課的結語是 give yourself a pat on the back. 所以我就拿它來當標題. 接下來找下一個可以學的東西.

AI 學習小筆記

前陣子發現, 網路上不只是有很多學習資源, 而且好幾個單位都證書. 雖然這些證書把關通常很鬆散, 但是用來記錄自己學了什麼就很有幫助. 換個角度看, 畢竟我們不是被逼著上課, 已經知道的或重複的就可以跳過. 而不是像在學校裡, 不能因為聽懂就翹課或是不參加考試, 那就畢不了業了.

如果說 AI 有哪個東西要先學習, 我看起來還是 Python. 然後搭配自己的專業領域使用. 像是 audio, video, image, 或者是我以前用在 OCR. 新手可以學 Python 的地方超級多, 入門也非常簡單. 所以這應該是正確的第一步無誤. 再來介紹一下錯誤的第一步.

有些人, 像是我, 從小就對人腦很有興趣. 總是會想要用人腦的特性來做出更厲害的 AI. 比方說, 有一天我想到遺忘也是人的特性, 如果讓神經網路可以遺忘, 不就是一大突破了! 哇哈哈哈…不過我很快就發現 LSTM (Long Short-Term Memory) 已經有這招了! 我又想到, 意義相似的字應該用向量表示遠近比較好! 再一查, word embedding 已經有向量觀念….嗯, 我想得到人家也想得到.

我記錄 idea 的 Onenote 筆記

所以專家幾乎都不推薦用人腦去設計 NN. 頂多是在投影片裡, 從生醫角度切入, 使人覺得更高大上 (e.g. BERT 用上 DNA 雙螺旋來講解). 除非你就是要複製人腦, 不在乎它到底能不能實用 (make money)! 至於聽起來就沒有商機則是例外. 像是 hypothalamic-pituitary-adrenal axis [6] 和 AI 的關係就只限於  Adrenal Insufficiency (腎上腺機能不全), 表示未來讓 AI 談戀愛這個領域還有發展空間.

言歸正傳. 有了語言, 接下來要找環境. 以前我傻傻地自己開 Jupyter Notebook, 後來發現 Google Colabatory 就能直接用了. 除非需要很大的算力時, 才需要用到自己 PC 的顯卡. 若只是要練習 Python, 學 AI, 直接註冊一個免費的 Colab 帳號即可, 而且很多 Google 的網路資源都可以直接調用. 不用到處找. Colab 不開 GPU/TPU 時, 預設在 no power 等級. 設定裡面可以選柯基犬、貓咪、螃蟹模式, 我還以為有什麼差別, 原來是小動物跑來跑去~~

接下來, 我認為值得按讚是 CNN. 因為除了 CNN, 很多背景知識都跟我 30 年前學的差不多. (當然我那個時候講到 CNN, 一定是先想到 Concurrent 開頭的 CNN, 不是現在 Convolution 開頭的這個 CNN). 會強調 CNN, 主要是 CNN + DNN (deep learning) 把特徵值和絕對位置脫鉤了. 這個真的很厲害.

新 model 可以留給博士們研究, 要實做就需要學 framework. Google 主推的 tensorflow [3] 有許多教學網站. 除了 Youtube 上非常多老師在教. FreeCodeCamp [2] 也 “免費" 教很多技術, 他們在介紹 AI 相關技術時也會用到 tensorflow + Colab, 我覺得挺不錯. 其中, 講解的小哥可以快速講一些基本觀念. 當然他們沒辦法一行一行 trace code, 或是把細節講得很清楚. 講師帶我們瀏覽完大概, 細節就要自己花時間看, 最好是 Colab 開起來模擬一遍.

在 Youtube 也可以找到 FreeCodeCamp 小哥 Tim 的 7 小時學 tensorflow. 然而, 連復仇者終局之戰都沒演那麼久了, 誰能一口氣看得完這個? 所幸在 FreeCodeCamp 上, 這個影片會被分成大約每 15 分鐘一段的短片, 每個短片後面還有一個小測驗, 算是滿貼心的設計. 這樣就不需要太考驗耐心.

然而, FreeCodeCamp 不是 Google 這種大戶, 所以它需要大家自願 donate 才活得下去 (5 USD 起跳, 每個月捐 20 USD 可以讓其他人學習 1 千小時.). 畢竟 lib 或是 tool 會過時, 隔一陣子確實該更新或 debug. 像是 tensorflow 小哥影片中的 sklearn 已經可以改用新版的 scikit-learn, 或者講 DNN 的老哥在 7’51″ 這個地方線的顏色有些不對, 按圖 negative * negative 應該是 positive, 後續影片播到 10’10″ 左右這兩條線才更正為 positive. 總之, 他們值得贊助, 也需要贊助.

至於要學另一個主流 framework 是 Pytorch, 教學影片除了 Youtube, 就只找到 Microsoft [4]. Pytorch 當初是 Meta 推的, 不過 Meta 好像跟 Google, Microsoft (OpenAI) 的發展沒得比. 但是看在開源 llama2 的份上, 我對 Meta 感激不盡, 也原諒它一直偷聽我講話.

基於我們不會大改 model, 用 LoRA (Low-Rank Adaptation) [5] 可以小改. LoRA 訴求主要是在某幾層針對特定目標減少計算. 更小的修改是直接在既有模型後面再加一層 (或許幾層也是可以), 把原本的結果從新詮釋. FreeCodeCamp 的例子是從原本能分辨 10 種動物的模型, 改為只要能認貓或狗. 當然這沒省到計算量, 但是可以揀現成.

[REF]

  1. https://colab.research.google.com/
  2. https://www.freecodecamp.org/
  3. https://www.tensorflow.org/?hl=zh-tw
  4. https://learn.microsoft.com/zh-tw/shows/ai-show/pytorch-deep-dive
  5. https://d223302.github.io/AACL2022-Pretrain-Language-Model-Tutorial/lecture_material/AACL_2022_tutorial_PLMs.pdf
  6. https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3181830/