php+网站开发案例教程,做网站的财务需求,国外免费推广平台有哪些,个人建站模板第1种解说#xff1a;(核心最后一张图#xff0c;两种填充方式输出的形状尺寸计算公式)在用tensorflow写CNN的时候#xff0c;调用卷积核api的时候#xff0c;会有填padding方式的参数#xff0c;找到源码中的函数定义如下#xff08;max pooling也是一样#xff09;(核心最后一张图两种填充方式输出的形状尺寸计算公式)在用tensorflow写CNN的时候调用卷积核api的时候会有填padding方式的参数找到源码中的函数定义如下max pooling也是一样def conv2d(input, filter, strides, padding, use_cudnn_on_gpuNone, data_formatNone, nameNone)源码中对于padding参数的说明如下padding: A string from: SAME, VALID. The type of padding algorithm to use.说了padding可以用“SAME”和“VALID”两种方式但是对于这两种方式具体是什么并没有多加说明。 这里用Stack Overflow中的一份代码来简单说明一下代码如下x tf.constant([[1., 2., 3.],[4., 5., 6.]])
x tf.reshape(x, [1, 2, 3, 1]) # give a shape accepted by tf.nn.max_pool
valid_pad tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], paddingVALID)
same_pad tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], paddingSAME)print(valid_pad.get_shape())
print(same_pad.get_shape())
# 最后输出的结果为
(1, 1, 1, 1)
(1, 1, 2, 1)可以看出“SAME”的填充方式是比“VALID”的填充方式多了一列。 让我们来看看变量x是一个2x3的矩阵max pooling窗口为2x2两个维度的strides2。 第一次由于窗口可以覆盖橙色区域做max pool操作没什么问题如下 接下来就是“SAME”和“VALID”的区别所在由于步长为2当向右滑动两步之后“VALID”发现余下的窗口不到2x2所以就把第三列直接去了而“SAME”并不会把多出的一列丢弃但是只有一列了不够2x2怎么办填充如上图所示“SAME”会增加第四列以保证可以达到2x2但为了不影响原来的图像像素信息一般以0来填充。(这里使用表格的形式展示markdown不太好控制格式明白意思就行)这就不难理解不同的padding方式输出的形状会有所不同了。 在CNN用在文本中时一般卷积层设置卷积核的大小为n×k其中k为输入向量的维度即[n,k,input_channel_num,output_channel_num]这时候我们就需要选择“VALID”填充方式这时候窗口仅仅是沿着一个维度扫描而不是两个维度。可以理解为统计语言模型当中的N-gram。我们设计网络结构时需要设置输入输出的shape源码nn_ops.py中的convolution函数和pool函数给出的计算公式如下If padding SAME:output_spatial_shape[i] ceil(input_spatial_shape[i] / strides[i])If padding VALID:output_spatial_shape[i] ceil((input_spatial_shape[i] -(spatial_filter_shape[i]-1) * dilation_rate[i])/ strides[i]).dilation_rate为一个可选的参数默认为1这里我们可以先不管它。 整理一下对于“VALID”输出的形状计算如下 参考https://cloud.tencent.com/developer/article/1012365第2种解说利用tf.nn.conv2d示例来理解 strides, padding效果这里先再简单重复一下tf.nn.conv2d使用其基本参数的使用规范同样也适用于其他CNN语句tf.nn.conv2d (input, filter, strides, padding, use_cudnn_on_gpuNone, data_formatNone, nameNone)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]第一位和最后一位固定必须是1padding string类型值为“SAME” 和 “VALID”表示的是卷积的形式是否考虑边界。SAME是考虑边界不足的时候用0去填充周围VALID则不考虑use_cudnn_on_gpu bool类型是否使用cudnn加速默认为trueimport tensorflow as tf
# case 1
# 输入是1张 3*3 大小的图片图像通道数是5卷积核是 1*1 大小数量是1
# 步长是[1,1,1,1]最后得到一个 3*3 的feature map
# 1张图最后输出就是一个 shape为[1,3,3,1] 的张量
input tf.Variable(tf.random_normal([1,3,3,5]))
filter tf.Variable(tf.random_normal([1,1,5,1]))
op1 tf.nn.conv2d(input, filter, strides[1,1,1,1], paddingSAME)# case 2
# 输入是1张 3*3 大小的图片图像通道数是5卷积核是 2*2 大小数量是1
# 步长是[1,1,1,1]最后得到一个 3*3 的feature map
# 1张图最后输出就是一个 shape为[1,3,3,1] 的张量
input tf.Variable(tf.random_normal([1,3,3,5]))
filter tf.Variable(tf.random_normal([2,2,5,1]))
op2 tf.nn.conv2d(input, filter, strides[1,1,1,1], paddingSAME)# case 3
# 输入是1张 3*3 大小的图片图像通道数是5卷积核是 3*3 大小数量是1
# 步长是[1,1,1,1]最后得到一个 1*1 的feature map (不考虑边界)
# 1张图最后输出就是一个 shape为[1,1,1,1] 的张量
input tf.Variable(tf.random_normal([1,3,3,5]))
filter tf.Variable(tf.random_normal([3,3,5,1]))
op3 tf.nn.conv2d(input, filter, strides[1, 1, 1, 1], paddingVALID) # case 4
# 输入是1张 5*5 大小的图片图像通道数是5卷积核是 3*3 大小数量是1
# 步长是[1,1,1,1]最后得到一个 3*3 的feature map (不考虑边界)
# 1张图最后输出就是一个 shape为[1,3,3,1] 的张量
input tf.Variable(tf.random_normal([1,5,5,5]))
filter tf.Variable(tf.random_normal([3,3,5,1]))
op4 tf.nn.conv2d(input, filter, strides[1, 1, 1, 1], paddingVALID) # case 5
# 输入是1张 5*5 大小的图片图像通道数是5卷积核是 3*3 大小数量是1
# 步长是[1,1,1,1]最后得到一个 5*5 的feature map (考虑边界)
# 1张图最后输出就是一个 shape为[1,5,5,1] 的张量
input tf.Variable(tf.random_normal([1,5,5,5]))
filter tf.Variable(tf.random_normal([3,3,5,1]))
op5 tf.nn.conv2d(input, filter, strides[1, 1, 1, 1], paddingSAME) # case 6
# 输入是1张 5*5 大小的图片图像通道数是5卷积核是 3*3 大小数量是7
# 步长是[1,1,1,1]最后得到一个 5*5 的feature map (考虑边界)
# 1张图最后输出就是一个 shape为[1,5,5,7] 的张量
input tf.Variable(tf.random_normal([1,5,5,5]))
filter tf.Variable(tf.random_normal([3,3,5,7]))
op6 tf.nn.conv2d(input, filter, strides[1, 1, 1, 1], paddingSAME) # case 7
# 输入是1张 5*5 大小的图片图像通道数是5卷积核是 3*3 大小数量是7
# 步长是[1,2,2,1]最后得到7个 3*3 的feature map (考虑边界)
# 1张图最后输出就是一个 shape为[1,3,3,7] 的张量
input tf.Variable(tf.random_normal([1,5,5,5]))
filter tf.Variable(tf.random_normal([3,3,5,7]))
op7 tf.nn.conv2d(input, filter, strides[1, 2, 2, 1], paddingSAME) # case 8
# 输入是10 张 5*5 大小的图片图像通道数是5卷积核是 3*3 大小数量是7
# 步长是[1,2,2,1]最后每张图得到7个 3*3 的feature map (考虑边界)
# 10张图最后输出就是一个 shape为[10,3,3,7] 的张量
input tf.Variable(tf.random_normal([10,5,5,5]))
filter tf.Variable(tf.random_normal([3,3,5,7]))
op8 tf.nn.conv2d(input, filter, strides[1, 2, 2, 1], paddingSAME) init tf.initialize_all_variables()
with tf.Session() as sess:sess.run(init)print(* * 20 op1 * * 20)print(sess.run(op1))print(* * 20 op2 * * 20)print(sess.run(op2))print(* * 20 op3 * * 20)print(sess.run(op3))print(* * 20 op4 * * 20)print(sess.run(op4))print(* * 20 op5 * * 20)print(sess.run(op5))print(* * 20 op6 * * 20)print(sess.run(op6))print(* * 20 op7 * * 20)print(sess.run(op7))print(* * 20 op8 * * 20)print(sess.run(op8))# 运行结果运行结果这里就省略了太长了所以不写这里了。复制语句到Jupyter中运行一下就懂了参考理解tf.nn.conv2d方法