AlexeyAB / darknet

YOLOv4 / Scaled-YOLOv4 / YOLO - Neural Networks for Object Detection (Windows and Linux version of Darknet )
http://pjreddie.com/darknet/
Other
21.64k stars 7.96k forks source link

The Conv layer of yolov3-tiny_xnor #5393

Open Yingxiu-Chang opened 4 years ago

Yingxiu-Chang commented 4 years ago

@AlexeyAB Hello Sir, I'm working on your yolov3-tiny_xnor model and facing some confusions.

  1. In XNOR Conv layer, did you follow this convolutional algorithm? image The fomula is I∗W≈(sign(I)⊛sign(W))⊙K⊙α.
  2. If question 1 is yes, did you use alpha and K in the XNOR Conv layer? I confused about how to get the alpha and K results.
  3. In your yolov3-tiny_xnor.cfg, there is a bin_output=1. I'm not sure where you use it. Just like the formula in question 1, did you put it before ⊙K or after ⊙α?
AlexeyAB commented 4 years ago
  1. yes
  2. as in any common conv-layers, there are: conv, *scale, +bias scale = K*alpha also there is +bias
  3. bin_output=1 is used before xnor=1 layer, it means that we should apply activation, since it doesn't make sense
Yingxiu-Chang commented 4 years ago

Got it. So there is +bias after ⊙α, and finally use batch_normalization, right?

Yingxiu-Chang commented 4 years ago

@AlexeyAB Got it. So there is +bias after ⊙α, and finally use batch_normalization, right?

Yingxiu-Chang commented 4 years ago

@AlexeyAB Hello Sir, When I was reading your darknet code, especially in convolutional_kernels.cu. The comments between line 592 and line 598 are

    if (l.batch_normalize) {
        forward_batchnorm_layer_gpu(l, state);
    }
    else {
        add_bias_gpu(l.output_gpu, l.biases_gpu, l.batch, l.n, l.out_w*l.out_h);
    }
#endif

which means that we can only use BN or bias separately.

  1. As refering your previous answers, did you only use +bias in your middle conv layers of yolov3-tiny_xnor configuration?
  2. Actually, I can extract the kernel weights from yolov3-tiny_xnor.weights, but I don't know how to extract the float type of bias from weights file. Thank you for your help.
AlexeyAB commented 4 years ago
  1. I use BN for all conv-layers (except conv with activation=linear)

  2. https://github.com/AlexeyAB/darknet/blob/6cbb75d10b43a95f11326a2475d64500b11fa64e/src/parser.c#L1695-L1718

Yingxiu-Chang commented 4 years ago

@AlexeyAB Hello Sir, I confuse about the function of float_to_bit in gemm.c, especially between line 1789 and line 1811 as below.

void float_to_bit(float *src, unsigned char *dst, size_t size)
{
    size_t dst_size = size / 8 + 1;
    memset(dst, 0, dst_size);

    size_t i;
    //__m256i all256_sing1 = _mm256_set_epi32(0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000);
    __m256 float_zero256 = _mm256_set1_ps(0.0);

    for (i = 0; i < size; i+=8)
    {
        //__m256i src256 = _mm256_loadu_si256((__m256i *)(&src[i]));
        //__m256i result256 = _mm256_and_si256(src256, all256_sing1); // check sign in 8 x 32-bit floats
        //uint32_t mask = _mm256_movemask_ps(_mm256_castsi256_ps(result256)); // (val >= 0) ? 0 : 1
        ////mask = ~mask;   // inverse mask,  (val >= 0) ? 1 : 0

        __m256 src256 = _mm256_loadu_ps((float *)(&src[i]));
        __m256 result256 = _mm256_cmp_ps(src256, float_zero256, _CMP_GT_OS);
        uint32_t mask = _mm256_movemask_ps(result256); // (val > 0) ? 0 : 1

        dst[i / 8] = mask;
    }
}

The part that I don't get it is the function of __m256 src256 = _mm256_loadu_ps((float *)(&src[i])); Each src[i] is a 32-bit float points element. However, src256 is a 256-bit element. I don't know how to change a 32-bit element to a 256-bit element.

AlexeyAB commented 4 years ago

It reads 8 x float-32-bit values. https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/intrinsics/intrinsics-for-intel-advanced-vector-extensions/intrinsics-for-load-and-store-operations-1/mm256-loadu-ps.html

Yingxiu-Chang commented 4 years ago

Thank you so much for your answer.