• 徑向基函數 RBF Function
  • 徑向基網路 RBF Network Model

https://www.youtube.com/watch?v=1Cw45yNm6VA

徑向基函數

關於 y 軸對稱,且在 x=0 時達到最大值(峰值),峰值一般為 1

如高斯函數:
image.png
徑向基函數也可以是多維的,但不論輸入向量是多少維,輸出都是一個標量值(為輸入向量和中心向量的距離,一般為歐氏距離,記為 r

輸入向量和中心向量維數相同,否則無法計算距離

高斯徑向基函數公式:
Radial Basic Function Network 徑向基函數網路 - 图2

可以看出,和中心向量越近,函數值越接近 1

在應用中會進行適當的放縮

Ricker 小波函數(墨西哥帽子函數)
Radial Basic Function Network 徑向基函數網路 - 图3
image.png

徑向基函數網路

即可用於分類,也可用於回歸問題

將多個徑向基函數加權求和,每個徑向基函數都接受一個帶權重的輸入,從而對輸出進行預測

image.png

X 為輸入向量,c 為中心向量,因此括號中的值為 r
p 是所選的徑向基函數
a 是每個函數的權重,一般為向量形式
b 是每個輸入對應的權重

看下下面的圖立刻就能明白原理了:
箭頭表示公式中的全部係數
輸入和徑向基函數的箭頭表示 b
徑向基函數和求和間的箭頭表示 a
bias 輸出恆為 1,因此不需要輸入,之後誠意對應的係數,相當於無論輸入什麼,都有一個對應係數直接加在輸出上。它很有用,尤其在輸入為 0 時,也能保證依然有值可以輸出。

多個求和函數,求出的和的最大值即為對應的預測類別
image.png
鳶尾花資料集為例:
輸入為四維向量,輸出三種類別(採用 One-hot 編碼)
image.png

徑向基函數網路的長期記憶向量包含以下部分:

  • 輸入係數
  • 輸出係數(求和係數)
  • 徑向基函數放縮範圍(在各維度範圍相同)
  • 徑向基函數中心向量

構造 rbf 函數網路

  1. typedef struct RBF_NETWORK {
  2. RBF_FUNCTION rbf;
  3. unsigned int ltm_size;
  4. unsigned int input_count;
  5. unsigned int rbf_count;
  6. unsigned int output_count;
  7. double *long_term_memory;
  8. double *rbf_output;
  9. double *weighted_input;
  10. unsigned int *rbf_index;
  11. unsigned int index_input_weights;
  12. unsigned int index_output_weights;
  13. } RBF_NETWORK;
  1. RBF_NETWORK* RBFNetworkCreate(RBF_FUNCTION rbf, // 指定使用的函數,如高斯函數
  2. int input_count, // 輸入通道數
  3. int rbf_count, // rbf 函數數目
  4. int output_count) // 輸出通道數
  5. {
  6. RBF_NETWORK *result;
  7. int i;
  8. /* calculate input and output weight counts
  9. add 1 to output to account for an extra bias node */
  10. const int inputWeightCount = input_count * rbf_count;
  11. const int outputWeightCount = (rbf_count + 1) * output_count;
  12. const int rbfParams = (input_count + 1) * rbf_count;
  13. /* allocate structure */
  14. result = (RBF_NETWORK*)calloc(1,sizeof(RBF_NETWORK));
  15. result->input_count = input_count;
  16. result->rbf_count = rbf_count;
  17. result->rbf = rbf;
  18. result->output_count = output_count;
  19. result->rbf_index = (unsigned int*)calloc(rbf_count,sizeof(int));
  20. result->rbf_output = (double*)calloc(rbf_count+1,sizeof(double));
  21. result->weighted_input = (double*)calloc(input_count,sizeof(double));
  22. result->ltm_size = inputWeightCount + outputWeightCount + rbfParams;
  23. result->long_term_memory = (double*)calloc(result->ltm_size,sizeof(double));
  24. result->index_input_weights = 0;
  25. result->index_output_weights = inputWeightCount + rbfParams;
  26. for (i = 0; i < rbf_count; i++) {
  27. result->rbf_index[i] = inputWeightCount + ((input_count + 1) * i);
  28. }
  29. return result;
  30. }

計算 rbf 網路輸出

  1. void RBFNetworkComputeRegression(RBF_NETWORK *network, double *input, double *output) {
  2. unsigned int inputIndex, outputIndex, rbfIndex, memoryIndex;
  3. double sum;
  4. /* first, compute the output values of each of the RBFs
  5. Add in one additional RBF output for bias (always set to one). */
  6. network->rbf_output[network->rbf_count] = 1; // bias
  7. for (rbfIndex = 0; rbfIndex < network->rbf_count; rbfIndex++) {
  8. /* weight the input */
  9. for (inputIndex = 0; inputIndex < network->input_count; inputIndex++) {
  10. memoryIndex = network->index_input_weights + (rbfIndex * network->input_count) + inputIndex;
  11. network->weighted_input[inputIndex] = input[inputIndex] * network->long_term_memory[memoryIndex];
  12. }
  13. /* calculate the rbf */
  14. network->rbf_output[rbfIndex] = network->rbf(network->weighted_input,0,network->input_count,network->long_term_memory,network->rbf_index[rbfIndex]);
  15. }
  16. /* second, calculate the output, which is the result of the weighted result of the RBF's. */
  17. for (outputIndex = 0; outputIndex < network->output_count; outputIndex++) {
  18. sum = 0;
  19. for (rbfIndex = 0; rbfIndex <= network->rbf_count; rbfIndex++) {
  20. /* add 1 to rbf length for bias */
  21. memoryIndex = network->index_output_weights + (outputIndex * (network->rbf_count + 1)) + rbfIndex;
  22. sum += network->rbf_output[rbfIndex] * network->long_term_memory[memoryIndex];
  23. }
  24. output[outputIndex] = sum;
  25. }
  26. }