e798. 卷積神經網路

題目

2019TOI1214 新手同好會 5. 卷積神經網路 (CNN) {試題連結}

問題敘述

卷積神經網絡 (Convolutional Neural Network) 簡稱 CNN,是現在最火紅的深度學習課程必教的模型。 CNN 在影像識別方面非常厲害,許多影像辨識的模型都是以 CNN 的架構為基礎去做延伸。 CNN 分為三個部分:卷積層 (convolution layer)、池化層 (pooling layer) 和全連接層 (fully connected layer)。 卷積層用於提取影像特徵,池化層減小資料的空間大小,全連接層主要目的為實現分類。 池化層最常見的作法是最大池化法 (max pooling),它將輸入的影像劃分為若干個 2×2 的矩形子區域,對每個子區域輸出最大值。 給定一個 n×n 的二維陣列,請實作最大池化演算法並輸出池化後的結果。

image

最大池化法示意圖 圖片來源:https://embarc.org/embarc_mli/doc/build/html/MLI_kernels/pooling_max.html

輸入格式

第一行有一個正整數n(4 <= n <= 20,n為2的倍數),代表輸入影像邊長。接下去有n行,每行各有n個數字,數值範圍在正負 2^31 之間,以空白隔開,代表影像陣列中的資料值。

輸出格式

輸出經2x2 最大池化後的結果。

範例測資

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
輸入1 :
4
12 20 30 0
8 12 2 0
34 70 37 4
112 100 25 12

輸出1 :
20 30
112 37

輸入2 :
6 
10 2 0 12 1 3
21 0 13 2 2 0
0 0 0 10 0 0
19 2 0 13 61 1
0 1 32 3 0 2
9 2 0 31 11 0

輸出2 :
21 13 3
19 13 61
9 38 11

解題方向

簡化題目後,我們可以得出題目是要我們把一個大矩陣都拆成2*2的小矩陣。然後把每個小矩陣的最大值輸出成一個新的矩陣,而這個過程被稱作池化。了解題目的要求後就簡單了,我的作法是以一個小區塊先池化,輸出後再處理下一個小區塊。

如下圖所示,而實際的方法可以把輸入的影像邊常除2,再丟進迴圈裡跑。這樣迴圈每跑次就是處理一組小矩陣。 比較要注意的是後續處理比較四格大小的時候,要記得把迴圈索引值乘2。

參考程式碼

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n;
    cin>>n;

    int pool[n][n];
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            cin>>pool[i][j];
        }
    }

    int max;
    for(int i=0;i<n/2;i++){
        for(int j=0;j<n/2;j++){
            max=pool[2*i][2*j];
            max=(pool[2*i+1][2*j]>max)?pool[2*i+1][2*j]:max;
            max=(pool[2*i][2*j+1]>max)?pool[2*i][2*j+1]:max;
            max=(pool[2*i+1][2*j+1]>max)?pool[2*i+1][2*j+1]:max;
            cout<<max<<" ";
        }
        cout<<endl;
    }
    return 0;
}
Licensed under CC BY-NC-SA 4.0
Never Too Late To Start
使用 Hugo 建立
主題 StackJimmy 設計