Posted on

梯度下降法介紹

梯度下降法

梯度下降法(英語:Gradient descent)是一個一階最佳化算法,通常也稱為最陡下降法,但是不該與近似積分的最陡下降法(英語:Method of steepest descent)混淆。 要使用梯度下降法找到一個函數的局部極小值,必須向函數上當前點對應梯度(或者是近似梯度)的反方向的規定步長距離點進行疊代搜索。如果相反地向梯度正方向疊代進行搜索,則會接近函數的局部極大值點;這個過程則被稱為梯度上升法。

既然在變量空間的某一點處,函數沿梯度方向具有最大的變化率,那麼在優化目標函數的時候,自然是沿著負梯度方向去減小函數值,以此達到我們的優化目標。
如何沿著負梯度方向減小函數值呢?既然梯度是偏導數的集合,如下:

同時梯度和偏導數都是向量,那麼參考向量運算法則,我們在每個變量軸上減小對應變量值即可,梯度下降法可以描述如下:

描述


甚麼是梯度消失

梯度是一種數學概念,用於描述一個函數的變化率。在機器學習中,我們會使用梯度下降法來最小化損失函數。

損失函數是用來衡量模型預測結果與實際結果之間的差異的函數。通過最小化損失函數,我們可以讓模型的預測結果越來越接近實際結果。

梯度下降法是一種基於梯度的最優化算法,它會不斷計算損失函數的梯度,並根據梯度的大小和方向來更新模型的參數。當梯度越大,就意味著模型的預測結果與實際結果的差異越大,所以需要更大的步長來進行更新。當梯度越小,就意味著模型的預測結果與實際結果的差異越小,所以可以使用較小的步長來進行更新。

隨著層數的增加,梯度有可能會越來越小。這是因為在深度神經網路中,每個層的輸入都是前一層的輸出,因此如果前一層的輸出有變化,那麼這層的輸入也會有變化。如果前一層的輸出有很大的變化,那麼這層的輸入也有可能有很大的變化,導致梯度變小。而如果前一層的輸出沒有太大變化,那麼這層的輸入也不會有太大變化,梯度就不會變小。

當梯度變得非常小時,梯度下降法就無法有效地更新模型的參數、有可能陷入局部最小值,使得模型無法有效地學習。

這就是深度神經網路中的梯度消失問題。殘差網路就是為了解決這個問題而設計的。這是因為梯度下降法是通過梯度的大小和方向來決定步長的,如果梯度變得非常小,那麼步長也會變得非常小,導致更新參數的幅度非常小。

這篇文章對梯度下降法有很詳細的解釋: https://ithelp.ithome.com.tw/articles/10273302
更多關於CNN殘差學習介紹: https://zhuanlan.zhihu.com/p/31852747

Posted on

物體偵測技術介紹

取得圖片中可能的目標的位置資訊

要讓模型吐出圖片中目標的座標位置資訊,常用的方法是使用目標檢測 (object detection) 的模型,這些模型通常可以同時預測目標的類別 (class) 和座標位置 (bounding box)。

常用的目標檢測模型有 YOLO (You Only Look Once)、SSD (Single Shot MultiBox Detector) 以及 Faster R-CNN。在 TensorFlow 中,可以使用 TensorFlow Object Detection API 來訓練和使用這些模型。

訓練模型時需要給予圖片和相對應的座標位置(Annotation), 訓練好之後, 就可以得到模型預測目標的座標位置.

如果你要找的目標是特定類型, 也可以使用像 RetinaNet, FPN 等特定目標檢測模型, 它們通常都能很好的偵測目標並輸出相對應的座標位置資訊。

常見的模型介紹

常見的物體偵測模型,包括:

  • Single Shot MultiBox Detector (SSD):這是一個快速的目標檢測模型,可以在計算資源有限的環境中運行。
  • You Only Look Once (YOLO):這也是一個快速的目標檢測模型,可以在實時應用中使用。
  • Faster R-CNN:這是一個經典的目標檢測模型,在准確性和效率之間取得了很好的平衡。
  • RetinaNet:這是一個新的目標檢測模型,在准確性和效率上都有很好的表現。

這些模型都是廣泛使用的,可以根據您的需求和硬體資源選擇適當的模型。

區域建議網絡(Region Proposal Network, RPN) 是一種卷積神經網絡,它的主要功能是在輸入圖像中產生候選的目標區域。這些候選區域之後可以被傳入一個分類器來預測目標的類別和座標位置。

區域建議網絡通常由兩個部分組成: 一個卷積層,負責對輸入圖像進行特徵提取;一個全卷積層,負責對每個位置產生候選區域。

Faster R-CNN介紹

Faster R-CNN 是一種目標檢測模型,其基礎概念為使用卷積神經網絡(CNN)的特徵提取器 (feature extractor) 和基於區域的建議網絡 (region-based proposal network) 來預測目標的類別和座標位置。

Faster R-CNN 的架構由三個部分組成:

  • 一個區域建議網絡 (RPN) : 這部分主要負責對圖像產生區域建議,並且預測每個建議區域中是否包含目標。
  • 一個卷積神經網絡特徵提取器 (CNN feature extractor) :這部分主要負責對輸入圖像進行預處理,提取出高維度的特徵。
  • 一個分類器 (classifier) : 這部分主要負責對建議區域進行分類,並預測每個區域中目標的類別和座標位置。

為了能夠得到目標的座標位置資訊,Faster R-CNN 首先使用 RPN 來產生區域建議,並且預測每個建議區域中是否包含目標。接著,將這些建議區域輸入分類器,並預測每個區域中目標的類別和座標位置。

RPN原理

RPN 通常使用一種稱為 anchor 的技巧,設置預先定義好的候選區域 (如長方形),在輸入圖像中做卷積運算,預測每個 anchor 是否包含目標,並且預測每個目標的座標位置。

在 RPN 中使用 anchor 的方法是:

  • 對於輸入圖像中的每個位置,預先放置一些 anchor
  • 對於每個 anchor,預測它是否包含目標,並且預測目標的座標位置。

Anchor 技巧的目的在於可以減少目標檢測的計算量,因為只需要在少數候選區域中進行目標檢測,而不是在整張圖像中進行目標檢測。 並且因為anchor的設定, 更能更好的適用不同的目標。

下圖為一個檢測流程的範例:

簡單範例

以下是使用 TensorFlow Object Detection API 訓練和使用 Faster R-CNN 的示例代碼:

# 安裝 TensorFlow Object Detection API
pip install tensorflow-object-detection-api
# 引入需要的庫
import tensorflow as tf
from object_detection import model_hparams
from object_detection import model_lib

# 設置訓練參數
hparams = model_hparams.create_hparams()
hparams.num_classes = NUM_CLASSES  # 設置類別數量
hparams.batch_size = BATCH_SIZE  # 設置批量大小

# 設置訓練路徑
train_dir = 'path/to/train'

# 建立模型
model_fn = model_lib.create_faster_rcnn_model_fn(hparams)

# 創建訓練配置
session_config = tf.ConfigProto(allow_soft_placement=True)

# 啟動訓練
tf.estimator.train_and_evaluate(
model_fn,
train_input_fn,
eval_input_fn,
train_dir,
session_config=session_config
)
Posted on

Dense全連接層介紹

Tensorflow的全連接層

對Tensorflow而言,全連接層的類別為: tf.keras.layers.Dense
相關介紹: https://www.tensorflow.org/api_docs/python/tf/keras/layers/Dense

甚麼是全連接層

在 Dense 層中,每個輸入都會對每個輸出進行綜合計算,得到一個輸出值。這個綜合計算包括了對輸入和前一層輸出的矩陣乘法,以及對輸入和輸出的加權和。計算過程中,對輸入的乘法是通過對每個輸入的加權,得到的权重矩陣就是Dense層的權重矩陣。這些权重矩陣就是Dense層所學習的模型參數。

這層的經典用途就是進行分類,把特徵轉成概率,進而做出預測, 可以實現多種不同的操作, 如全連接,激活函數等,是基礎網路結構的基礎。

Dense層中通常還會有一個偏差項, 每個輸出都有一個偏差項, 該項是Dense層的一部分參數, 也會在學習過程中更新。

最后 Dense層 還會有一個激活函數, 用於對綜合計算的結果進行非線性轉換, 增加網絡的非線性表達能力。

全連接層的優點

在多數的深度學習模型中,輸出層常常使用 Dense 層,這是因為 Dense 層具有下列優點:

1. Dense層可以實現任意的非線性轉換,而輸出層需要進行非線性轉換,因為在大多數情況下,輸出的預測結果需要進行非線性轉換。

2. Dense層具有較高的計算效率,對於輸出層來說,需要進行大量的運算,而 Dense 層可以高效地完成這些運算。

3. Dense層 可以通過學習來自動調整權重和偏差,而且可以將輸入特徵在輸出層進行組合, 獲得高維度且有用的輸出.

因此, Dense層 是輸出層的選擇之一,並且被廣泛使用。

簡單的圖片介紹

下圖第二和第三層,與全部前一層相連接,便為Dense層

我們可以單純使用Dense來建構一個MNIST的分類器,其格式如下:

import tensorflow as tf
# Import TensorFlow Datasets
import tensorflow_datasets as tfds
tfds.disable_progress_bar()

# Helper libraries
import math
import numpy as np
import matplotlib.pyplot as plt
import logging
logger = tf.get_logger()
logger.setLevel(logging.ERROR)
dataset, metadata = tfds.load('fashion_mnist', as_supervised=True, with_info=True)
train_dataset, test_dataset = dataset['train'], dataset['test']
class_names = metadata.features['label'].names
print("Class names: {}".format(class_names))
num_train_examples = metadata.splits['train'].num_examples
num_test_examples = metadata.splits['test'].num_examples
print("Number of training examples: {}".format(num_train_examples))
print("Number of test examples:     {}".format(num_test_examples))
def normalize(images, labels):
  images = tf.cast(images, tf.float32)
  images /= 255
  return images, labels

# The map function applies the normalize function to each element in the train
# and test datasets
train_dataset =  train_dataset.map(normalize)
test_dataset  =  test_dataset.map(normalize)

# The first time you use the dataset, the images will be loaded from disk
# Caching will keep them in memory, making training faster
train_dataset =  train_dataset.cache()
test_dataset  =  test_dataset.cache()
# Take a single image, and remove the color dimension by reshaping
for image, label in test_dataset.take(1):
  break
image = image.numpy().reshape((28,28))

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28, 1)),
    tf.keras.layers.Dense(128, activation=tf.nn.relu),
    tf.keras.layers.Dense(10, activation=tf.nn.softmax)
])
model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(),
              metrics=['accuracy'])
BATCH_SIZE = 32
train_dataset = train_dataset.cache().repeat().shuffle(num_train_examples).batch(BATCH_SIZE)
test_dataset = test_dataset.cache().batch(BATCH_SIZE)
model.fit(train_dataset, epochs=5, steps_per_epoch=math.ceil(num_train_examples/BATCH_SIZE))

test_loss, test_accuracy = model.evaluate(test_dataset, steps=math.ceil(num_test_examples/32))
print('Accuracy on test dataset:', test_accuracy)

for test_images, test_labels in test_dataset.take(1):
  test_images = test_images.numpy()
  test_labels = test_labels.numpy()
  predictions = model.predict(test_images)
np.argmax(predictions[0])

實踐概念

Dense層是使用線性代數裡的矩陣運算概念實現的。

具體地說,Dense層的計算過程包括了對輸入和前一層輸出的矩陣乘法,以及對輸入和輸出的加權和。 這個綜合計算可以用下面這個矩陣的形式來表示

y = W*x + b

其中 y 是 Dense 層的輸出,x 是輸入,W 是 Dense 層的權重矩陣, b 是偏差項。

這個運算滿足矩陣乘法的性質, W 可以看成是一個 m x n 的矩陣, x 是一個 n x 1 的向量, 這樣 y 就是一個 m x 1 的向量,就是輸出。這種運算方式可以幫助網絡在運算過程中組合特徵,輸出高維度且有用的特徵。

Posted on

如何使用回撥(callbacks)來觸發訓練週期的結束

在 TensorFlow 和 Keras 中,可以使用回撥 (callbacks) 來在訓練週期結束時觸發某些操作。回撥是一個類似於函數的物件,可以在訓練過程中的特定時間點被調用。

其中一種回撥叫做 ModelCheckpoint,它能在訓練的某個時間點保存模型的權重。另一種叫做 EarlyStopping,它能在訓練達到一定的準確率後停止訓練。

要在訓練週期結束時觸發回撥,需要在調用 fit() 或者 fit_generator() 時將它們添加為參數。

範例:

from keras.callbacks import ModelCheckpoint, EarlyStopping

callbacks = [ModelCheckpoint('model.h5'), EarlyStopping(monitor='val_loss', patience=2)]

model.fit(X_train, y_train, epochs=10, callbacks=callbacks, validation_data=(X_val, y_val))

這樣的程式會在訓練結束後儲存權重並在驗證損失停止改善2次後停止訓練

通常,回撥可以根據您的需求進行自定義,並結合多種回撥以實現複雜的訓練流程。

Posted on

如何從預先訓練的模型中提取特徵

預先訓練的模型中提取特徵的一種常見方法是使用模型的中間層。例如,如果使用卷積神經網絡 (CNN) 來預訓練圖像識別模型,則可以使用 CNN 的某些中間層(如卷積層或池化層)來提取圖像的特徵。

另外,您可以將整個預先訓練的模型看作是一個特徵提取器。 一種方法是將輸入數據丟入預先訓練的模型中,然後使用模型的最後一層輸出 (通常是分類層) 作為特徵。

最後,您還可以使用深度學習框架中內置的函數(如 Keras 中的 model.predict())來提取特徵。

在使用預先訓練的模型提取特徵時,重要的是要注意模型是否符合您的任務,並且選擇適當的層和方法。

Posted on

二元分類器 (binary classification) 介紹

甚麼是二元分類器

二元分類 (binary classification) 是一種機器學習中常見的任務,其目的是從兩個不同類別中將每個數據樣本歸類為其中之一。這種分類方式只有兩個類別,因此其結果是二元的。例如,對於圖像分類問題,二元分類可能用於識別猫和狗的圖像,或者用於識別垃圾郵件和非垃圾郵件的電子郵件。

在二元分類中,我們通常使用一些算法來建立一個模型,如 logistic regression, decision tree, SVM, Random forest, neural network等 來預測每個輸入數據樣本屬於哪個類別。 當我們對新數據進行預測時,該模型將輸出預測類別 (0 或 1)。

在訓練階段,通常需要提供已經標註好類別的數據來訓練模型。並在測試階段使用該模型來預測新的數據的類別,並使用常見的度量指標來評估模型的效果如精確度, AUC-ROC, F1 score等

如果您需要分類多於兩個類別的數據,則需要使用多元分類 (multiclass classification)。

和多元分類器的不同

在 TensorFlow 中,實現二元分類和多元分類器主要有兩個不同之處:

  • 損失函數: 二元分類器通常使用二元交叉熵 (binary cross-entropy) 作為損失函數。而多元分類器則常使用交叉熵 (cross-entropy) 作為損失函數。
  • 輸出層的激活函數: 二元分類器的輸出層通常使用 sigmoid 激活函數。而多元分類器的輸出層則通常使用 softmax 激活函數。

除了上述兩點的不同之外,實現二元分類器和多元分類器在 TensorFlow 中沒有太大差別。
如果使用Keras, 可以直接使用其封裝好的model,
例如:
keras.models.Sequential() 中的binary_crossentropy適用於二元分類問題

model.compile(loss='binary_crossentropy',optimizer='adam',metrics=['accuracy']) 

而 categorical_crossentropy則適用於多元分類問題.

model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy']) 

但是要注意在訓練和測試階段,多元分類需要對每個類別進行單熱編碼 ( one-hot encoding)。在 TensorFlow 中,可以使用 tf.keras.utils.to_categorical() 函數將標籤轉換為 one-hot 編碼。

優缺點比較

使用二元分類器和使用多元分類器並將其限制為兩個類別的方式之間有以下優缺點:

優點:

  • 使用二元分類器可以較為簡單地對兩個類別進行分類,而無需考慮額外的類別。
  • 如果模型使用二元交叉熵作為損失函數,則可以較容易地解釋分類結果,因為輸出層輸出的值是概率值,可以用來表示一個類別的可能性。

缺點:

  • 如果類別數量超過兩個,則無法使用二元分類器。
  • 將多元分類器限制為兩個類別可能會使模型的複雜度增加,因為必須考慮額外的類別,即使這些類別不需要分類。
  • 如果將多元分類器限制為兩個類別,則無法充分利用模型的能力,可能無法在更大范圍內解決問題。
  • 在某些情況下,使用二元分類器可能不能提供足夠的信息來解釋分類結果,因為只提供了兩個類別之間的信息。

總之, 如果您有兩個類別並且需要將數據標記為其中之一,則使用二元分類器可能是最佳選擇。如果類別數量超過兩個或者需要更多的信息來解釋分類結果,則使用多元分類器可能是更佳選擇。

Posted on

Tensorflow裡ResNet(殘差網路)的介紹

殘差網路ResNet

殘差網路(Residual Network,簡稱 ResNet)是一種深度卷積神經網路,它被設計用來解決深度神經網路中的梯度消失問題。

在深度神經網路中,隨著層數的增加,梯度有可能會越來越小,導致模型無法有效地學習。殘差網路通過在每一層中引入一個「殘差块」來解決這個問題。殘差块包含兩個卷積層和一個殘差路徑,殘差路徑將輸入數據直接加到輸出數據上。這樣,當殘差块的輸出數據與輸入數據相加時,梯度就不會被消失。

這邊是別人的文章介紹: https://ithelp.ithome.com.tw/articles/10264843?sc=hot

與Conv2D關鍵的不同

Conv2D就是一個提取圖片裡的特徵的方式,他是可以讓圖片也可以丟進Dense去找到共通特徵的一個關鍵,但是,Conv2D一定會需要與其他像是池化層、全連接層、輸出層等一起使用。
而殘差網路就是某個對ML非常熟的神人,所使用像是卷積層、池化層、連接層等,可有效降低梯度消失的問題的一個【已經建立好的模型】
例如: 以下為一個原始的TF模型的建立方式

model = tf.keras.Sequential([
    tf.keras.layers.Rescaling(1./255),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32, 3, activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(num_classes)
])

ResNet使用範例

而使用ResNet非常的簡單,就使用別人已建立好的ResNet就可以了,以下範例中的 ResNet 使用了 20 個 ResidualBlock,每個 ResidualBlock 中使用了 64 個濾波器,卷積核大小為 3×3,步長為 2。

import tensorflow as tf
from tensorflow.keras import layers

class ResidualBlock(layers.Layer):
    def __init__(self, filters, kernel_size, strides, use_projection=False):
        super(ResidualBlock, self).__init__()
        self.use_projection = use_projection
        self.conv1 = layers.Conv2D(filters, kernel_size, strides=strides, padding='same')
        self.bn1 = layers.BatchNormalization()
        self.relu = layers.ReLU()
        self.conv2 = layers.Conv2D(filters, kernel_size, strides=1, padding='same')
        self.bn2 = layers.BatchNormalization()
        if use_projection:
            self.projection = layers.Conv2D(filters, 1, strides=strides, padding='same')

    def call(self, inputs, training=False):
        x = self.conv1(inputs)
        x = self.bn1(x, training=training)
        x = self.relu(x)
        x = self.conv2(x)
        x = self.bn2(x, training=training)
        if self.use_projection:
            shortcut = self.projection(inputs)
        else:
            shortcut = inputs
        x += shortcut
        x = self.relu(x)
        return x

class ResNet(layers.Layer):
    def __init__(self, blocks, filters, kernel_size, strides):
        super(ResNet, self).__init__()
        self.conv = layers.Conv2D(filters, kernel_size, strides=strides, padding='same')
        self.bn = layers.BatchNormalization()
        self.relu = layers.ReLU()
        self.blocks = blocks
        self.res_blocks = [ResidualBlock(filters, kernel_size, strides) for _ in range(blocks)]

    def call(self, inputs, training=False):
        x = self.conv(inputs)
        x = self.bn(x, training=training)
        x = self.relu(x)
        for res_block in self.res_blocks:
            x = res_block(x, training=training)
        return x

inputs = tf.keras.Input(shape=(224, 224, 3))
resnet = ResNet(20, 64, 3, 2)(inputs)
outputs = layers.Dense(10, activation='softmax')(resnet)
model = tf.keras.Model(inputs, outputs)

官方介紹文件

V1版本: https://www.tensorflow.org/api_docs/python/tf/keras/applications/resnet
V2版本: https://www.tensorflow.org/api_docs/python/tf/keras/applications/resnet_v2

好多種ResNet,有甚麼差?

ResNet50, ResNet101, ResNet152 是 TensorFlow 中原始版本的 ResNet 模型,而 ResNet50V2, ResNet101V2, ResNet152V2 是 V2 版本的 ResNet 模型。以下是這些模型之間的主要區別:

  • 深度: ResNet50 的深度為 50 層,ResNet101 的深度為 101 層,ResNet152 的深度為 152 層,V2 版本的深度分別為 50 層,101 層和 152 層。
  • 架構: V2 版本的 ResNet 模型在原始版本的基礎上增加了許多改進,包括使用非常深的層 (bottleneck layer) 來減少參數數量,並在輸入層和輸出層之間使用高密度連接 (dense connection)。
  • 參數數量: V2版本的 ResNet 模型通常具有較少的參數數量,因為它們使用了更高效的架構。
  • 效能: V2版本的 ResNet 模型通常具有更好的效能,因為它們使用了更高效的架構和更少的參數。

總之, 如果要在效能和參數數量之間取得平衡, 使用 V2 版本的 ResNet 模型是個好選擇。
如果效能是優先考量,則可以使用原始版本的 ResNet 模型。

設定ResNet模型超參數

在建立殘差網路 ResNet 的模型時,有一些重要的超參數可以考慮調整,例如:

  • 卷積層數量 (num_blocks):通常來說,越多的卷積層能夠讓模型的表現更好,但也會使模型變得越大且訓練時間越長。因此可以根據實際的情況決定卷積層的數量。
  • 初始濾波器數量 (initial_filters):通常來說,使用較大的濾波器能夠讓模型的表現更好,但也會使模型變得越大且訓練時間越長。因此可以根據實際的情況決定初始濾波器的數量。
  • 激活函數 (activation):激活函數可以對輸入的數據施加非線性轉換,以便讓模型能夠學習更複雜的模式。常見的激活函數包括 ReLU、Sigmoid 和 tanh 等。
  • 優化器 (optimizer):優化器是用來更新模型參數的算法,通常會使用常見的優化器如 SGD、Adam 和 RMSprop 等。
  • 學習率 (learning rate):學習率決定了優化器更新參數的速度。如果學習率過大,則優化器可能會震蕩,無法有效地學習;如果學習率過小,則優化器可能會過慢,學習效率較低。因此可以根據實際的情況選擇合適的學習率。
  • 批次大小 (batch size):批次大小決定了每次更新參數時使用的數據數量。如果批次大小過大,則更新參數的速度會較快,但也有可能導致模型的表現變差;如果批次大小過小,則更新參數的速度會較慢,但也有可能會使模型的表現更好。因此可以根據實際的情況選擇合適的批次大小。
  • 訓練輪數 (epochs):訓練輪數決定了模型在訓練集上訓練的次數。如果訓練輪數過多,則模型有可能會對訓練集過擬合,導致在驗證集上的表現變差;如果訓練輪數過少,則模型可能無法充分學習到訓練集中的模式,導致整體的表現較差。因此可以根據實際的情況選擇合適的訓練輪數。
  • 正規化 (regularization):正規化是指在訓練過程中加入額外的限制,以防止模型過度擬合。常見的正規化方法包括 L1 正規化和 L2 正規化。
  • 丟棄率 (dropout rate):丟棄率是指在訓練過程中隨機丟棄一定比例的神經元,以防止模型過度擬合。
  • 濾波器數量 (filters):濾波器數量決定了每個卷積層使用的濾波器數量。通常來說,使用較多的濾波器能夠讓模型的表現更好,但也會使模型變得越大且訓練時間越長。因此可以根據實際的情況決定濾波器的數量。
  • 卷積層的濾波器大小 (filter size):卷積層的濾波器大小決定了每個卷積層使用的濾波器的大小。通常來說,使用較大的濾波器能夠讓模型的表現更好,但也會使模型變得越大且訓練時間越長。因此可以根據實際的情況決定濾波器的大小。

使用TunableResNet

GitHub位置: https://github.com/keras-team/keras-tuner
官方網站: https://keras.io/keras_tuner/

Posted on

PyCharm – 好用的python開發環境

官方網站

https://www.jetbrains.com/pycharm/

為什麼選擇PYCHARM

  • 所有 PYTHON 工具集中在一處
  • 提高生產力: 在 PyCharm 處理例程時節省時間。專注於更大的事情並採用以鍵盤為中心的方法來充分利用 PyCharm 的許多生產力功能。
  • 獲得智能幫助: PyCharm 了解您的代碼的一切。依靠它實現智能代碼完成、實時錯誤檢查和快速修復、輕鬆的項目導航等等。
  • 提升代碼質量: 編寫整潔且可維護的代碼,同時 IDE 通過 PEP8 檢查、測試協助、智能重構和大量檢查幫助您控制質量。
  • 只需您所需要的: PyCharm 由程序員設計,為程序員而設計,旨在提供高效 Python 開發所需的所有工具。

免費的社區版本和付費的專業版本

功能比較圖

專業版的優惠方案

若為在學學生,可以獲得免費帳號
https://www.jetbrains.com/community/education/#students
若以畢業,但是電子信箱仍然可以用,則也可以用學校的信箱申請學生版本使用。

另外,對於一些電腦學院或者是初期創業者也都有提供優惠,個人使用者也有優惠(更多資訊: https://www.jetbrains.com/pycharm/buy/#discounts)

下載連結

請點此下載: https://www.jetbrains.com/pycharm/download/#section=windows

點進去右邊為免費版本,左邊為付費版本,但是可以免費使用30天

Posted on

TensorFlow 開發者認證計劃介紹

TensorFlow認證計劃課程

以下為介紹網頁
https://www.tensorflow.org/certificate
在這個網頁當中,他們推薦了幾個課程

而我選擇了Udacity的課程(因為免費),而且可以有中文字幕

必備知識

為了順利完成考試,應試者應該了解以下知識:

  • 機器學習和深度學習的基本原則
  • 在TensorFlow 2.x 中構建機器學習模型
  • 使用深度神經網絡和卷積神經網絡構建圖像識別算法、對象檢測算法、文本識別算法
  • 使用不同形狀和大小的真實圖像可視化圖像的捲積過程,了解計算機如何“觀察”信息、繪製損失和準確率圖
  • 探索防止過擬合的策略,包括增強和丟棄策略
  • 在TensorFlow 中使用神經網絡解決自然語言處理問題

認證考試使用的工具

PyCharm
因此應熟悉在PyCharm中撰寫Python程式、Debug及Compiler。
此為社區版連結: https://www.jetbrains.com/pycharm/download/#section=windows
若是仍有學生的email信箱,則可以免費申請專業版: https://www.jetbrains.com/community/education/#students

認證考試的內容

雖然我們不一定要去獲得認證,但是從認證考試範圍可以了解,要學習Tensorflow有那些東西是官方認為必備的知識,以下為官方的認證說明文件:
TF_Certificate_Candidate_Handbook

TensorFlow開發技能

  • 在PyCharm中寫程式Python的知識,解決Python問題,並編譯和執行Python程式。
  • 了解如何查找有關 TensorFlow API 的信息,包括如何查找指南和 API(tensorflow.org 上的參考資料)。
  • 知道如何從TensorFlow API中除錯、調查和解決錯誤訊息。
  • 知道如何在tensorflow.org 之外搜尋必要知識來解決在tensorflow遇到的問題
  • 知道如何使用TensorFlow建立ML模型,其中模型大小對正在解決的問題來說是合理的。
  • 知道如何儲存ML模型並檢查模型
  • 了解不同版本的Tensorflow的相容性差異

使用TensorFlow 2.x構建和訓練神經網路模型

  • 使用TensorFlow 2.x。
  • 使用TensorFlow構建、編譯和訓練機器學習(ML)模型。
  • 預處理資料,使其準備好在模型中使用。
  • 使用模型來預測結果。
  • 為二元分類 (binary classification) 構建和訓練模型
  • 為多元分類器建構和訓練模型
  • 繪製經過訓練的模型的損失和準確性。
  • 了解如何防止過度擬合,包括資料增強(augmentation)和dropout
  • 使用預先訓練的模型(轉移學習)。
  • 從預先訓練的模型中提取特徵。
  • 確保模型的輸入處於正確的形狀。
  • 確保您可以將測試資料與神經網路的輸入形狀匹配。
  • 確保您可以將神經網絡的輸出數據與測試數據的指定輸入形狀相匹配。
  • 瞭解資料的批次載入
  • 使用回撥來觸發訓練週期的結束
  • 使用不同的來源的資料集
  • 使用不同格式的資料集,包括CSV和JSON
  • 使用tf.data.datasets裡的資料集

影像分類

瞭解如何使用TensorFlow 2.x使用深度神經網路和卷積神經網路構建影象識別和物件檢測模型。 您需要知道如何:

  • 使用 Conv2D 和池化層定義卷積神經網絡。
  • 構建和訓練模型來處理真實世界的圖像數據集。
  • 了解如何使用卷積來改進您的神經網絡。
  • 使用不同形狀和大小的真實世界圖像。
  • 使用圖像增強來防止過度擬合。
  • 使用 ImageDataGenerator。
  • 了解 ImageDataGenerator 如何根據目錄結構標記圖像。

自然語言處理(NLP)

你需要了解如何使用神經網絡張量流來解決自然語言處理問題。

您需要知道如何:

  • 使用 TensorFlow 構建自然語言處理系統。
  • 準備要在 TensorFlow 模型中使用的文本。
  • 構建使用二元分類識別一段文本類別的模型
  • 構建使用多類分類識別一段文本類別的模型
  • 在您的 TensorFlow 模型中使用詞嵌入。
  • 在您的模型中使用 LSTM 對文本進行分類以進行二分類或多分類。
  • 將 RNN 和 GRU 層添加到您的模型中。
  • 在處理文本的模型中使用 RNNS、LSTM、GRU 和 CNN。
  • 在現有文本上訓練 LSTM 以生成文本(例如歌曲和詩歌)

時間序列、序列和預測

您需要瞭解如何在TensorFlow中解決時間序列和預測問題。 您需要知道如何:

  • 訓練、調整和使用時間序列、序列和預測模型。
  • 訓練模型來預測單變數和多變數時間序列的值。
  • 為時間序列學習準備資料。
  • 瞭解平均絕對誤差(MAE)以及如何將其用於評估序列模型的準確性。
  • 使用RNN和CNN進行時間序列、序列和預測模型。
  • 確定何時使用尾隨視窗與居中視窗。
  • 使用TensorFlow進行預測。
  • 準備功能和標籤。
  • 識別和補償序列偏差。
  • 動態調整時間序列、序列和預測模型的學習率。
Posted on

在K8S內node js紀錄log的解決方案

千萬不要使用PM2

PM2是一個在linux裡面管理nodejs程序的好工具,它可以讓nodejs在死掉時自動控制重啟,並可於重啟次數超過時停止重啟
但是由於在K8S之中,這種管理的機制已經交由K8S去管理了,因此,若再於裡面包一層PM2,很容易出問題

可能發生的問題

  • pm2 一開始起來時會依你的參數去試著把 resource 給最大化,所以會一下子把 resource 吃滿,這會讓 k8s 覺得 是不是這個 pod 又很忙了,就馬上又起一個 pod 要來試著接手
  • pm2 會自己重啟 node process : 這會讓 k8s 不知道其實 pod 已經死了,就不會再建新的 pod 來接手

PM2其他功能的替代方案

因為PM2的部分功能與K8S重疊,不推薦使用,那關於PM2另外的文字檔log功能,則有幾種方案可解決

  • container 是吐到 stdout,k8s 的 cri 會寫到 host 上
  • 自己實作log系統

而我們公司由於管K8S的系統的運營部門不處理我們的log的儲存以及打至ELK裡的問題,所以就只能採用第二種方案,以下為我們nodeJS的解決方案log4js

使用nodeJS所推出的log管理系統

https://www.npmjs.com/package/log4js
官方的說明非常簡單好懂,下面為一個基礎使用範例,可每日分檔案,儲存三天

const log4js = require("log4js");
log4js.configure({
    appenders: {
        log: { type: "dateFile", filename: "logs/log.log", pattern: "yyyy-MM-dd", layout: { type: "pattern", pattern: "[%d] %m", }, keepFileExt: true, fileNameSep: "-", numBackups: 3 },
        error: { type: "dateFile", filename: "logs/error.log", pattern: "yyyy-MM-dd", layout: { type: "pattern", pattern: "[%d] %m", }, keepFileExt: true, fileNameSep: "-", numBackups: 3 },
    },
    categories: { default: { appenders: ["log"], level: "debug" }, error: { appenders: ["error"], level: "error" } }
});
var logger = log4js.getLogger();
var logger_error = log4js.getLogger("error");
logger.level = "debug";

exports.log = (...msg) => {
    logger.debug(...msg);
}

exports.error = (...msg) => {
    logger_error.error(...msg);
}