zoukankan      html  css  js  c++  java
  • mxnet与tensorflow的卷积实现细节比较

    mxnet的卷积 kernel = 3  pad=1边界补充0后,不管stride是否1还是2,imgw = 奇数或者偶数, 都是从图像位置(0,0)开始卷积

    tensorlfow的卷积 kernel = 3 pad=‘SAME’边界补充0后,

    imgw = 偶数          

    stride=1, 是从图像位置(0,0)开始卷积

    stride=2, 是从图像位置(1,1)开始卷积 与mxnet不同 

    imgw = 奇数         

    stride=1, 是从图像位置(0,0)开始卷积

    stride=2, 是从图像位置(0,0)开始卷积

    tensorlfow的卷积 kernel = 3 pad=‘VAILD’ 边界不补充0,

    不管stride是否1还是2,imgw = 奇数或者偶数, 都是从图像位置(1,1)开始卷积

    #coding=utf-8
    import math
    import mxnet as mx
    import numpy as np
    import tensorflow as tf
    from mxnet.gluon import nn
    from mxnet import ndarray as nd
    # import tensorlayer as tl
    # from tensorflow.contrib.layers.python.layers import utils
    # import collections
    # from tensorlayer.layers import Layer, list_remove_repeat
    
    def out_dim(input, kernel, stride, pad, dilate):
        x = input
        p = pad
        s = stride
        d = dilate
        k = kernel
        output = math.floor((x + 2 * p - d * (k - 1) - 1) / s) + 1
        return output
    
    
    #比较mxnet与tensorflow的conv batchnorm prelu的计算
    #mxnet卷积层
    # 输入数据格式是:batch * inchannel * height * width
    # 输出数据格式是:batch * outchannel * height * width
    # 权重格式:      output_channels * in_channels * height * width
    #(1)比较卷积
    height = 6
    width = 6
    inchannel = 1
    outchannel = 1
    
    # #conv0 (64, 112, 112) kernel (3, 3) stride (1, 1) pad (1, 1)
    # wkernel = 3
    # stride = 1
    # pad = 1
    # dilate  = 1
    # output_height = out_dim(height, wkernel, stride, pad, dilate)
    # if output_height == height:
    #     print("input: ", height, width, " wkernel", wkernel, " stride: ", stride, " pad:", pad, " output_height: ", output_height, output_height, "SAME")
    # else:
    #     print("input: ", height, width, " wkernel", wkernel, " stride: ", stride, " pad:", pad, " output_height: ", output_height, output_height, "VALID")
    
    #stage1_unit1_conv2 (64, 56, 56) kernel (3, 3) stride (2, 2) pad (1, 1)
    wkernel = 3
    stride = 2
    pad = 1
    dilate  = 1
    output_height = out_dim(height, wkernel, stride, pad, dilate)
    if output_height == height:
        print("input: ", height, width, " wkernel", wkernel, " stride: ", stride, " pad:", pad, " output_height: ", output_height, output_height, "SAME")
    else:
        print("input: ", height, width, " wkernel", wkernel, " stride: ", stride, " pad:", pad, " output_height: ", output_height, output_height, "VALID")
    
    # #stage1_unit1_conv1sc (64, 56, 56) kernel (1, 1) stride (2, 2) pad (0, 0)
    # wkernel = 1
    # stride = 2
    # pad = 0
    # dilate  = 1
    # output_height = out_dim(height, wkernel, stride, pad, dilate)
    # if output_height == height:
    #     print("input: ", height, width, " wkernel", wkernel, " stride: ", stride, " pad:", pad, " output_height: ", output_height, output_height, "SAME")
    # else:
    #     print("input: ", height, width, " wkernel", wkernel, " stride: ", stride, " pad:", pad, " output_height: ", output_height, output_height, "VALID")
    
    w = nd.arange(wkernel * wkernel * inchannel * outchannel).reshape((outchannel,inchannel,wkernel,wkernel))
    b = nd.array([0])
    data = nd.arange(height * width * inchannel).reshape((1,inchannel,height,width))
    # mxnet直接nd卷积运算nd.Convolution
    #out = nd.Convolution(data,w,b,kernel=w.shape[2:],num_filter=outchannel,stride=(1,1), pad=(1, 1))
    print('input:',data)
    print('weight:',w)
    #print('bias:',b)
    # print('mxnet ndarray output:',out)
    # print('
    ')
    
    #mxnet利用symbol计算卷积
    ws = mx.sym.Variable('w')
    bs = mx.sym.Variable('b')
    datas = mx.sym.Variable('data')
    # outs = mx.sym.Convolution(data=datas, weight=ws, bias=bs, num_filter=w.shape[1], kernel=w.shape[2:], stride=(1,1), pad=(0, 0),
    #                                 no_bias=False, name="conv0")
    outs = mx.sym.Convolution(data=datas, weight=ws, num_filter=outchannel, kernel=w.shape[2:], stride=(stride,stride), pad=(pad, pad),
                                    no_bias=True, name="conv0")
    #outs = mx.sym.Convolution(datas,ws,bs,kernel=w.shape[2:],num_filter=w.shape[1])
    ex=outs.bind(mx.cpu(), {'data':data, 'w':w, 'b':b})
    ex.forward()
    mxnetresult = ex.outputs[0].asnumpy()
    print("mxnet symbol:
    ", ex.outputs[0].asnumpy())
    # output_height = out_dim(height, w.shape[2], stride, pad, dilate)
    # output_width = out_dim(width, w.shape[2], stride, pad, dilate)
    # print("input_height: ", height, width)
    # print("output_height: ", output_height, output_width)
    
    
    
    #tensorflow计算卷积
    #(W-F + 2 p / S)+ 1
    # 输入数据格式是:batch *  height * width * inchannel
    # 输出数据格式是:batch  * height * width * outchannel
    # 权重格式:      height * width * in_channels * output_channels 
    # w = np.arange(4).reshape((2,2,1,1))
    # b = np.array([0])
    # data = np.arange(9).reshape((1,3,3,1))
    # w = w.reshape((wkernel,wkernel,inchannel,outchannel)).asnumpy()
    # data = data.reshape((1, height,width,inchannel)).asnumpy()
    
    data = data.asnumpy().transpose(0,2,3,1)
    w = w.asnumpy().transpose(2,3,1,0)
    b = b.asnumpy()
    # print('input:',data)
    # print('inputshape:',data.shape)
    # print('weight:',w)
    # print('weight:',w.shape)
    input = tf.Variable(data, dtype=np.float32)
    #input_reshape = tf.reshape(input, [1,inchannel,height,width])
    filter = tf.Variable(w, dtype=np.float32)
    #filter_reshape = tf.reshape(filter, [outchannel,inchannel,wkernel,wkernel])
    if pad == 0:
        conv = tf.nn.conv2d(input, filter, strides=[1, stride, stride, 1], padding='VALID')
    else:
        conv = tf.nn.conv2d(input, filter, strides=[1, stride, stride, 1], padding='SAME')
    
    kernel_size = 3
    kernel_size_effective = kernel_size
    pad_total = kernel_size_effective - 1
    pad_beg = pad_total // 2
    pad_end = pad_total - pad_beg
    print(pad_beg, pad_end)
    input_PadLayer = tf.pad(input, [[0, 0], [pad_beg, pad_end], [pad_beg, pad_end], [0, 0]], name='padding')
    
    if stride==2:
        conv_padlayer = tf.nn.conv2d(input_PadLayer, filter, strides=[1, stride, stride, 1], padding='VALID')
    
    # nets = tl.layers.Conv2d(inputs, n_filter=num_outputs, filter_size=(kernel_size, kernel_size), b_init=None,
    #                             strides=(strides, strides), W_init=w_init, act=None, padding='VALID', name=scope,
    #                             use_cudnn_on_gpu=True)
    #nets = BatchNormLayer(nets, act=tf.identity, is_train=True, trainable=trainable, name=scope+'bn3')
    #conv_reshape = tf.reshape(conv, [1,outchannel,output_height,output_height])
    #conv_reshape = tf.reshape(conv, [1,1,2,2])
    
    init = tf.global_variables_initializer()
    with tf.Session() as sess:
        sess.run(init)
        #print("input: 
    ", sess.run(input))
        input_reshape = sess.run(input).transpose(0,3,1,2)
        #print("input_reshape: 
    ", input_reshape)
        #print("filter: 
    ", sess.run(filter))
        filter_reshape = sess.run(filter).transpose(3,2,0,1)
        #print("filter_reshape: 
    ", filter_reshape)
        #print("conv ", sess.run(conv))
        conv_reshape = sess.run(conv).transpose(0,3,1,2)
        print("conv_reshape: 
    ", conv_reshape)
        if stride==2:
            input_PadLayer_reshape = sess.run(input_PadLayer).transpose(0,3,1,2)
            print("input_PadLayer_reshape: 
    ", input_PadLayer_reshape)
    
            conv_padlayer_reshape = sess.run(conv_padlayer).transpose(0,3,1,2)
            print("conv_padlayer_reshape: 
    ", conv_padlayer_reshape)
        
            tensorflowresult = conv_padlayer_reshape
        else:
            tensorflowresult = conv_reshape
        #print("tf_height", op2_reshape.shape.as_list())
        #print("tf_height", op2_reshape.shape.as_list())
        if (tensorflowresult==mxnetresult).all():
            print("success ")
        else:
            print("failed ")

    input: 6 6 wkernel 3 stride: 2 pad: 1 output_height: 3 3 VALID
    input:
    [[[[ 0. 1. 2. 3. 4. 5.]
    [ 6. 7. 8. 9. 10. 11.]
    [ 12. 13. 14. 15. 16. 17.]
    [ 18. 19. 20. 21. 22. 23.]
    [ 24. 25. 26. 27. 28. 29.]
    [ 30. 31. 32. 33. 34. 35.]]]]
    <NDArray 1x1x6x6 @cpu(0)>
    weight:
    [[[[ 0. 1. 2.]
    [ 3. 4. 5.]
    [ 6. 7. 8.]]]]
    <NDArray 1x1x3x3 @cpu(0)>
    mxnet symbol:
    [[[[ 103. 196. 262.]
    [ 411. 618. 690.]
    [ 735. 1050. 1122.]]]]
    1 1
    conv_reshape:
    [[[[ 366. 438. 294.]
    [ 798. 870. 546.]
    [ 451. 481. 271.]]]]
    input_PadLayer_reshape:
    [[[[ 0. 0. 0. 0. 0. 0. 0. 0.]
    [ 0. 0. 1. 2. 3. 4. 5. 0.]
    [ 0. 6. 7. 8. 9. 10. 11. 0.]
    [ 0. 12. 13. 14. 15. 16. 17. 0.]
    [ 0. 18. 19. 20. 21. 22. 23. 0.]
    [ 0. 24. 25. 26. 27. 28. 29. 0.]
    [ 0. 30. 31. 32. 33. 34. 35. 0.]
    [ 0. 0. 0. 0. 0. 0. 0. 0.]]]]
    conv_padlayer_reshape:
    [[[[ 103. 196. 262.]
    [ 411. 618. 690.]
    [ 735. 1050. 1122.]]]]
    success

  • 相关阅读:
    反汇编角度->C++ const
    反汇编->C++虚函数深度分析
    反汇编->C++内联
    反汇编->C++引用与指针
    数据库初步认识
    数据库系统的结构抽象与演变
    Android · PendingIntent学习
    Android · ContentProvider学习
    notepad++
    MapReduce使用JobControl管理实例
  • 原文地址:https://www.cnblogs.com/adong7639/p/9212189.html
Copyright © 2011-2022 走看看