写一个神经网络学习的C语言
时间: 2024-03-09 12:50:29 浏览: 51
当然可以,请看以下的 C 语言代码实现神经网络学习:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define LEARNING_RATE 0.1 // 学习率
#define EPOCHS 1000 // 训练轮数
#define INPUT_SIZE 2 // 输入层大小
#define HIDDEN_SIZE 4 // 隐藏层大小
#define OUTPUT_SIZE 1 // 输出层大小
// 激活函数
float sigmoid(float x) {
return 1.0 / (1.0 + exp(-x));
}
// 前向传播
void forward(float input[], float hidden[], float output[], float weights_ih[][HIDDEN_SIZE], float weights_ho[][OUTPUT_SIZE], float bias_h[], float bias_o[]) {
// 计算隐藏层
for(int i = 0; i < HIDDEN_SIZE; i++) {
hidden[i] = 0.0;
for(int j = 0; j < INPUT_SIZE; j++) {
hidden[i] += input[j] * weights_ih[j][i];
}
hidden[i] += bias_h[i];
hidden[i] = sigmoid(hidden[i]);
}
// 计算输出层
for(int i = 0; i < OUTPUT_SIZE; i++) {
output[i] = 0.0;
for(int j = 0; j < HIDDEN_SIZE; j++) {
output[i] += hidden[j] * weights_ho[j][i];
}
output[i] += bias_o[i];
output[i] = sigmoid(output[i]);
}
}
// 反向传播
void backward(float input[], float hidden[], float output[], float target, float weights_ih[][HIDDEN_SIZE], float weights_ho[][OUTPUT_SIZE], float bias_h[], float bias_o[]) {
float error_o[OUTPUT_SIZE];
float error_h[HIDDEN_SIZE];
// 计算输出层误差
for(int i = 0; i < OUTPUT_SIZE; i++) {
error_o[i] = target - output[i];
}
// 计算隐藏层误差
for(int i = 0; i < HIDDEN_SIZE; i++) {
error_h[i] = 0.0;
for(int j = 0; j < OUTPUT_SIZE; j++) {
error_h[i] += error_o[j] * weights_ho[i][j];
}
error_h[i] *= hidden[i] * (1 - hidden[i]);
}
// 更新权重和偏置
for(int i = 0; i < HIDDEN_SIZE; i++) {
for(int j = 0; j < OUTPUT_SIZE; j++) {
weights_ho[i][j] += LEARNING_RATE * error_o[j] * hidden[i];
}
}
for(int i = 0; i < INPUT_SIZE; i++) {
for(int j = 0; j < HIDDEN_SIZE; j++) {
weights_ih[i][j] += LEARNING_RATE * error_h[j] * input[i];
}
}
for(int i = 0; i < HIDDEN_SIZE; i++) {
bias_h[i] += LEARNING_RATE * error_h[i];
}
for(int i = 0; i < OUTPUT_SIZE; i++) {
bias_o[i] += LEARNING_RATE * error_o[i];
}
}
int main() {
float input[][INPUT_SIZE] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}}; // 输入数据
float target[] = {0, 1, 1, 0}; // 目标数据
float hidden[HIDDEN_SIZE]; // 隐藏层输出
float output[OUTPUT_SIZE]; // 输出层输出
float weights_ih[INPUT_SIZE][HIDDEN_SIZE]; // 输入层到隐藏层的权重
float weights_ho[HIDDEN_SIZE][OUTPUT_SIZE]; // 隐藏层到输出层的权重
float bias_h[HIDDEN_SIZE]; // 隐藏层偏置
float bias_o[OUTPUT_SIZE]; // 输出层偏置
// 初始化权重和偏置
for(int i = 0; i < INPUT_SIZE; i++) {
for(int j = 0; j < HIDDEN_SIZE; j++) {
weights_ih[i][j] = (float)rand() / (float)RAND_MAX; // 随机初始化权重
}
}
for(int i = 0; i < HIDDEN_SIZE; i++) {
for(int j = 0; j < OUTPUT_SIZE; j++) {
weights_ho[i][j] = (float)rand() / (float)RAND_MAX; // 随机初始化权重
}
}
for(int i = 0; i < HIDDEN_SIZE; i++) {
bias_h[i] = (float)rand() / (float)RAND_MAX; // 随机初始化偏置
}
for(int i = 0; i < OUTPUT_SIZE; i++) {
bias_o[i] = (float)rand() / (float)RAND_MAX; // 随机初始化偏置
}
// 训练
for(int epoch = 0; epoch < EPOCHS; epoch++) {
float error = 0.0;
for(int i = 0; i < 4; i++) {
forward(input[i], hidden, output, weights_ih, weights_ho, bias_h, bias_o);
backward(input[i], hidden, output, target[i], weights_ih, weights_ho, bias_h, bias_o);
error += (target[i] - output[0]) * (target[i] - output[0]);
}
error /= 4;
printf("Epoch %d, Error = %.4f\n", epoch+1, error);
}
// 测试
printf("\nTesting...\n");
for(int i = 0; i < 4; i++) {
forward(input[i], hidden, output, weights_ih, weights_ho, bias_h, bias_o);
printf("Input = %d %d, Output = %.4f\n", (int)input[i][0], (int)input[i][1], output[0]);
}
return 0;
}
```
在上述代码中,我们使用了一个简单的神经网络来解决异或问题。该神经网络包含一个输入层、一个隐藏层和一个输出层,其中隐藏层和输出层都采用了 sigmoid 激活函数。我们使用随机初始化的权重和偏置来训练神经网络,并通过反向传播算法来更新权重和偏置。训练完成后,我们在测试集上进行测试,并输出测试结果。
阅读全文