終于把卷積神經(jīng)網(wǎng)絡算法搞懂了?。?!
大家好,我是小寒
今天給大家分享一個強大的算法模型,卷積神經(jīng)網(wǎng)絡
卷積神經(jīng)網(wǎng)絡算法(CNN)是一種專門用于處理網(wǎng)格狀拓撲結(jié)構(gòu)數(shù)據(jù)的深度學習算法,廣泛應用于計算機視覺領域,在圖像分類、目標檢測和圖像分割等任務中表現(xiàn)出色。
CNN 的核心思想是通過模仿生物神經(jīng)系統(tǒng)的視覺皮層結(jié)構(gòu),逐層提取數(shù)據(jù)的局部特征,從而實現(xiàn)高效的特征學習。CNN 相比于傳統(tǒng)的全連接神經(jīng)網(wǎng)絡,具有較少的參數(shù)和更強的空間不變性。
圖片
卷積神經(jīng)網(wǎng)絡的基本結(jié)構(gòu)
CNN 主要由卷積層、池化層和全連接層構(gòu)成,各部分共同協(xié)作從輸入圖像中提取特征,最后實現(xiàn)分類或回歸任務。
卷積層
卷積層是 CNN 的核心組成部分,它的主要功能是通過卷積操作提取局部特征。
卷積操作是通過一個小的濾波器(或卷積核)在輸入圖像上滑動來計算的,每次滑動時,卷積核與局部區(qū)域的像素值做點積運算,并輸出一個新的值。這些新值組成了特征圖(feature map)。
圖片
卷積核
卷積核(也稱為濾波器)是一個小的權(quán)重矩陣(例如 3x3、5x5),它的參數(shù)(權(quán)重)是可學習的。
它通過在輸入數(shù)據(jù)上滑動(卷積)來生成特征圖。
步長
步長決定了卷積核在輸入數(shù)據(jù)上滑動的步伐。
較大的步長會減少輸出特征圖的尺寸,反之,較小的步長會增加輸出特征圖的尺寸。
圖片
填充(Padding)
填充是為了確保卷積操作不會丟失邊緣信息,通常會在輸入數(shù)據(jù)的邊緣添加一些零值,稱為零填充。
圖片
卷積層的作用是通過不同的卷積核提取不同的特征,比如邊緣、角點、紋理等。
卷積操作后的輸出通常會通過一個非線性激活函數(shù)處理,以引入非線性,提升模型表達復雜特征的能力。
池化層
池化層通常位于卷積層之后,它通過下采樣操作減小特征圖的尺寸,減少計算量和參數(shù)數(shù)量,避免過擬合。
常見的池化操作有最大池化和平均池化
- 最大池化(Max Pooling),對每個子區(qū)域選擇最大值。
- 平均池化(Average Pooling),對每個子區(qū)域取平均值。
圖片
全連接層
全連接層通常位于網(wǎng)絡的最后階段,其主要作用是將卷積層和池化層提取的高維特征映射到標簽空間,實現(xiàn)最終的分類任務。
全連接層中的每個神經(jīng)元與前一層的所有神經(jīng)元都有連接。
圖片
卷積神經(jīng)網(wǎng)絡的工作流程
- 輸入層
輸入層通常是一個多維矩陣(如彩色圖像為一個3維矩陣:寬度 × 高度 × 通道數(shù))。 - 卷積操作
在卷積層中,濾波器(卷積核)在輸入數(shù)據(jù)上滑動,提取局部特征。 - 激活函數(shù)
卷積操作后通過激活函數(shù)(如ReLU)引入非線性,使模型能夠?qū)W習到更復雜的特征。 - 池化層
池化層通過下采樣操作減少特征圖的尺寸,減小計算復雜度并提取更具抽象性的特征。 - 全連接層
全連接層將提取到的特征進行整合,并最終輸出預測結(jié)果。 - 輸出層
最后一層通常使用 softmax 函數(shù)輸出每個類別的概率,用于分類任務。
CNN的優(yōu)點
- 參數(shù)共享
卷積層中權(quán)重共享的設計減少了網(wǎng)絡參數(shù)數(shù)量,使得CNN在較少的計算資源下仍能保持較高的精度。 - 自動特征提取
通過逐層堆疊卷積層,CNN 可以自動從數(shù)據(jù)中提取特征,無需手工設計特征。 - 空間不變性
卷積操作對圖像的平移、旋轉(zhuǎn)、縮放具有一定的魯棒性。
案例分享
下面是一個使用卷積神經(jīng)網(wǎng)絡(CNN)進行手寫數(shù)字識別的示例代碼。
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt
# 加載 MNIST 數(shù)據(jù)集
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train = x_train.reshape((x_train.shape[0], 28, 28, 1))
x_test = x_test.reshape((x_test.shape[0], 28, 28, 1))
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)
# 構(gòu)建 CNN 模型
model = models.Sequential([
layers.Conv2D(32, (3, 3), activatinotallow='relu', input_shape=(28, 28, 1)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activatinotallow='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activatinotallow='relu'),
layers.Flatten(),
layers.Dense(64, activatinotallow='relu'),
layers.Dense(10, activatinotallow='softmax') # 10 類輸出
])
# 編譯模型
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
# 訓練模型
model.fit(x_train, y_train, epochs=5, batch_size=64, validation_data=(x_test, y_test))
# 在測試集上評估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"Test accuracy: {test_acc:.4f}")
# 隨機選擇一些測試圖像的索引
num_images = 10
random_indices = np.random.choice(x_test.shape[0], num_images, replace=False)
test_images = x_test[random_indices]
true_labels = np.argmax(y_test[random_indices], axis=1)
predicted_labels = np.argmax(model.predict(test_images), axis=1)
plt.figure(figsize=(12, 4))
for i in range(num_images):
plt.subplot(2, 5, i + 1)
plt.imshow(test_images[i].reshape(28, 28), cmap='gray')
plt.title(f"True: {true_labels[i]}\nPred: {predicted_labels[i]}")
plt.axis('off')
plt.show()
圖片