(四)卷積神經網路 -- 8 網路中的網路(NiN)
8. 網路中的網路(NiN)
前文所述的LeNet、AlexNet和VGG,在設計上的共同點是:
先以由卷積層構成的模組充分抽取空間特徵,再以由全連線層構成的模組來輸出分類結果。
其中,AlexNet和VGG對LeNet的改進,主要在於:
如何對卷積層模組和全連線層模組,加寬(增加通道數)和加深。
網路中的網路(NiN)提出了另一個思路:
通過串聯多個由卷積層和“全連線”層構成的小網路,來構建一個深層網路。
8.1 NiN塊
卷積層的輸入和輸出通常是四維陣列(樣本,通道,高,寬),而全連線層的輸入和輸出則通常是二維陣列(樣本,特徵)。
如果想在全連線層後再接上卷積層,需要將全連線層的輸出變換為四維。
在 (四)卷積神經網路 – 3 多輸入通道和多輸出通道 一節裡介紹的1×1卷積層,可以看作全連線層。其中,空間維度(高和寬)上的每個元素相當於樣本,通道相當於特徵。
因此,NiN使用1×1卷積層來替代全連線層,從而使空間資訊能夠自然傳遞到後面的層中去。
下圖對比了NiN同AlexNet和VGG等網路在結構上的主要區別:
NiN塊是NiN中的基礎塊,它由一個卷積層加兩個充當全連線層的1×1卷積層串聯而成。
其中,第一個卷積層的超引數可以自行設定,而第二和第三個卷積層的超引數一般是固定的。
程式碼實現如下:
import tensorflow as tf
print(tf.__version__)
import numpy as np
from tensorflow.keras import Sequential
for gpu in tf.config.experimental.list_physical_devices('GPU'):
tf.config.experimental.set_memory_growth(gpu, True)
2.3.0
def nin_block(num_channels, kernel_size, strides, padding):
blk = Sequential()
blk.add(Conv2D(num_channels, kernel_size, strides, padding, activation='relu'))
blk.add(Conv2D(num_channels, kernel_size=1, activation='relu'))
blk.add(Conv2D(num_channels, kernel_size=1, activation='relu'))
return blk
8.2 NiN模型
NiN是在AlexNet問世不久後提出的,
兩者相似點:
NiN使用卷積視窗形狀分別為11×11、5×5和3×3的卷積層,相應的輸出通道數也與AlexNet中的一致;
每個NiN塊後接一個步幅為2、視窗形狀為3×3的最大池化層。
兩者不同點:
使用NiN塊;
NiN去掉了AlexNet最後的3個全連線層,替換為輸出通道數等於標籤類別數的NiN塊,然後使用全域性平均池化層對每個通道中所有元素求平均並直接用於分類。
其中,全域性平均池化層,指視窗形狀等於輸入空間維形狀的平均池化層。
NiN的這個設計的好處是,可以顯著減小模型引數尺寸,從而緩解過擬合。
然而,該設計有時會造成獲得有效模型的訓練時間的增加。
程式碼實現如下:
net = Sequential()
net.add(nin_block(96, kernel_size=11, strides=4, padding='valid'))
net.add(MaxPool2D(pool_size=3, strides=2))
net.add(nin_block(256, kernel_size=5, strides=1, padding='same'))
net.add(MaxPool2D(pool_size=3, strides=2))
net.add(nin_block(384, kernel_size=3, strides=1, padding='same'))
net.add(MaxPool2D(pool_size=3, strides=2))
net.add(Dropout(0.5))
net.add(nin_block(10, kernel_size=3, strides=1, padding='same'))
net.add(GlobalAveragePooling2D())
net.add(Flatten())
構造一個高和寬均為224的單通道資料樣本觀察每一層的輸出形狀:
X = tf.random.uniform((1, 224, 224, 1))
for blk in net.layers:
X = blk(X)
print(blk.name, "output shape: ", X.shape)
sequential_1 output shape: (1, 54, 54, 96)
max_pooling2d output shape: (1, 26, 26, 96)
sequential_2 output shape: (1, 26, 26, 256)
max_pooling2d_1 output shape: (1, 12, 12, 256)
sequential_3 output shape: (1, 12, 12, 384)
max_pooling2d_2 output shape: (1, 5, 5, 384)
dropout output shape: (1, 5, 5, 384)
sequential_4 output shape: (1, 5, 5, 10)
global_average_pooling2d output shape: (1, 10)
flatten output shape: (1, 10)
8.3 資料獲取和模型訓練
依然使用Fashion-MNIST資料集來訓練模型。
NiN的訓練與AlexNet和VGG的類似,但這裡使用的學習率更大。
資料獲取
class DataLoader():
def __init__(self):
# fashion_mnist = tf.keras.datasets.fashion_mnist
# (self.train_images, self.train_labels), (self.test_images, self.test_labels) = fashion_mnist.load_data()
# load data from local
with open("../input/fashionmnist/train-labels-idx1-ubyte", 'rb') as f:
self.train_labels = np.frombuffer(f.read(), np.uint8, offset=8)
with open("../input/fashionmnist/train-images-idx3-ubyte", 'rb') as f:
self.train_images = np.frombuffer(f.read(), np.uint8, offset=16).reshape(len(self.train_labels), 28, 28)
with open("../input/fashionmnist/t10k-labels-idx1-ubyte", 'rb') as f:
self.test_labels = np.frombuffer(f.read(), np.uint8, offset=8)
with open("../input/fashionmnist/t10k-images-idx3-ubyte", 'rb') as f:
self.test_images = np.frombuffer(f.read(), np.uint8, offset=16).reshape(len(self.test_labels), 28, 28)
# np.expand_dims(images, axis=-1) -- convert (10000, 28, 28) into (10000, 28, 28, 1)
self.train_images = np.expand_dims(self.train_images.astype(np.float32)/255.0,axis=-1)
self.test_images = np.expand_dims(self.test_images.astype(np.float32)/255.0,axis=-1)
self.train_labels = self.train_labels.astype(np.int32)
self.test_labels = self.test_labels.astype(np.int32)
self.num_train, self.num_test = self.train_images.shape[0], self.test_images.shape[0]
def get_batch_train(self, batch_size):
"""
Examples
--------
>>> np.random.randint(0, 10, size=2)
array([5, 7])
"""
index = np.random.randint(0, np.shape(self.train_images)[0], batch_size)
resized_images = tf.image.resize_with_pad(self.train_images[index],224,224)
return resized_images.numpy(), self.train_labels[index]
def get_batch_test(self, batch_size):
index = np.random.randint(0, np.shape(self.test_images)[0], batch_size)
resized_images = tf.image.resize_with_pad(self.test_images[index],224,224)
return resized_images.numpy(), self.test_labels[index]
batch_size = 128
dataLoader = DataLoader()
x_batch, y_batch = dataLoader.get_batch_train(batch_size)
print("x_batch shape:",x_batch.shape,"y_batch shape:", y_batch.shape)
x_batch shape: (128, 224, 224, 1) y_batch shape: (128,)
模型訓練
模型訓練過程與(四)卷積神經網路 – 6 AlexNet 小節類似,且使用更大的學習率:
def train_nin():
epoch = 5
num_iter = dataLoader.num_train//batch_size
for e in range(epoch):
for n in range(num_iter):
x_batch, y_batch = dataLoader.get_batch_train(batch_size)
net.fit(x_batch, y_batch)
if n%20 == 0:
net.save_weights("5.8_nin_weights.h5")
optimizer = tf.keras.optimizers.Adam(lr=1e-7)
net.compile(optimizer=optimizer,
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
x_batch, y_batch = dataLoader.get_batch_train(batch_size)
net.fit(x_batch, y_batch)
train_nin()
讀入訓練好的引數,在測試集上評估準確率:
net.load_weights("5.8_nin_weights.h5")
x_test, y_test = dataLoader.get_batch_test(2000)
net.evaluate(x_test, y_test, verbose=2)
63/63 - 1s - loss: 6.9264 - accuracy: 0.0945
[6.926401138305664, 0.09449999779462814]
參考
相關文章
- 卷積神經網路卷積神經網路
- 【深度學習篇】--神經網路中的卷積神經網路深度學習神經網路卷積
- (四)卷積神經網路 -- 12 稠密連線網路(DenseNet)卷積神經網路SENet
- 卷積神經網路四種卷積型別卷積神經網路型別
- 卷積神經網路鼻祖LeNet網路分析卷積神經網路
- 卷積神經網路概述卷積神經網路
- 解密卷積神經網路!解密卷積神經網路
- 5.2.1 卷積神經網路卷積神經網路
- 卷積神經網路CNN卷積神經網路CNN
- 卷積神經網路-AlexNet卷積神經網路
- 卷積神經網路-1卷積神經網路
- 卷積神經網路-2卷積神經網路
- 卷積神經網路-3卷積神經網路
- 全卷積神經網路FCN卷積神經網路
- 深度剖析卷積神經網路卷積神經網路
- 第四周:卷積神經網路 part 3卷積神經網路
- 卷積神經網路中的Winograd快速卷積演算法卷積神經網路演算法
- CNN神經網路之卷積操作CNN神經網路卷積
- 卷積神經網路 part2卷積神經網路
- 14 卷積神經網路(進階)卷積神經網路
- 卷積神經網路(CNN)詳解卷積神經網路CNN
- 何為神經網路卷積層?神經網路卷積
- Tensorflow-卷積神經網路CNN卷積神經網路CNN
- 卷積神經網路學習筆記——Siamese networks(孿生神經網路)卷積神經網路筆記
- 卷積神經網路中的視覺化方法卷積神經網路視覺化
- 神經網路之卷積篇:詳解經典網路(Classic networks)神經網路卷積
- 神經網路之卷積篇:詳解單層卷積網路(One layer of a convolutional network)神經網路卷積
- 卷積神經網路:Convolutional Neural Networks(CNN)卷積神經網路CNN
- 卷積神經網路(Convolutional Neural Network,CNN)卷積神經網路CNN
- 直白介紹卷積神經網路(CNN)卷積神經網路CNN
- 卷積神經網路—基本部件(2)卷積神經網路
- 卷積神經網路-啟用函式卷積神經網路函式
- 深度學習三:卷積神經網路深度學習卷積神經網路
- 一文看懂卷積神經網路卷積神經網路
- 8-深度學習之神經網路核心原理與演算法-卷積神經網路深度學習神經網路演算法卷積
- 淺聊卷積神經網路的發展卷積神經網路
- 吳恩達《卷積神經網路》課程筆記(1)– 卷積神經網路基礎吳恩達卷積神經網路筆記
- 8、神經網路神經網路