使用C语言实现神经网络进行数字识别

要求:

1、对C语言基本语法已经完全掌握

2、对机器学习的底层原理认识清晰

训练数据

// 训练数据
    double inputs[5][ROWS * COLS] = {
        {0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0},
        {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0},
        {0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
        {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0},
    };
    int labels[5] = { 1,2,3,4,5 };
    
// 测试数据
    double test_inputs[5][ROWS * COLS] = {
        {0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0},
        {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0},
    };
    int test_labels[5] = { 4, 2, 3, 5, 5 };

完整代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define ROWS 5
#define COLS 5
#define NUM_CLASSES 5
#define LEARNING_RATE 0.01
#define EPOCHS 6000

// sigmoid激活函数
double sigmoid(double x) {
    return 1.0 / (1.0 + exp(-x));
}

// softmax分类函数
void softmax(double* output, int n) {
    double sum = 0.0;
    for (int i = 0; i < n; i++) {
        sum += exp(output[i]);
    }
    for (int i = 0; i < n; i++) {
        output[i] = exp(output[i]) / sum;
    }
}

// 前向传播函数
void forward(double* input, double* weights, double* output) {
    for (int i = 0; i < NUM_CLASSES; i++) {
        double sum = 0.0;
        for (int j = 0; j < ROWS * COLS; j++) {
            sum += input[j] * weights[i * ROWS * COLS + j];
        }
        output[i] = sigmoid(sum);
    }
    softmax(output, NUM_CLASSES);
}

// 反向传播函数
void backward(double* input, double* weights, double* output, int label) {
    double delta[NUM_CLASSES];
    for (int i = 0; i < NUM_CLASSES; i++) {
        delta[i] = (i == label ? 1.0 : 0.0) - output[i];
    }
    for (int i = 0; i < NUM_CLASSES; i++) {
        for (int j = 0; j < ROWS * COLS; j++) {
            weights[i * ROWS * COLS + j] += LEARNING_RATE * delta[i] * input[j];
        }
    }
}

// 训练函数
void train(double* inputs, int* labels, double* weights, int num_examples) {
    for (int epoch = 0; epoch < EPOCHS; epoch++) {
        double loss = 0.0;
        for (int i = 0; i < num_examples; i++) {
            double output[NUM_CLASSES];
            forward(&inputs[i * ROWS * COLS], weights, output);
            backward(&inputs[i * ROWS * COLS], weights, output, labels[i]);
            loss -= log(output[labels[i]]);
        }
        loss /= num_examples;
        printf("Epoch %d\n", epoch + 1, loss);
    }
}

// 测试函数
void test(double* inputs, int* labels, double* weights, int num_examples) {
    int num_correct = 0;
    for (int i = 0; i < num_examples; i++) {
        double output[NUM_CLASSES];
        forward(&inputs[i * ROWS * COLS], weights, output);
        int prediction = 0;
        for (int j = 1; j < NUM_CLASSES; j++) {
            if (output[j] > output[prediction]) {
                prediction = j;
            }
        }
        if (prediction == labels[i]) {
            num_correct++;
        }
        printf("Prediction = %d\n", prediction);
    }
    double accuracy = (double)num_correct / num_examples;

    printf("Test Accuracy = %f\n", accuracy);
}

int main() {
    // 训练数据
    double inputs[5][ROWS * COLS] = {
        {0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0},
        {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0},
        {0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0},
        {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0},
    };
    int labels[5] = { 1,2,3,4,5 };

    // 初始化权重
    double weights[NUM_CLASSES * ROWS * COLS];
    for (int i = 0; i < NUM_CLASSES * ROWS * COLS; i++) {
        weights[i] = (double)rand() / RAND_MAX - 0.5;
    }

    // 训练模型
    train((double*)inputs, labels, weights, 5);

    // 测试模型
    double test_inputs[5][ROWS * COLS] = {
        {0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0},
        {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1},
        {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0},
        {0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0},
        {0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0},
    };
    int test_labels[5] = { 4, 2, 3, 5, 5 };
    test((double*)test_inputs, test_labels, weights, 5);

    return 0;
    
}

### Gradio 深度定制化开发指南 #### 自定义组件和界面设计 Gradio 提供了一套灵活的接口用于创建自定义组件,允许开发者根据需求扩展平台的功能。对于希望实现更复杂交互逻辑的应用场景而言,这无疑是一个重要的特性[^1]。 为了增加新的输入或输出类型,可以继承 `gr.components.Component` 类并重写相应的方法来处理数据传递与渲染过程。例如: ```python import gradio as gr class CustomComponent(gr.inputs.BaseInput): def __init__(self, **kwargs): super().__init__(**kwargs) @classmethod def from_params(cls, params=None): return cls() def preprocess(self, x): # 处理前端传来的原始数据 pass def postprocess(self, y): # 将预测结果转换成可展示的形式 pass ``` #### 修改源码以实现高级功能 当现有的API无法满足特定业务需求时,则可能涉及到对Gradio本身的修改工作。这种情况下建议先熟悉项目的整体架构以及核心模块的工作原理,在此基础上再考虑如何安全有效地做出改动。 通常来说,深入理解官方文档和技术社区中的讨论是非常有帮助的;同时也要注意保持代码风格的一致性和良好的测试覆盖率,确保任何变更都不会破坏现有功能稳定性。 #### 实现高级特性的具体方法 针对某些特殊应用场景下的性能优化或者新特性集成,可以通过调整配置文件、利用环境变量控制行为等方式来进行无侵入式的改进尝试。如果确实有必要直接编辑源代码的话,应该遵循开源软件贡献的最佳实践,比如提交Pull Request给上游仓库以便让更多的人受益于这些增强措施。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值