【EAI】关于dnn_compute输出值predication的问题

原手势识别例程中的dnn_compute输出很正常

在使用例程提供的train脚本自己训练网络后,输出就变得不正常了,如6分类任务,有几个任务永远是0,无论输入是什么

Parents
  • 你把你自己的dnn_compute函数贴上来看看。

  • TPrecision* dnn_compute(TPrecision* X_0)
    {
    convolution(X_0,Conv2D_0_pad,Conv2D_0_weights,Conv2D_0_biases,Conv2D_0,layer_shapes.Conv2D_0_shape);
    relu(Conv2D_0,layer_shapes.Conv2D_0_activ_shape);
    pooling_without_pad(Conv2D_0,MaxPool_0,layer_shapes.MaxPool_0_shape);
    convolution(MaxPool_0,Conv2D_1_0_pad,Conv2D_1_0_weights,Conv2D_1_0_biases,Conv2D_1_0,layer_shapes.Conv2D_1_0_shape);
    relu(Conv2D_1_0,layer_shapes.Conv2D_1_0_activ_shape);
    pooling(Conv2D_1_0,Flatten_flatten_Reshape_0_pad,Flatten_flatten_Reshape_0,layer_shapes.Flatten_flatten_Reshape_0_shape);

    innerproduct(Flatten_flatten_Reshape_0,fully_connected_BiasAdd_0_weights,fully_connected_BiasAdd_0_biases,fully_connected_BiasAdd_0,layer_shapes.fully_connected_BiasAdd_0_shape);
    return(fully_connected_BiasAdd_0);
    }
    这是我的dnn_compute,网络结构与提供的手写识别train脚本的完全相同
  • 可能是translator翻译过程中出错了,这个函数return之前少了一层softmax层,python脚本中应该是有这一层的。
    你在return前边加上一行:
    softmax(fully_connected_BiasAdd_0,layer_shapes.softmax_cross_entropy_with_logits_sg_Reshape_0_activ_shape);
    试试看。
    (上边函数的第二个参数名可能和你本地的不一样,可以去layer_shapes.h文件中的struct shapes最后一项查看正确的命名)
  • 是的,少了一层softmax,以及确定python脚本中是没有这一层的
    在加上这层后(第二个参数名只是一个数字,应该代表的是输出个数吧,手势识别是6分类,我们填了6)
    输出的prediction变成了正值,但是比较奇怪的是一直是prediction[0]的值最大,在0.9左右(之前都是负数,按线性输出应该是比较小的值才对啊)
  • 如果python脚本中没有这一层,那么这里也不应该有,可以看看你python里设置的网络模型吗?
  • 当然可以,就是官方给我们提供的hand_gesture_training .py中的网络模型

    从此处下载japan.renesasrulz.com/.../448

     

    def forward_prop(X, parameters):
    W1 = parameters['W1']
    W2 = parameters['W2']
    W3 = parameters['W3']

    # X_image = tf.reshape(X,[-1,n_H0,n_W0,1])
    # print (X.shape)
    Z1 = tf.nn.conv2d(X, W1, [1,1,1,1], padding="SAME")
    A1 = tf.nn.relu(Z1)
    P1 = tf.nn.max_pool(A1, ksize=[1,2,2,1],strides=[1,2,2,1], padding="SAME" )
    # print (P1)
    Z2 = tf.nn.conv2d(P1, W2,strides=[1,1,1,1], padding="SAME")
    A2 = tf.nn.relu(Z2)
    P2 = tf.nn.max_pool(A2, ksize=[1,2,2,1], strides=[1,2,2,1], padding="SAME")
    # print (P2)
    # Z3 = tf.nn.conv2d(P2, W3, strides=[1,1,1,1], padding="SAME")
    # A3 = tf.nn.relu(Z3)
    # P3 = tf.nn.max_pool(A3, ksize=[1,2,2,1], strides=[1,2,2,1], padding="SAME")
    # print (P3)
    P3 = tf.contrib.layers.flatten(P2)
    # print (P3)
    Z4 = tf.contrib.layers.fully_connected(P3,n_types, activation_fn=None)
    # print (Z4)

    return Z4

     

  • 你的python脚本中,两层池化层都是SAME padding的方式,但是C code中,第一层是pooling_without_pad,第二层变成了pooling,这种pooling方式是带padding的,这就导致这一层的输出跟你预设的不一致。
    你查查是不是这里的问题。
    (不过建议第二层池化层带padding好一点,因为经过第一层池化你的图变成25x25的尺寸,再做stride为2的池化如果不padding的话会有数据丢失。)
  • same padding是填充0的方式
    那么生成的应该是两层带padding的pooling吧?
    那我应该怎么修改生成的dnn_compute呢?pooling_without_pad和pooling函数的参数也不一样,也不明白带pooling的多出来的参数*dpad是怎么设置的
    为什么会翻译错误啊。。。
  • 这个翻译的模型结构和python里的结构是一致的。
    因为第一层池化是从50x50到25x25,就算选SAME padding也不会有任何补充,所以translator自动转换成了without pad的形式,其实是没有影响的。
    既然输出不一致,你追一追输入的位置是否一致?
    比如同一张图你在PC上进行推论,看推论结果是什么?然后把这张图以数组的形式存在代码中,让模型去对这个数组进行推论,对比一下两次推论的结果是否一致?
Reply
  • 这个翻译的模型结构和python里的结构是一致的。
    因为第一层池化是从50x50到25x25,就算选SAME padding也不会有任何补充,所以translator自动转换成了without pad的形式,其实是没有影响的。
    既然输出不一致,你追一追输入的位置是否一致?
    比如同一张图你在PC上进行推论,看推论结果是什么?然后把这张图以数组的形式存在代码中,让模型去对这个数组进行推论,对比一下两次推论的结果是否一致?
Children
No Data