殘差網路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/