[AI] 3-8. 客製化 Training

內建的 fit() 只適用於監督式學習(supervised learning),然而不是所有的機器學習任務都適用,如生成式學習(generative learning)、自監督式學習(self-supervised learning)、強化式學習(reinforcement learning) 等。 監督式學習的訓練 在實作 Keras 訓練迴圈時有兩個重要細節: training 參數: 某些層(如 Dropout)在訓練和推論時行為不同 訓練時需設定 training=True 推論時設定 training=False 模型權重分類: Trainable weights: 可訓練的權重 Non-trainable weights: 不可訓練的權重(如 BatchNormalization 層的統計值) 取梯度時應使用 model.trainable_weights 以下是完整可執行範例: import tensorflow as tf from tensorflow import keras import numpy as np # 建立範例資料 x_train = np.random.random((1000, 28, 28)) y_train = np.random.randint(10, size=(1000,)) # 建立包含 Dropout 和 BatchNormalization 的模型 model = keras.Sequential([ keras.layers.Flatten(input_shape=(28, 28)), keras.layers.Dense(128), keras.layers.BatchNormalization(), keras.layers.Dropout(0.5), keras.layers.Dense(10) ]) # 損失函數與優化器 loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True) optimizer = keras.optimizers.Adam(learning_rate=1e-3) # 自定義訓練步驟 @tf.function def train_step(inputs, targets): with tf.GradientTape() as tape: # 訓練模式前向傳播 predictions = model(inputs, training=True) loss = loss_fn(targets, predictions) # 計算可訓練權重的梯度 gradients = tape.gradient(loss, model.trainable_weights) optimizer.apply_gradients(zip(gradients, model.trainable_weights)) return loss # 訓練迴圈 batch_size = 32 for epoch in range(5): print(f"\nEpoch {epoch+1}") for step in range(0, len(x_train), batch_size): x_batch = x_train[step:step + batch_size] y_batch = y_train[step:step + batch_size] loss = train_step(x_batch, y_batch) if step % 200 == 0: print(f"Step {step}: loss = {loss:.4f}") # 推論時使用 training=False test_predictions = model(x_train[:1], training=False) 評量指標 在訓練期間,我們可以用 Keras 的評量指標來查詢當前的指標值,我們會用到幾個函式: update_state(y_true, y_pred) result() reset_state() import tensorflow as tf from tensorflow import keras import numpy as np # 建立模型 model = keras.Sequential([ keras.layers.Dense(64, activation='relu'), keras.layers.Dense(10, activation='softmax') ]) # 初始化指標追蹤器 accuracy_tracker = keras.metrics.SparseCategoricalAccuracy() loss_tracker = keras.metrics.Mean() # 訓練步驟 @tf.function def train_step(inputs, targets): with tf.GradientTape() as tape: predictions = model(inputs, training=True) loss = tf.keras.losses.sparse_categorical_crossentropy(targets, predictions) # 更新梯度 gradients = tape.gradient(loss, model.trainable_weights) optimizer.apply_gradients(zip(gradients, model.trainable_weights)) # 更新指標 accuracy_tracker.update_state(targets, predictions) loss_tracker.update_state(loss) return loss # 訓練迴圈 x_train = np.random.random((1000, 32)) y_train = np.random.randint(10, size=(1000,)) optimizer = keras.optimizers.Adam() batch_size = 32 for epoch in range(3): # 重置每個 epoch 的指標 accuracy_tracker.reset_state() loss_tracker.reset_state() for step in range(0, len(x_train), batch_size): x_batch = x_train[step:step + batch_size] y_batch = y_train[step:step + batch_size] loss = train_step(x_batch, y_batch) if step % 200 == 0: print( f"Step {step}: ", f"Loss: {loss_tracker.result():.4f}, ", f"Accuracy: {accuracy_tracker.result():.4f}" ) 完整的訓練與評估迴圈 設計練訓函式 model = get_mnist_model() loss_fn = keras.losses.SparseCategoricalCrossentropy() optimizer = keras.optimizers.RMSprop() metrics = [keras.metrics.SparseCategoricalAccuracy()] loss_tracking_metric = keras.metrics.Mean() def train_step(inputs, targets): with tf.GradientTape() as tape: predictions = model(inputs, training=True) loss = loss_fn(targets, predictions) gradients = tape.gradient(loss, model.trainable_weights) optimizer.apply_gradients(zip(gradients, model.trainable_weights)) logs = {} for metric in metrics: metric.update_state(targets, predictions) logs[metric.name] = metric.result() loss_tracking_metric.update_state(loss) logs["loss"] = loss_tracking_metric.result() return logs 重置評量指標 def reset_metrics(): for metric in metrics: metric.reset_state() loss_tracking_metric.reset_state() 設計訓練迴圈 training_dataset = tf.data.Dataset.from_tensor_slices((train_images, train_labels)) training_dataset = training_dataset.batch(32) epochs = 3 for epoch in range(epochs): reset_metrics() for inputs_batch, targets_batch in training_dataset: logs = train_step(inputs_batch, targets_batch) print(f"Results at the end of epoch {epoch}") for key, value in logs.items(): print(f"...{key}: {value:.4f}") 設計評估迴圈 def test_step(inputs, targets): predictions = model(inputs, training=False) loss = loss_fn(targets, predictions) logs = {} for metric in metrics: metric.update_state(targets, predictions) logs["val_" + metric.name] = metric.result() loss_tracking_metric.update_state(loss) logs["val_loss"] = loss_tracking_metric.result() return logs val_dataset = tf.data.Dataset.from_tensor_slices((val_images, val_labels)) val_dataset = val_dataset.batch(32) reset_metrics() for inputs_batch, targets_batch in val_dataset: logs = test_step(inputs_batch, targets_batch) print("Evaluation results:") for key, value in logs.items(): print(f"...{key}: {value:.4f}") 利用 tf.function 來加速 只要在要編譯的函式前加上 @tf.function 裝飾器就可以將 TensorFlow 程式碼編譯成運算圖(computation graph)。 搭配 fit() 和自定義的訓練的迴圈 from tensorflow import keras from tensorflow.keras import layers import tensorflow as tf # 1. 將 optimizer 移到類別內部 class CustomModel(keras.Model): def __init__(self, inputs, outputs): super().__init__(inputs=inputs, outputs=outputs) self.loss_tracker = keras.metrics.Mean(name="loss") # 2. 移到類別內 self.optimizer = keras.optimizers.RMSprop() # 3. 加入 optimizer self.loss_fn = keras.losses.SparseCategoricalCrossentropy() def train_step(self, data): inputs, targets = data with tf.GradientTape() as tape: predictions = self(inputs, training=True) loss = self.loss_fn(targets, predictions) gradients = tape.gradient(loss, self.trainable_weights) self.optimizer.apply_gradients(zip(gradients, self.trainable_weights)) # 4. 使用 self.optimizer self.loss_tracker.update_state(loss) # 5. 使用 self.loss_tracker return {"loss": self.loss_tracker.result()} @property def metrics(self): return [self.loss_tracker] # 6. 使用 self.loss_trackerxqf # 建立模型 inputs = keras.Input(shape=(28 * 28,)) features = layers.Dense(512, activation="relu")(inputs) features = layers.Dropout(0.5)(features) outputs = layers.Dense(10, activation="softmax")(features) model = CustomModel(inputs=inputs, outputs=outputs) model.compile() # 7. 移除 optimizer 參數 model.fit(train_images, train_labels, epochs=3)

December 27, 2024 · 3 分鐘 · Rain Hu

[AI] 3-7. Keras API

基礎篇 1. Layer Layer 是神經網路的基本資料處理模組(data-processing module),可以接受一個或多個張量輸入,再輸出一個或多個張量。Layer 的權重可視為該層的狀態(state),在經過隨機梯度下降法(SGD)不斷更新權重(學習),最終得到損失值最低的權重值。 分類 不同格式的資料需要不同的層來處理。 密集連接層(densely connected layer): 又稱全連接層(fully connected layer)或密集層(dense layer)。如果資料輸入是簡單的 1D 向量資料,則多半是儲存在 2D 張量中,其 shape 為 (樣本 samples, 特徵 features),通常是用 循環層(recurrent layer): 如果輸入的資料是 2D 序列(sequence) 資料,多半是儲存在 3D 張量中,其 shape 為 (樣本 samples, 時戳 timestamps, 特徵 features),如 LSTM 層。 2D 卷積層: 如果是 3D 影像資料,多半是儲存在 4D 張量中,通常使用 2D 卷積層(Conv2D Layer) Keras 中的基礎 Layer 類別 Layer 類別是 Keras 的核心,每個 Keras 元件都是一個 Layer 物件並與 Layer 有密切互動。Layer 是將一些狀態(權重)和運算(正向傳播)包在一起的物件。 雖然權重可以在建構子 __init__() 中建立,但我們通常會使用 build() 來建立,然後用 call() 來執行正向傳播。 from tensorflow import tf class SimpleDemo(keras.layers.Layer): def __init__(self, units, activation=None): super().__init__() self.units = units self.activation = activation def build(self, input_shape): input_dim = input_shape[-1] self.W = self.add_weight(shape=(input_dim, self.units),initializer="random_normal") self.b = self.add_weight(shape=(self.units,),initializer="zeros") def call(self, inputs): y = tf.matmul(inputs, self.W) + self.b if self.activation is not None: y = self.activation(y) return y 我們可以像使用函式一樣來實例化 Layer 物件,其輸入為一個張量 sample_layer = SimpleDemo(units=32, activation=tf.nn.relu) 建立 build() 方法的意義在於,我們希望在第一次呼叫 layer 物件時才即時創建權重張量。 keras 會幫我們做好自動推論權重的 shape,我們可以把關注給放在如何定義 build()。 model = keras.Sequential([ SimpleDense(32, activation="relu"), SimpleDense(64, activation="relu"), SimpleDense(32, activation="relu"), SimpleDense(10, activation="softmax") ]) 事實上 __call__() 做的是遠不只推論 shape,還有 eager 執行模式 和 graph 執行模式 之的路徑選擇等等。 2. Model 深度學習模型是由多個層所組成的結構,在 Keras 是以 Model 類別來建立模型物件。 ...

December 20, 2024 · 7 分鐘 · Rain Hu

[AI] 3-6. 實作線性分類器

命題 我們先嘗試製作一個 sample data,考慮某一個台獨國內的房價與坪數的分布,標記出「城市」與「鄉下」兩個標籤: 紫色代表城市的房子、黃色代表鄉下的房子 城市的房子房價較高且坪數較小、鄉下的房子房價較低且坪數較大。 隱藏的特徵為單位坪數的價格,城市會高於鄉下。 以下是產生的 data,seed 設為 42 import numpy as np def load_data(n1=1000,n2=300,seed=42): np.random.seed(seed) n=n1+n2 # 城市房屋 city = np.random.multivariate_normal( mean=[25.9, 1503.7], # [坪數, 總價(萬)] cov=[[33.64, 400], # 坪數標準差 5.8 [400, 64112.24]], # 總價標準差 253.2 size=n ) # 鄉村房屋 rural = np.random.multivariate_normal( mean=[31.8, 834.3], # [坪數, 總價(萬)] cov=[[62.41, 200], # 坪數標準差 7.9 [200, 9623.61]], # 總價標準差 98.1 size=n ) # 合併資料 data = np.vstack((city, rural)).astype(np.float32) labels = np.vstack((np.zeros((n,1), dtype="float32"), np.ones((n,1), dtype="float32"))) # 打散順序 shuffle_idx = np.random.permutation(len(data)) data = data[shuffle_idx] labels = labels[shuffle_idx] # 分割訓練集和測試集 train_data = data[:2*n1] test_data = data[2*n1:] train_labels = labels[:2*n1] test_labels = labels[2*n1:] return (train_data, train_labels), (test_data, test_labels) (train_data, train_labels), (test_data, test_labels) = load_data() 通用函式 因為 price 與 size 之間的值相差較大,所以我定義了正規化的函式、繪圖的函式、training 函式。 import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import StandardScaler import tensorflow as tf from tensorflow.keras import layers, models, callbacks import pandas as pd # 共用參數 LEARNING_RATE = 0.01 BATCH_SIZE = 32 EPOCHS = 100 EARLY_STOPPING_PATIENCE = 10 def normalize_data(train_data, test_data): """標準化資料""" scaler = StandardScaler() train_normalized = scaler.fit_transform(train_data) test_normalized = scaler.transform(test_data) return train_normalized, test_normalized, scaler def plot_decision_boundary(model, X, y, title, scaler=None, is_extended=False): """繪製決策邊界 Parameters: ----------- model : 訓練好的模型 X : array-like, shape (n_samples, 2) or (n_samples, 3) 輸入特徵 y : array-like 目標變數 title : str 圖表標題 scaler : StandardScaler, optional 用於還原正規化的scaler is_extended : bool 是否為擴展特徵模型 """ if is_extended: # 對於擴展特徵模型,只使用前兩個特徵繪圖 X_plot = X[:, :2] else: X_plot = X # 設定決策邊界的範圍 x_min, x_max = X_plot[:, 0].min() - 0.5, X_plot[:, 0].max() + 0.5 y_min, y_max = X_plot[:, 1].min() - 0.5, X_plot[:, 1].max() + 0.5 # 創建網格點 xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02)) # 預測網格點的類別 grid_points = np.c_[xx.ravel(), yy.ravel()] if is_extended: # 為擴展特徵模型添加 price/size ratio ratio = grid_points[:, 1:2] / grid_points[:, 0:1] grid_points = np.hstack((grid_points, ratio)) Z = model.predict(grid_points) Z = Z.reshape(xx.shape) # 如果提供了scaler,將數據轉換回原始尺度 if scaler is not None: # 轉換網格點 grid_points_original = scaler.inverse_transform(grid_points[:, :2]) xx_original = grid_points_original[:, 0].reshape(xx.shape) yy_original = grid_points_original[:, 1].reshape(yy.shape) # 轉換特徵點 X_original = scaler.inverse_transform(X_plot) x_plot = X_original[:, 0] y_plot = X_original[:, 1] xlabel = 'Size' ylabel = 'Price' else: x_plot = X_plot[:, 0] y_plot = X_plot[:, 1] xx_original = xx yy_original = yy xlabel = 'Normalized Size' ylabel = 'Normalized Price' # 繪製圖形 plt.figure(figsize=(10, 8)) # 繪製預測機率的漸層 plt.contourf(xx_original, yy_original, Z, alpha=0.4, levels=np.linspace(0, 1, 11)) # 添加決策邊界(機率=0.5的等高線) plt.contour(xx_original, yy_original, Z, levels=[0.5], colors='red', linestyles='-', linewidths=2) # 繪製資料點 plt.scatter(x_plot, y_plot, c=y.ravel(), alpha=0.8) plt.title(title) plt.xlabel(xlabel) plt.ylabel(ylabel) # 添加顏色條 plt.colorbar(label='Prediction Probability') plt.show() def train_and_evaluate(model, train_data, train_labels, test_data, test_labels, epochs=EPOCHS, batch_size=BATCH_SIZE, use_early_stopping=False): """訓練模型並評估""" callbacks_list = [] if use_early_stopping: early_stopping = callbacks.EarlyStopping( monitor='val_loss', patience=EARLY_STOPPING_PATIENCE, restore_best_weights=True ) callbacks_list.append(early_stopping) history = model.fit( train_data, train_labels, epochs=epochs, batch_size=batch_size, validation_split=0.2, callbacks=callbacks_list, verbose=0 ) test_loss, test_accuracy = model.evaluate(test_data, test_labels, verbose=0) return history, test_loss, test_accuracy 定義模型 本篇設定了不同的 model, optimizer, loss,不代表哪一種 pattern 的優劣,純粹是示範 library 使用。 由於我想看不同的 optimizer/activation/loss function的差異,所以我共用了部分參數 LEARNING_RATE = 0.01 BATCH_SIZE = 32 EPOCHS = 100 EARLY_STOPPING_PATIENCE = 10 我列了幾個不同的策略,來看看結果的差異 SGD + 線性模型 (wx+b) + MSE SGD + Sigmoid 模型 + MSE SGD + ReLU 模型 + MSE SGD + Sigmoid 模型 + BCE Adam + Sigmoid 模型 + BCE Adam + Sigmoid 模型 + BCE (加入新特徵 price/size) Adam + 雜複模型 + BCD Adam + 複雜模型 + BCD (加入新特徵 price/size) 1. SGD + 線性模型 (wx+b) + MSE # 1. 線性模型 (wx+b) def create_linear_model(): model = models.Sequential([ layers.Dense(1, input_shape=(2,), activation='linear') ]) model.compile(optimizer=tf.keras.optimizers.SGD(learning_rate=LEARNING_RATE), loss='mse', metrics=['accuracy']) return model ...

December 19, 2024 · 5 分鐘 · Rain Hu

[AI] 3-5. 邏輯斯迴歸(logistic regression)

貝式定理 假設有一個抽獎箱內有紅球與藍球,球上有標示 A 與 B 類別。 $$ \begin{array}{|c|c|} \hline A&B\\\hline \blue{\text{●}}\blue{\text{●}}\blue{\text{●}}\red{\text{●}}&\blue{\text{●}}\blue{\text{●}}\red{\text{●}}\red{\text{●}}\red{\text{●}}\red{\text{●}}\\\hline \end{array} $$ 我們抽到藍球,它是來自於 A 的機率為何,即求 \(P(A|\blue{\text{●}})\)? 根據貝式定理: $$ P(A|x)=\frac{P(x|A)P(A)}{P(x|A)P(A)+P(x|B)P(B)} $$ 先驗機率 \(P(A)=\frac{\text{A的球數}}{\text{總球數}}=\frac{4}{10}\) \(P(B)=\frac{\text{B的球數}}{\text{總球數}}=\frac{6}{10}\) 條件機率 \(P(\blue{\text{●}}|A)=\frac{\text{A中的}\blue{\text{●}}}{\text{A的總球數}}=\frac{3}{4}\) \(P(\blue{\text{●}}|B)=\frac{\text{B中的}\blue{\text{●}}}{\text{B的總球數}}=\frac{2}{6}\) 套入公式可得 $$ P(A|\blue{\text{●}})=\frac{P(\blue{\text{●}}|A)P(A)}{P(\blue{\text{●}}|A)P(A)+P(\blue{\text{●}}|B)P(B)}=\frac{3/4\times4/10}{3/4\times4/10+2/6\times6/10}=\frac{3}{5} $$ 假設今天猜中類別才能得獎,已經知道是藍球的情況下,來自 A 的機率是 0.6,來自 B 的機率是 0.4,所以我們理論上會選擇 A,因為機率較大。換言之,在機器學習中,我們判斷一個二元分類的問題,我們會將分類判給機率 > 0.5 的那個類別。 高斯分布 一維的高斯分分機率密度函數(probability density function, pdf)為: $$ f_{\mu,\sigma}(x)=\frac{1}{\sqrt{2\pi\sigma^2}}exp\bigg\lbrace-\frac{(x-\mu)^2}{2\sigma^2}\bigg\rbrace $$ 其中 \(\mu\) 為平均數(Mean),決定分布的中心位置。 \(\sigma\) 為標準差(Standard Deviation),決定分布的寬度。 擴展到 n 維向量的多維高斯分布機率密度函數為: $$ f_{\mu,\Sigma}(x)=\frac{1}{(2\pi)^{D/2}}\frac{1}{|\Sigma|^{1/2}}exp\bigg\lbrace-\frac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)\bigg\rbrace $$ 其中 x 是一階張量 $$ x = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_n \end{bmatrix} $$ ...

December 19, 2024 · 5 分鐘 · Rain Hu

[AI] 3-4. 線性迴歸

目標 機器學習的目標有很多種,參考李宏毅教授的機器學習課程,可以用下面一張圖來概述。 Task 代表機器學習的目標 Regression: 透過迴歸來預測值。 Classification: 處理分類問題。 Structed Learning: 生成結構化的資訊(現在稱為生成式 AI, GenAI) Scenario 代表解決問題的策略 Supervised Learning: 使用已標記的訓練數據進行訓練 Semi-supervised Learning: 使用有標記與無標記的訓練數據進行訓練 Unsupervised Learning: 不使用標記的訓練數據進行訓據,由模型自行發現模式與結構 Reinforcement Learning: 透過「獎勵」與「懲罰」來學習。 Transfer Learning: 將一個任務學習到的知識應用到相關的新任務 Method 指應用的方法 Linear Model Deep Learning SVM Decision Tree KNN 線性迴歸 暴力解 假設我們大概知道答案的區間,我們可以暴力求解,將每一個 w, b 代入求最小的 (w, b) 組合 這個方法的缺點是,計算量很大,且我們求值的方式不是連續的,精準度不夠。 import sys areas = data[:,0] prices = data[:,1] def compute_loss(y_pred, y): return (y_pred - y)**2 best_w = 0. best_b = 0. min_loss = sys.float_info.max # 猜 w=30-50, step = 0.1 # 猜 b=200-600 step = 1 for i in range(200): for j in range(400): w = 30 + i*0.1 b = 200 + j*1 loss = 0. for area, price in zip(areas, prices): y_pred = w * area + b loss += compute_loss(y_pred, price) if loss < min_loss: min_loss = loss best_w = w best_b = b w=35.1 b=599 線性代數解法 假如我們學過線性代數,我們想得到它的歸性迴歸方程式,我們的作法會是: 設迴歸方程式為 $$\text{y}=\text{wx}+\text{b}\quad\quad (1)$$ ...

December 19, 2024 · 13 分鐘 · Rain Hu

[AI] 3-3. 使用 TensorFlow 與 Keras 函式庫

建立張量與變數 張量 引入 tensorflow import tensorflow as tf 建立張量並以 0 作為初始值 x = tf.ones(shape=(2,1)) print(x) >>> tf.Tensor( [[1.] [1.]], shape=(2, 1), dtype=float32) 建立張量並以 1 作為初始值 y = tf.zeros(shape=(2,1)) print(y) >>> tf.Tensor( [[0.] [0.]], shape=(2, 1), dtype=float32) 建立張量,並以常數初始化 a = tf.constant(((1.,4.),(9.,16.))) print(a) >>> tf.Tensor( [[ 1. 4.] [ 9. 16.]], shape=(2, 2), dtype=float32) 建立由亂數組成的張量 常態分佈 # 亂數從平均值 0、標準差 1 的常態分佈中抽取出來 # 等同於 np.random.normal(size=(3,1), loc=0., scale=1.) z = tf.random.normal(shape=(3,1), mean=0., stddev=1.) print(z) >>> tf.Tensor( [[-1.1859674 ] [ 0.3267818 ] [ 0.11066005]], shape=(3, 1), dtype=float32) 均勻分布 # 亂數從 0 到 1 之間均勻分布抽取出來 # 等同於 np.random.uniform(size=(3,1), low=0., high=1.) k = tf.random.uniform(shape=(3,1), minval=0., maxval=1.) print(k) >>> tf.Tensor( [[0.97643256] [0.13791454] [0.7854562 ]], shape=(3, 1), dtype=float32) NumPy 與 TensorFlow 的差異在於,TensorFlow 的張量為常數 ,無法修改。 將 numpy 轉換成 tensorflow x = np.ones((2,2)) x[0, 0] = 0 y = tf.convert_to_tensor(x) print(y) >>> tf.Tensor( [[0. 1.] [1. 1.]], shape=(2, 2), dtype=float64) 變數 創建變數 直接用 tuple 初始化 v = tf.Variable(((3.,1.,3.),(2.,3.,2.))) print(v) >>> <tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=array( [[3., 1., 3.], [2., 3., 2.]], dtype=float32)> 用隨機值初始化 v = tf.Variable(initial_value=tf.random.normal(shape=(3,1))) print(v) >>> <tf.Variable 'Variable:0' shape=(3, 1) dtype=float32, numpy=array( [[2.1368823 ], [0.8101084 ], [0.47075817]], dtype=float32)> 變數賦值 透過 assign() 方法對變數賦值 v.assign(tf.ones(shape=(3,1))) >>> <tf.Variable 'UnreadVariable' shape=(3, 1) dtype=float32, numpy=array( [[1.], [1.], [1.]], dtype=float32)> 對變數局部賦值 v[0,0].assign(0) >>> <tf.Variable 'UnreadVariable' shape=(2, 3) dtype=float32, numpy=array( [[0., 1., 3.], [2., 3., 2.]], dtype=float32)> 變數運算 加法 v.assign_add(tf.ones((2,3))) >>> <tf.Variable 'Variable:0' shape=(2, 3) dtype=float32, numpy=array( [[1., 2., 4.], [3., 4., 3.]], dtype=float32)> 減法 v.assign_sub(2*tf.ones((2,3))) >>> <tf.Variable 'UnreadVariable' shape=(2, 3) dtype=float32, numpy=array( [[-1., 0., 2.], [ 1., 2., 1.]], dtype=float32)> 張量操作 基本數學運算 初始化 a = tf.constant(((1.,4.),(9.,16.))) >>> tf.Tensor( [[ 1. 4.] [ 9. 16.]], shape=(2, 2), dtype=float32) 平方 a = tf.square(a) print(a) >>> tf.Tensor( [[ 1. 16.] [ 81. 256.]], shape=(2, 2), dtype=float32) 平方根 a = tf.sqrt(a) print(a) >>> tf.Tensor( [[ 1. 4.] [ 9. 16.]], shape=(2, 2), dtype=float32) 加法(逐元素相加) b = tf.ones((2,2)) print(a+b) >>> tf.Tensor( [[ 2. 5.] [10. 17.]], shape=(2, 2), dtype=float32) 點積 b = tf.constant(((1.,-1.),(-1.,1.))) c = tf.matmul(a,b) print(c) >>> tf.Tensor( [[-3. 3.] [-7. 7.]], shape=(2, 2), dtype=float32) 相乘(逐元素相乘) d = a*b print(d) >>> tf.Tensor( [[ 1. -4.] [-9. 16.]], shape=(2, 2), dtype=float32) 微分 計算一階梯度 ...

December 18, 2024 · 3 分鐘 · Rain Hu

[AI] 3-2. Keras 介紹

Keras 是建立在 TensorFlow 上的 Python 深度學習 API,提供了簡易方法來定義、訓練深度學習的模型。 可以想成 TensorFlow 負責張量運算、Keras 是演算法。 Keras(高層 API): 負責深度學習模型的高階抽象 提供用戶友好的介面 處理模型定義和訓練流程 eg. Layer, Model, Optimizers, Loss functions, Metrics TensorFlow(中層): 處理底層的數學運算 管理計算圖和自動微分 優化運算效率 eg. Tensor, Variable、GradientTape Hardware(硬體層): 實際執行計算任務 提供不同的計算加速選項 優化特定類型的運算 eg. CPU, GPU, TPU

December 18, 2024 · 1 分鐘 · Rain Hu

[AI] 3-1. TensorFlow 介紹

TensorFlow 是一個開源的 Python 機器學習框架,主要由 Google 開發。 TensorFlow 可以做到以下的事: 可進行自動微分、計算梯度。 可在 CPU 上運行,也可以在 GPU 及 TPU 上運行。 可以將運算程序分散到多台機器上共同執行。 可以匯出為各種不同語言的程式,包含 C++, JavaScript 或 TensorFlow Lite,使得 TensorFlow 應用可以輕鬆部署到各種實際場景。

December 18, 2024 · 1 分鐘 · Rain Hu

[AI] 2-3. 優化器 Optimizer

在神經網路中,每個神經層都通過以下的方式進行資料轉換 output = relu(dot(W, input) + b) W 和 b 為該層的屬性張量,統稱為該層的權重(weights) 或可訓練參數(trainable parameters),分別為 內核(kernel) 屬性和 偏值(bias) 屬性。 我們的目標是要透過訓練(training) 來進行權重的微調,進而得到最小的損失值。 參數調大或調小,可能會對應到「損失值變大」或「損失值變小」兩種可能(如果兩者皆變小,稱為 saddle point,兩者皆變大,可能為 local minium)。 但如果透過兩個方向的正向傳播來檢查微調的方向,效率很低,於是科學家引入了梯度下降法。 梯度下降法(gradient descent) 張量運算的導數稱為梯度(gradient)。 純量函數的導數相當於在函數曲線上找某一點的斜率。 張量函數上求梯度,相當於在函數描繪的多維曲面上求曲率。 y_pred = dot(W, x) loss_value = loss(y_pred, y_true) 假設只考慮 W 為變數,我們可以將 loss_value 視為 W 的函數。 loss_value = loss(dot(W, x), y_true) = f(W) 假設 W 的當前值為 W0,那麼函數 f 在 W0 這點的導數就是 $$ f’(W)=\frac{d\text{(loss\_value)}}{d\text{W}}|\text{W}_0 $$ 我們將上式寫成 g = grad(loss_value, W0) 代表了在 W0 附近,loss_value = f(W) 的梯度最陡方向之張量,我們可以透過往往「斜率反方向」移動來降低 f(W)。 ...

December 16, 2024 · 4 分鐘 · Rain Hu

[AI] 2-2. 張量 Tensor

張量 Tensor 是神經網路的資料表示法。 在 Python,我們常用 NumPy 陣列來作為機器學習的基礎資料結構,說 NumPy 陣列也稱為張量。 張量的維、階、軸 階(rank): 又稱為軸(axis),代表陣列的軸數。 維(dimension): 某一階的元素個數。 1. 純量 (0D 張量) 純量是單一個數值,也稱為 0 維張量 (0D Tensor) x = 5 2. 向量 (1D 張量) 向量是包含單一軸的數列,也稱為 1 維張量 (1D Tensor) x = [1, 2, 3] 3. 矩陣 (2D 張量) 矩陣是二維的數據結構,也稱為 2 維張量 (2D Tensor) x = [[1, 2, 3], [4, 5, 6]] 4. 3D 張量與高階張量 3D 張量:在二維矩陣基礎上增加一個深度維度,常用於處理圖片數據 (例如 RGB 通道)。 高階張量 (nD 張量):當張量的維度超過 3D 時,用於更高維度的資料表示,例如影片、文字數據等。 x = [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]]] 5. 張量的屬性 張量擁有幾個關鍵屬性,用於描述其結構與內容: ...

December 15, 2024 · 4 分鐘 · Rain Hu