将函数传递给结构数组内的指针
Passing a function to a pointer inside a struct array
我正在尝试使用 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;
我得到以下编译错误:
error: invalid type argument of '->' (have '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);
}
事实证明这只是函数 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;
谢谢你的帮助,Unn。
我正在尝试使用 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;
我得到以下编译错误:
error: invalid type argument of '->' (have '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);
}
事实证明这只是函数 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;
谢谢你的帮助,Unn。