NC200120. “人 工 智 能”
描述
外界称为人工智能,行业内还是单独称机器学习,或者潜在特指的深度学习技术,已经逐渐改变了我们的生活,也改变了创新创业团队的idea。众所周知,在每年大家提交的PPT和项目计划书中,都或多或少的使用AI技术创造了巨大的价值和财富,尽管AI省赛的举办都无人知晓,Kaggle和天池等竞赛也几乎无人问津,但还是反映了在学校教学改革和学术鼓励政策的引导下,大家优秀的学术科技创新能力。
深度学习在计算机视觉(Computer Vision)方向里也有使用,目前CV方向各子任务的SOTA(State Of The Art)模型大多都使用了图像卷积及其衍生技术。那么什么是图像卷积呢?
篇幅所限,我们省略诸多数学定义,在这里直接给出一个简要介绍和计算公式:
我们都知道,图像由像素组成,图像可以使用矩阵表示,让每一个矩阵的元素为一个数值,这个数值表示对应坐标的像素值,对于图像的操作都可以转变为矩阵运算。
图像卷积其实是两个矩阵之间的运算,一个是图像的矩阵,一个是卷积核(kernel),我们假设矩阵是阶方阵,卷积核是阶方阵,图像卷积运算结果也是一个方阵,所谓的图像卷积,就是这个公式:
图中演示的就是
1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 1 1 0 0 1 1 0 0
1 0 1 0 1 0 1 0 1
例如图中如果当前区域图像的元素是:
1 1 1 0 1 1 0 0 1
对于图像卷积运算,实际上有三种模式:VALID、FULL、SAME,对于每个元素的计算方式都如上所述,但是计算的边界有区别,下面给出边界的状态,橙色是图片image,蓝色是卷积核,灰色是重合区域,白色部分元素的值视为。
VALID模式:当卷积核全部在image里面的时候,进行卷积运算
FULL模式:从卷积核和image刚相交开始做卷积
SAME模式:当卷积核的中心(K)与image的边角重合时,开始做卷积运算。
输入描述
输入第一行为两个整数,表示图像image阶数和卷积核阶数,他们都是方阵。
接下来行,每行个用空格隔开的整数,表示image的数据
接下来行,每行个用空格隔开的整数,表示卷积核的数据
输出描述
输出三个矩阵,依次为VALID、FULL、SAME模式的图像卷积运算结果。每个矩阵设阶数为,那么输出行,每行是空格分隔的整数,表示元素值。
示例1
输入:
5 3 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 1 1 0 0 1 1 0 1 1 0 1 0 1 0 1 0 1
输出:
4 3 4 2 4 3 2 3 5 1 1 2 1 1 0 0 0 2 2 3 1 1 0 1 1 4 3 4 1 1 0 1 2 4 3 3 0 0 1 2 3 5 1 2 0 0 2 2 1 2 0 0 1 1 1 2 0 1 2 2 3 1 1 1 4 3 4 1 1 2 4 3 3 1 2 3 5 1 0 2 2 1 2
Python3(3.9) 解法, 执行用时: 209ms, 内存消耗: 3468K, 提交时间: 2020-12-19 09:52:02
m, n = map(int, input().split(' ')) matrix1 = [list(map(int, input().split(' '))) for i in range(m)] matrix2 = [list(map(int, input().split(' '))) for i in range(n)] def matrix_mutiple(matrix, x, y): n = len(matrix2) cnt = 0 for i in range(n): for j in range(n): cnt += matrix2[i][j] * matrix[i+x][j+y] return cnt def solve1(matrix): m0 = len(matrix) arr = [[] for i in range(m0-n+1)] for i in range(m0-n+1): for j in range(m0-n+1): arr[i].append(matrix_mutiple(matrix, i, j)) return arr def buchong(a): global matrix1 matrix = matrix1[:] bu0 = [[0]*(2*a+m)]*a for i in range(m): matrix[i] = [0]*a + matrix[i] + [0]*a matrix = bu0 + matrix + bu0 return matrix def show(matrix): for i in range(len(matrix)): print(' '.join(map(str, matrix[i]))) show(solve1(matrix1)) matrix = buchong(n-1) show(solve1(matrix)) matrix = buchong(n//2) show(solve1(matrix))
C++(g++ 7.5.0) 解法, 执行用时: 9ms, 内存消耗: 624K, 提交时间: 2022-12-06 15:55:52
#include<bits/stdc++.h> using namespace std; const int maxn = 205; int gr[maxn][maxn],ans[maxn][maxn],cr[maxn][maxn]; int main(){ int n,m; cin >> n >> m; for(int i = m-1;i<m-1+n;++i){ for(int j = m-1;j<m-1+n;++j){ cin >> gr[i][j]; } } for(int i = 0;i < m;++i){ for(int j = 0;j < m;++j){ cin >> cr[i][j]; } } for(int i = 0;i < n+(m<<1)-2;++i){ for(int j = 0;j < n+(m<<1)-2;++j){ for(int k = 0;k < m;++k){ for(int l = 0;l < m;++l){ ans[i][j] += gr[i+k][j+l]*cr[k][l]; } } } } for(int i = m-1;i<= m-1+(n-m);++i){ for(int j = m-1;j <= m-1+(n-m);++j){ cout << ans[i][j] << ' '; } cout << '\n'; } for(int i = 0;i<n+m-1;++i){ for(int j = 0;j<n+m-1;++j){ cout << ans[i][j] << ' '; } cout << '\n'; } for(int i = m>>1;i<(m>>1)+n;++i){ for(int j = (m)>>1;j<((m)>>1)+n;++j){ cout << ans[i][j] << ' '; } cout << '\n'; } }
C++14(g++5.4) 解法, 执行用时: 8ms, 内存消耗: 528K, 提交时间: 2019-12-08 13:38:38
#include <iostream> #include <cstdio> #include <cstdlib> using namespace std; const int maxn=110; int n,k,a[maxn][maxn],b[maxn][maxn]; void solve(int l,int r) { for (int i=l;i<=r;i++) { for (int j=l;j<=r;j++) { int sum=0; for (int kk=i;kk<=i+k-1;kk++) for (int l=j;l<=j+k-1;l++) if (kk<=0 || l<=0 || kk-i+1<=0 || l-j+1<=0) continue; else sum+=a[kk][l]*b[kk-i+1][l-j+1]; printf("%d ",sum); } printf("\n"); } } int main() { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) scanf("%d",&a[i][j]); for (int i=1;i<=k;i++) for (int j=1;j<=k;j++) scanf("%d",&b[i][j]); solve(1,n-k+1); solve(1-k+1,n); solve(1-(k-1)/2,n-(k-1)/2); return 0; }
C++11(clang++ 3.9) 解法, 执行用时: 6ms, 内存消耗: 616K, 提交时间: 2019-12-09 16:29:09
#include<cstdio> const int maxn=1e2+35; int mp[maxn][maxn],T[10][10],n,m,ans[maxn][maxn]; void print(int l,int r) { for(int i=l;i<=r;++i) for(int j=l;j<=r;++j) printf("%d%c",ans[i][j]," \n"[j==r]); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) scanf("%d",&mp[i][j]); for(int i=1;i<=m;++i) for(int j=1;j<=m;++j) scanf("%d",&T[i][j]); for(int i=1;i<n+m;++i) for(int j=1;j<n+m;++j) { for(int x=i,tx=m;x&&tx;--x,--tx) for(int y=j,ty=m;y&&ty;--y,--ty) ans[i][j]+=T[tx][ty]*mp[x][y]; } print(m,n); print(1,m+n-1); print((m>>1)+1,n+m-(m>>1)-1); return 0; }
C 解法, 执行用时: 7ms, 内存消耗: 520K, 提交时间: 2021-12-25 16:40:03
#include<stdio.h> int main() { int a,b,i,j,k,m,c[125][125]={0},d[8][8],e[125][125]={0}; scanf("%d%d",&a,&b); for(i=b-1;i<a+b-1;i++) for(j=b-1;j<a+b-1;j++) scanf("%d",&c[i][j]); for(i=0;i<b;i++) for(j=0;j<b;j++) scanf("%d",&d[i][j]); for(i=0;i<a+b-1;i++) for(j=0;j<a+b-1;j++) {for(k=0;k<b;k++) for(m=0;m<b;m++) e[i][j]+=c[i+k][j+m]*d[k][m]; } for(i=b-1;i<a;i++) { for(j=b-1;j<a;j++) printf("%d ",e[i][j]);printf("\n");} for(i=0;i<a+b-1;i++) { for(j=0;j<a+b-1;j++) printf("%d ",e[i][j]);printf("\n");} for(i=b/2;i<a+b/2;i++) { for(j=b/2;j<a+b/2;j++) printf("%d ",e[i][j]);printf("\n");} }