将函数传递给结构数组内部的指针

时间:2019-08-25 00:08:17

标签: c arrays struct function-pointers

我正在尝试使用C从头开始实现神经网络,但是我遇到了一个关于如何动态地将激活函数分配给每一层的小问题。我创建了以下结构来表示网络的每一层:

typedef struct network{
    char* type;
    double* neurons;
    double (*activation_function)(double);
    double bias;
}network;

所以我有几个功能,如:

double tanh(double weight);

并创建一个像这样的网络阵列

network* neural_network = (network*) malloc(num_layers * sizeof(network));

但是,如果我这样做

neural_network[i].activation_function = &tanh;

代码编译没有错误,并在运行时给出分段错误。

如果我这样做

neural_network[i] -> activation_function = &tanh;

我收到以下编译错误:

  

错误:'->'(具有'network'{aka'struct network'})的无效类型参数

关于如何解决它的任何想法?

下面的最小可复制代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define ALLOW_REALLOC_LAYER 1 // allows a new layer to be added to a neural network where the pre-allocated space is already full


typedef struct network{
    char* type;
    double* neurons;
    double (*activation_function)(double);
    double bias;
}network;

double tanh(double weight){                     //tanh's range is between -1 and 1
    return((pow(M_E, 2 * weight) - 1)/(pow(M_E, 2 * weight) + 1));
}

double sigmoid(double weight){                  // sigmoid's range is between 0 and 1
    return(1/(1 + pow(M_E, weight * (-1))));
}

double identity(double weight){
    return(weight);
}

network* new_network(int num_layers){ // the 1st position of the array is the input layer and the nth position is the output layer
    if(num_layers < 2){
        printf("A neural network needs at least two layers\n");
        return(NULL);
    }

    int i;
    network* neural_network = (network*) malloc(num_layers * sizeof(network)); // initializing the neural network

    for(i = 0; i < num_layers; i++){
        neural_network[i].bias = 0.333; // initializing the bias of each network
        neural_network[i].neurons = NULL;
        neural_network[i].type = "feedforward";
    }

    return(neural_network);
}

void add_layer(network* neural_network, int* num_layers, int num_neurons, char* type, double (function)(double)){
    if(neural_network == NULL){
        printf("Neural network not initialized. Use new_network(int num_layers) to initialize it\n");
        return;
    }

    int i, j;
    pcg32_random_t rng1;

    for(i = 0; i < *num_layers; i++)
        if(neural_network[i].neurons == NULL)
            break;
                                                                                                    // checks if the neural network already has the pre-defined layers allocated
    if(i == *num_layers && ALLOW_REALLOC_LAYER){                                                    // if yes and ALLOW_REALLOC_LAYER == 1, then the neural network can be expanded
        neural_network = (network*) realloc(neural_network, (*num_layers + 1) * sizeof(network));

        neural_network[i].bias = 0.5; 
        neural_network[i].neurons = NULL;
        neural_network[i].type = type;
        neural_network[i].activation_function = &tanh;

        *num_layers = *num_layers + 1;                                                                              
    }else if(i == *num_layers && !ALLOW_REALLOC_LAYER){                                             // if yes and ALLOW_REALLOC_LAYER == 0, an error message is raised
        printf("Pre-allocated space is already full. Set ALLOW_REALLOC_LAYER to 1 to expand the neural network.");
        return;
    }

    neural_network[i].neurons = (double*) malloc(num_neurons * sizeof(double)); // creating the new layer

    for(j = 0; j < num_neurons; j++)                                        
        neural_network[i].neurons[j] = 0.5; // initializing the weights of each neuron

    printf("TEST : weight = %g \ntanh = %g", neural_network[i].neurons[0], neural_network[i].activation_function(neural_network[i].neurons[0]));
    return;
}


int main(void){
    int num_layers = 3;
    network* NN = new_network(num_layers);
    add_layer(NN, &num_layers, 10, "feedforward", &tanh);
    return(0);
}

1 个答案:

答案 0 :(得分:0)

结果证明,这只是功能add_layer()的错误条件设置。代替

if(i == *num_layers && ALLOW_REALLOC_LAYER){                                                    // if yes and ALLOW_REALLOC_LAYER == 1, then the neural network can be expanded
        neural_network = (network*) realloc(neural_network, (*num_layers + 1) * sizeof(network));

        neural_network[i].bias = 0.5; 
        neural_network[i].neurons = NULL;
        neural_network[i].type = type;
        neural_network[i].activation_function = &tanh;

        *num_layers = *num_layers + 1;                                                                              
    }else if(i == *num_layers && !ALLOW_REALLOC_LAYER){                                             // if yes and ALLOW_REALLOC_LAYER == 0, an error message is raised
        printf("Pre-allocated space is already full. Set ALLOW_REALLOC_LAYER to 1 to expand the neural network.");
        return;
    }

应该是

// checks if the neural network already has the pre-defined layers allocated
if(i == *num_layers && !ALLOW_REALLOC_LAYER){                                               // if yes and ALLOW_REALLOC_LAYER == 0, an error message is raised
    printf("Pre-allocated space is already full. Set ALLOW_REALLOC_LAYER to 1 to expand the neural network.");
    return;
}

// if yes and ALLOW_REALLOC_LAYER == 1, then the neural network can be expanded
neural_network = (network*) realloc(neural_network, (*num_layers + 1) * sizeof(network));

neural_network[i].bias = 0.5; 
neural_network[i].neurons = NULL;
neural_network[i].num_neurons = num_neurons;
neural_network[i].type = type;
neural_network[i].activation_function = &tanh;

*num_layers = *num_layers + 1;  

感谢您的帮助,恩。