Tensorflow卷积操作tf.nn.conv2d的理解

函数定义

tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)

功能:在给定4-D 输入和fliters的情况下,计算二维卷积。

input的shape: [batch, in_height, in_width, in_channels]
filter的shape: [filter_height, filter_width, in_channels, out_channels]

计算过程如下
(1)展平filter成如下2-D matrix,其shape: [filter_height * filter_width * in_channels, output_channels]
(2)从input tensor中提取patches构成一个virtual tensor, 其shape: [batch, out_height, out_width, filter_height * filter_width * in_channels]
(3)对于每一个patch, 右乘上(1)中的filter matrix。即[batch, out_height, out_width, filter_height * filter_width * in_channels] x [filter_height * filter_width * in_channels, output_channels],其结果的shape就是[batch, out_height, out_width, output_channels]。

【注:必须有 strides[0] = strides[3] = 1】。绝大多数情况下,水平的stride和竖直的stride一样,即strides = [1, stride, stride, 1]。

输出结果的shape计算
‘SAME’ 类型的padding,其输出的height和width计算如下:
out_height = ceil(float(in_height) / float(strides[1])) ceil:向上取整
out_width = ceil(float(in_width) / float(strides[2]))

‘VALID’类型的padding, 其输出的height和width计算如下:
out_height = ceil(float(in_height – filter_height + 1) / float(strides[1]))
out_width = ceil(float(in_width – filter_width + 1) / float(strides[2]))

:tensorflow中的卷积,严格上来说是cross-correlation,而不是卷积。因为在计算的过程中,没有对filter进行翻转,而严格的卷积计算是需要对filter进行翻转的!!!】

代码验证

tensorflow中的tf.nn.conv2d函数,实际上相当于用filter,以一定的步长stride在image上进行滑动,计算重叠部分的内积和,即为卷积结果。下面从定义出发对tf.nn.conv2d函数的功能进行验证:

# -*- coding: utf-8 -*-

from __future__ import division
import tensorflow as tf
import numpy as np
import math
import pandas as pd

input_arr = np.zeros((12, 15), dtype=np.float32)
number = 0
for row_idx in range(input_arr.shape[0]):
    for col_idx in range(input_arr.shape[1]):
        input_arr[row_idx][col_idx] = number
        number += 1

number = 6
w_arr = np.zeros((2, 3), dtype=np.float32)
for row_idx in range(w_arr.shape[0]):
    for col_idx in range(w_arr.shape[1]):
        w_arr[row_idx][col_idx] = number
        number -= 1

stride = [1, 1, 1, 1]

# 从卷积的定义【实际上不是卷积,而是cross-correlation】进行计算验证---对VALID类型卷积进行验证
res_shape_0 = int(math.ceil((input_arr.shape[0] - w_arr.shape[0] + 1) / stride[1]))
res_shape_1 = int(math.ceil((input_arr.shape[1] - w_arr.shape[1] + 1) / stride[2]))
validation_res = np.zeros(shape=(res_shape_0, res_shape_1), dtype=np.float32)

for row_idx in range(validation_res.shape[0]):
    for col_idx in range(validation_res.shape[1]):
        patch = input_arr[row_idx:row_idx+w_arr.shape[0], col_idx:col_idx+w_arr.shape[1]]
        # 这里的 * 实际上代表的是点积,即对应元素位置相乘
        res = np.sum(patch * w_arr)
        validation_res[row_idx][col_idx] = res

print('result of convolution from its definition: validation_res')
print validation_res
pd.DataFrame(validation_res).to_csv('Results/validation_res.csv', index=False, header=False)

input_arr = np.reshape(input_arr, [1, input_arr.shape[0], input_arr.shape[1], 1])
w_arr = np.reshape(w_arr, [w_arr.shape[0], w_arr.shape[1], 1, 1])

# 相当于要输入的图片,shape: [1, 12, 15, 1]
net_in = tf.constant(value=input_arr, dtype=tf.float32)

# 相当于filter, shape: [2, 3, 1, 1]
W = tf.constant(value=w_arr, dtype=tf.float32)

# tensorflow卷积的计算结果:
# valid卷积结果, shape: [1, 11, 13, 1]
result_conv_valid = tf.nn.conv2d(net_in, W, stride, 'VALID', True)

# same卷积结果, shape: [1, 12, 15, 1]
result_conv_same = tf.nn.conv2d(net_in, W, stride, 'SAME', True)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

valid_conv_res = sess.run(result_conv_valid)
same_conv_res = sess.run(result_conv_same)
sess.close()

print valid_conv_res.shape
valid_conv_res = np.reshape(valid_conv_res, [valid_conv_res.shape[1], valid_conv_res.shape[2]])
same_conv_res = np.reshape(same_conv_res, [same_conv_res.shape[1], same_conv_res.shape[2]])
print('tensorflow conv res: valid_conv_res')
print valid_conv_res
pd.DataFrame(valid_conv_res).to_csv('Results/conv_res.csv', index=False, header=False)
pd.DataFrame(same_conv_res).to_csv('Results/result_conv_same.csv', index=False, header=False)

上面代码,只针对valid卷积类型进行了验证,对same的卷积类型没有验证【same类型的卷积,其padding方式还不懂,求懂的高手指教】。计算结果保存到了相应的csv文件中。
(1)Tensorflow valid类型卷积计算结果:
这里写图片描述
(2)Tensorflow same类型卷积计算结果:
这里写图片描述
(3)从卷积定义出发,valid类型卷积计算结果:
这里写图片描述

可以看出,其验证结果是正确的。并且same和valid的卷积结果,除边缘部分外,其余的值都是一样的。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
NET框架(.NET Framework) 是由微软开发,一个致力于敏捷软件开发(Agile softwaredevelopment)、快速应用开发(Rapidapplication development)、平台无关性和网络透明化的软件开发平台。.NET是微软为下一个十年对服务器和桌面型软件工程迈出的第一步。.NET包含许多有助于互联网和内部网应用迅捷开发的技术。 .NET框架是一个多语言组件开发和执行环境,它提供了一个跨语言的统一编程环境。.NET框架的目的是便于开发人员更容易地建立Web应用程序和Web服务,使得Internet上的各应用程序之间,可以使用Web服务进行沟通。从层次结构来看,.NET框架又包括三个主要组成部分:公共语言运行时(CLR:Common Language Runtime)、服务框架(Services Framework)和上层的两类应用模板——传统的Windows应用程序模板(Win Forms)和基于ASP NET的面向Web的网络应用程序模板(Web Forms和Web Services)。 公共语言运行时(CLR),是一个运行时环境,管理代码的执行并使开发过程变得更加简单。CLR是一种受控的执行环境,其功能通过编译器与其它工具共同展现。 在CLR之上的是服务框架,它提供了一套开发人员希望在标准语言库中存在的基类库,包括集合、输入/输出、字符串及数据类。 那么,在Windows DNA(分布式集成网络应用体系结构)之后,微软提出新的.NET框架(新托管代码编程模型)的主要原因是什么? 问题出现在已开发了多种技术的整合的一个单一应用程序的子系统上。例如,一个制造企业有不同的系统,如库存管理系统,物料清单系统,财务总帐系统,所有使用可用于应用程序开发的各种技术实现的。这些系统需要集成在一起,从而形成一个更高级别的企业信息系统的组织。要做到这一点,应用程序开发人员必须使用如微 软的分布式组件对象模型(DCOM),通用对象请求代理体系结构(CORBA),Java远程方法调用(RMI)等技术。然而,这些分布的技术通过已开发的应用程序编程语言非常紧密地耦合在一起。 跨语言的互操作性也是受限的。例如,如果在Visual C++类已经被创建,那么不可能在Visual Basic开发新的类并将其扩展到Visual C++。因此,开发者将不得不用每一种项目中用到的语言重新编写同样的逻辑的类。功能的可重用性得到了支持,但在早期的技术,真正的代码的可重用性是不可用。因此,开发人员不得不学习被用于应用程序的开发组织用到的所有语言。注册的COM组件。COM组件注册,才可以在目标机器上使用的应用程序。应用程序必须查找Windows注册表中查找并加载的COM组件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值