列表

详情


NC200120. “人 工 智 能”

描述

外界称为人工智能,行业内还是单独称机器学习,或者潜在特指的深度学习技术,已经逐渐改变了我们的生活,也改变了创新创业团队的idea。众所周知,在每年大家提交的PPT和项目计划书中,都或多或少的使用AI技术创造了巨大的价值和财富,尽管AI省赛的举办都无人知晓,Kaggle和天池等竞赛也几乎无人问津,但还是反映了在学校教学改革和学术鼓励政策的引导下,大家优秀的学术科技创新能力。

 

深度学习在计算机视觉(Computer Vision)方向里也有使用,目前CV方向各子任务的SOTA(State Of The Art)模型大多都使用了图像卷积及其衍生技术。那么什么是图像卷积呢?

 

篇幅所限,我们省略诸多数学定义,在这里直接给出一个简要介绍和计算公式:

我们都知道,图像由像素组成,图像可以使用矩阵表示,让每一个矩阵的元素为一个数值,这个数值表示对应坐标的像素值,对于图像的操作都可以转变为矩阵运算。

图像卷积其实是两个矩阵之间的运算,一个是图像的矩阵,一个是卷积核(kernel),我们假设矩阵是阶方阵,卷积核是阶方阵,图像卷积运算结果也是一个方阵,所谓的图像卷积,就是这个公式:


或许用GIF表示更为直观:

图中演示的就是

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

假设当前区域表示的子矩阵是,卷积核矩阵是,那么这一次卷积的运算结果为:

所以这个位置的值为4,这就是图中左上角的元素。没看懂的话不妨多看几遍GIF,再拿笔演算一下!

对于图像卷积运算,实际上有三种模式:VALIDFULLSAME,对于每个元素的计算方式都如上所述,但是计算的边界有区别,下面给出边界的状态,橙色是图片image,蓝色是卷积核,灰色是重合区域,白色部分元素的值视为

VALID模式:当卷积核全部在image里面的时候,进行卷积运算


FULL模式:从卷积核和image刚相交开始做卷积


SAME模式:当卷积核的中心(K)image的边角重合时,开始做卷积运算。



现在给出图像image和卷积核,请依次输出他们进行VALIDFULLSAME模式卷积运算的结果。


输入描述

输入第一行为两个整数表示图像image阶数和卷积核阶数,他们都是方阵。

接下来行,每行个用空格隔开的整数,表示image的数据

接下来行,每行个用空格隔开的整数,表示卷积核的数据






输出描述

输出三个矩阵,依次VALIDFULLSAME模式的图像卷积运算结果。

每个矩阵设阶数为,那么输出行,每行是空格分隔的整数,表示元素值。

示例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");}
}

上一题