python实现卷积操作
大家好,又见面了,我是你们的朋友全栈君。
文章目录
我们知道,tensorflow里面自带卷积函数,tf.nn.conv2d()就可以实现相关功能,本文主要是自己实现卷积操作,然后和tf.nn.conv2d()函数的结果对比,验证正确性。
调用tf.nn.conv2d()实现卷积
首先是调用卷积函数实现卷积操作:
这里说明一下conv2d的定义及参数含义: 参考
【定义:】
tf.nn.conv2d (input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)
【参数:】
input : 输入的要做卷积的图片,要求为一个张量,shape为 [ batch, in_height, in_weight, in_channel ],其中batch为图片的数量,in_height 为图片高度,in_weight 为图片宽度,in_channel 为图片的通道数,灰度图该值为1,彩色图为3。(也可以用其它值,但是具体含义不是很理解)
filter: 卷积核,要求也是一个张量,shape为 [ filter_height, filter_weight, in_channel, out_channels ],其中 filter_height 为卷积核高度,filter_weight 为卷积核宽度,in_channel 是图像通道数 ,和 input 的 in_channel 要保持一致,out_channel 是卷积核数量。
strides: 卷积时在图像每一维的步长,这是一个一维的向量,[ 1, strides, strides, 1],第一位和最后一位固定必须是1
padding: string类型,值为“SAME” 和 “VALID”,表示的是卷积的形式,是否考虑边界。”SAME”是考虑边界,不足的时候用0去填充周围,”VALID”则不考虑
use_cudnn_on_gpu: bool类型,是否使用cudnn加速,默认为true
import tensorflow as tf
import numpy as np
input = np.array([[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]])
input = input.reshape([1,5,5,1]) #因为conv2d的参数都是四维的,因此要reshape成四维
kernel = np.array([[1,0,1],[0,1,0],[1,0,1]])
kernel = kernel.reshape([3,3,1,1]) #kernel也要reshape
print(input.shape,kernel.shape) #(1, 5, 5, 1) (3, 3, 1, 1)
x = tf.placeholder(tf.float32,[1,5,5,1])
k = tf.placeholder(tf.float32,[3,3,1,1])
output = tf.nn.conv2d(x,k,strides=[1,1,1,1],padding='VALID')
with tf.Session() as sess:
y = sess.run(output,feed_dict={
x:input,k:kernel})
print(y.shape) #(1,3,3,1)
print(y) #因为y有四维,输出太长了,我就只写一下中间两维的结果(3*3部分):[[4,3,4],[2,4,3],[2,3,4]]
自己实现卷积函数
下面我们自己实现一个卷积操作,就不care batch和channel那两维了,直接拿中间的二维为例。下面是 实现的代码(我这个太偷懒了,步长、padding这些都没有考虑进去):
import numpy as np
input = np.array([[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]])
kernel = np.array([[1,0,1],[0,1,0],[1,0,1]])
print(input.shape,kernel.shape)
def my_conv(input,kernel):
output_size = (len(input)-len(kernel)+1)
res = np.zeros([output_size,output_size],np.float32)
for i in range(len(res)):
for j in range(len(res)):
res[i][j] = compute_conv(input,kernel,i,j)
return res
def compute_conv(input,kernel,i,j):
res = 0
for kk in range(3):
for k in range(3):
print(input[i+kk][j+k])
res +=input[i+kk][j+k]*kernel[kk][k] #这句是关键代码,实现了两个矩阵的点乘操作
return res
print(my_conv(input,kernel))
输出:
[[4. 3. 4.]
[2. 4. 3.]
[2. 3. 4.]]
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/140438.html原文链接:https://javaforall.cn
相关文章
- python中astype用法_浅谈python 中的 type(), dtype(), astype()的区别[通俗易懂]
- python怎么把字体调大_python修改字体
- Python生成图文并茂的PDF报告
- Word2vec原理及其Python实现「建议收藏」
- Python项目49-用户验证短信接口(可劲撸)
- Python编码规范
- python copy&deepcopy
- (更新时间)2021年3月26日 python基础知识(模块制作)[通俗易懂]
- Python基础17-面向对象
- python浮雕图片_python图片处理PIL
- xgboost分类算法_python分类统计
- python执行cmd命令并解析结果_python如何打包成可执行程序
- 用Python画一棵带音乐的雪夜圣诞树
- 纯 Python 搭建全文搜索引擎
- [Python] 使用print作进度条(解决end=''时print不显示的问题)
- 20·Python基础-单例模式四种实现方式
- python——正则表达式(re模块)详解
- Python进阶43-drf框架(五)
- 视频识别车牌号(Python)
- python自行实现支付宝证书签名&验签全流程[通俗易懂]