C语言写出sofm 神经网络
时间: 2023-07-08 16:08:50 浏览: 56
SOFM(自组织特征映射)是一种无监督学习的神经网络,用于数据降维、聚类和可视化。下面是一个简单的 C 语言实现 SOFM 神经网络的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define INPUT_DIM 2 // 输入数据的维度
#define OUTPUT_DIM 3 // 输出数据的维度
#define MAX_ITER 1000 // 最大迭代次数
#define LEARNING_RATE 0.1 // 学习率
#define INIT_RADIUS 1 // 初始半径
// 计算欧几里得距离
double euclidean_distance(double *x, double *y, int dim) {
double dist = 0.0;
for (int i = 0; i < dim; i++) {
dist += pow(x[i] - y[i], 2);
}
return sqrt(dist);
}
// 初始化权重向量
void init_weights(double weights[OUTPUT_DIM][INPUT_DIM]) {
for (int i = 0; i < OUTPUT_DIM; i++) {
for (int j = 0; j < INPUT_DIM; j++) {
weights[i][j] = ((double) rand() / RAND_MAX) * 2 - 1;
}
}
}
// 更新权重向量
void update_weights(double weights[OUTPUT_DIM][INPUT_DIM], double input[INPUT_DIM], int winner, double radius, double learning_rate) {
for (int i = 0; i < OUTPUT_DIM; i++) {
double dist = abs(i - winner);
if (dist <= radius) {
double factor = exp(-pow(dist, 2) / (2 * pow(radius, 2)));
for (int j = 0; j < INPUT_DIM; j++) {
weights[i][j] += factor * learning_rate * (input[j] - weights[i][j]);
}
}
}
}
// 训练SOFM网络
void train_sofm(double inputs[][INPUT_DIM], int num_inputs, double weights[OUTPUT_DIM][INPUT_DIM]) {
for (int iter = 0; iter < MAX_ITER; iter++) {
// 随机选择一个输入样本
int idx = rand() % num_inputs;
double *input = inputs[idx];
// 计算最优神经元
double min_dist = INFINITY;
int winner = -1;
for (int i = 0; i < OUTPUT_DIM; i++) {
double dist = euclidean_distance(input, weights[i], INPUT_DIM);
if (dist < min_dist) {
min_dist = dist;
winner = i;
}
}
// 更新权重向量
double radius = INIT_RADIUS * exp(-iter / (double) MAX_ITER);
double learning_rate = LEARNING_RATE * exp(-iter / (double) MAX_ITER);
update_weights(weights, input, winner, radius, learning_rate);
}
}
// 测试SOFM网络
void test_sofm(double inputs[][INPUT_DIM], int num_inputs, double weights[OUTPUT_DIM][INPUT_DIM]) {
for (int i = 0; i < num_inputs; i++) {
double *input = inputs[i];
double min_dist = INFINITY;
int winner = -1;
for (int j = 0; j < OUTPUT_DIM; j++) {
double dist = euclidean_distance(input, weights[j], INPUT_DIM);
if (dist < min_dist) {
min_dist = dist;
winner = j;
}
}
printf("Input (%f, %f) belongs to neuron %d\n", input[0], input[1], winner);
}
}
int main() {
// 训练数据
double inputs[][INPUT_DIM] = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};
int num_inputs = sizeof(inputs) / sizeof(inputs[0]);
// 初始化权重向量
double weights[OUTPUT_DIM][INPUT_DIM];
init_weights(weights);
// 训练SOFM网络
train_sofm(inputs, num_inputs, weights);
// 测试SOFM网络
test_sofm(inputs, num_inputs, weights);
return 0;
}
```
该示例代码使用了随机梯度下降算法来训练 SOFM 神经网络,并使用欧几里得距离来计算神经元之间的距离。在训练过程中,每次随机选择一个输入样本,并通过计算最优神经元来更新权重向量。在测试过程中,对于每个输入样本,找到最近的神经元,并输出其编号。