卷积运算

卷积神经网络使用卷积操作来提取特征,卷积一般包含以下几个概念:

  1. 输入:一个mnm*n大小的矩阵,是一个二维数组,是图像的数据信息。
  2. 卷积核:一个klk*l大小的矩阵,是一个二维数组,kkll为奇数,保证卷积核有一个中心。
  3. 卷积操作:将卷积核的中心对准输入的某个元素,两个矩阵的重合区域中的对应元素相乘后求和,得到输出数组中对应元素的数据。
  4. 输出:将卷积核滑动过程的卷积结果按照顺序放入一个二维数组中,即图像卷积的输出。
  5. 滑动步长:卷积核每次滑动的距离,本题中为1。
  6. 本题中,当输出中元素小于0时要变更为0,当输出中的元素大于255时要变更为255。
输入:
第一行为M、N、K、L,后为图像矩阵和卷积矩阵。
5 6 3 3
1 1 1 1 1 1
1 2 2 2 2 1
2 3 3 1 2 2
1 2 2 3 4 5
5 6 6 6 3 4
1 10 1
1 20 1
1 8 1

输出:
31 41 42 42 41 31
52 84 84 69 74 51
65 107 109 79 106 98
91 137 139 138 145 161
118 154 157 165 118 137

代码实现

import java.util.*;

class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int M = sc.nextInt();
int N = sc.nextInt();
int K = sc.nextInt();
int L = sc.nextInt();
int[][] pic = new int[M][N];
int[][] core = new int[K][L];
int[][] ans = new int[M][N];
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
pic[i][j] = sc.nextInt();
}
}
for (int i = 0; i < K; i++) {
for (int j = 0; j < L; j++) {
core[i][j] = sc.nextInt();
}
}
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
ans[i][j] = helper(pic, core, i, j, M, N, K, L);
if(ans[i][j] < 0)ans[i][j] = 0;
if(ans[i][j] > 255)ans[i][j] = 255;
}
}
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
System.out.print(ans[i][j] + " ");
}
System.out.println();
}
}

public static int helper(int[][] pic, int[][] core, int x, int y, int M, int N, int K, int L){
int res = 0;
for(int i = - K / 2; i <= K / 2; i++){
for(int j = - L / 2; j <= L / 2; j++){
if(x + i < 0 || x + i > M - 1)continue;
if(y + j < 0 || y + j > N - 1)continue;
res += pic[x + i][y + j] * core[i + K / 2][j + L / 2];
}
}
return res;
}
}

参考

jiankychen教你学算法 - 学算法,看我就够了