#include "cnn.h" // 将原始矩阵复制到填充后的矩阵中央 float* expand(const float* old_matrix, u8 old_matrix_length, u8 layer){ float* new_matrix = (float *)malloc(sizeof(float)*layer*(old_matrix_length+2)*(old_matrix_length+2)); memset(new_matrix, 0, sizeof(float)*layer*(old_matrix_length+2)*(old_matrix_length+2)); for(u8 l=0; l < layer; l++){ for (u8 i = 0; i < old_matrix_length; i++) { for (u8 j = 0; j < old_matrix_length; j++) { new_matrix[(i + 1) * (old_matrix_length+2) + (j + 1) + l * (old_matrix_length+2) * (old_matrix_length+2)] = old_matrix[i * old_matrix_length + j + l * (old_matrix_length) * (old_matrix_length)]; } } } return new_matrix; } //model 模型名字 //input_matrix 输入图像 //input_matrix_length 输入图像的边长:102 //c_rl 输出图像的边长:100 //返回卷积的结果 float* convolution(Model model_w, Model model_b, const float* input_matrix, u8 input_matrix_length){ // 初始化卷积层参数 u8 im_l = input_matrix_length; u8 cr_l = input_matrix_length - 2; float conv_temp; // 临时变量,用于存储卷积计算的中间结果 float* conv_rlst = (float *) malloc(sizeof (float) * model_w.num_kernels * (cr_l * cr_l)); memset(conv_rlst, 0, sizeof (float) * model_w.num_kernels * (cr_l * cr_l)); // 遍历30个卷积核(假设有30个通道) for(u8 l=0;l 0) conv_rlst[(n*(cr_l*cr_l)) + (row*cr_l) + (col)] = conv_temp; // 如果卷积结果大于0,存入结果数组 else conv_rlst[(n*(cr_l*cr_l)) + (row*cr_l) + (col)] = 0; // 否则存入0 } } } } return conv_rlst; } //num_kernels 卷积核的个数:32 //area 池化的面积:2*2 //input_matrix 输入图像 //input_matrix_length 输入图像的边长:100 //输出图像的边长:50 //返回池化的结果 float* pooling(Model model_w, const float* input_matrix, u8 input_matrix_length){ u8 im_l = input_matrix_length; float pool_temp = 0; // 临时变量,用于存储池化操作的最大值 float* pool_rslt = (float *) malloc(sizeof (float)*model_w.num_kernels*im_l*im_l); memset(pool_rslt, 0, sizeof (float)*model_w.num_kernels*im_l*im_l); // 遍历30个通道(与卷积核数量相同) for(u8 n=0; n 0) // affine1_rslt[n] = affine1_temp; // 如果结果大于0,存入结果数组 // else // affine1_rslt[n] = 0; // 否则存入0 // } // // // // float *affine2_w; // 指向第二个全连接层(输出层)权重的内存地址的指针 // float *affine2_b; // 指向第二个全连接层(输出层)偏置的内存地址的指针 // float affine2_temp; // 临时变量,用于存储输出层的中间结果 // affine2_param_init(); // 初始化输出层参数 // // float affine2_rslt[10]; // 存储输出层的结果(假设输出层有10个神经元) // //// 比较输出层的最大值 // float temp = -100; // 用于存储最大值的临时变量,初始化为一个非常小的值 // int predict_num; // 用于存储预测的数字(对应最大值的索引) // //// 遍历10个输出神经元(假设有10个类别) // for(int n=0; n<10; n++) // { // affine2_temp = 0; // 当前神经元的输出初始化为0 // // // 进行矩阵乘法,将隐藏层的输出与输出层权重进行点积 // for(int i=0; i<100; i++) // { // affine2_temp = affine2_temp + affine2_w[i+100*n] * affine1_rslt[i]; // } // // // 加上对应神经元的偏置 // affine2_temp = affine2_temp + affine2_b[n]; // affine2_rslt[n] = affine2_temp; // 存储输出层的结果 // // // 寻找最大值 // if(temp <= affine2_rslt[n]) // { // temp = affine2_rslt[n]; // 更新最大值 // predict_num = n; // 记录最大值对应的类别索引 // } // } return 0; }