C语言 构建som网络,其二维神经元平面为10×10=100个神经元初始化权值为负一到正一之间的小数,输入节点为五维节点,按照计算欧式距离的方式输入十个不同的样本,要求显示对应激活神经元节点的序号,并修改对应神经元向量的值,使其更靠近唯一对应的输入样本 写代码
时间: 2024-03-07 10:46:42 浏览: 35
用C语言实现的神经网络SOM算法
好的,以下是一个简单的C语言代码实现SOM网络的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SOM_SIZE 10
#define INPUT_SIZE 5
#define LEARNING_RATE 0.1
#define SIGMA 5
typedef struct {
double vec[INPUT_SIZE];
int x;
int y;
} node;
double rand_double(double min, double max) {
return (double)rand() / RAND_MAX * (max - min) + min;
}
double euclidean_distance(node n1, node n2) {
double sum = 0.0;
for (int i = 0; i < INPUT_SIZE; i++) {
sum += pow(n1.vec[i] - n2.vec[i], 2);
}
return sqrt(sum);
}
double neighborhood(node n1, node n2, double sigma) {
double distance = pow(n1.x - n2.x, 2) + pow(n1.y - n2.y, 2);
return exp(-distance / (2 * sigma * sigma));
}
int get_winner(node input, node som[SOM_SIZE][SOM_SIZE]) {
int winner_x = 0;
int winner_y = 0;
double min_distance = euclidean_distance(input, som[winner_x][winner_y]);
for (int x = 0; x < SOM_SIZE; x++) {
for (int y = 0; y < SOM_SIZE; y++) {
double distance = euclidean_distance(input, som[x][y]);
if (distance < min_distance) {
min_distance = distance;
winner_x = x;
winner_y = y;
}
}
}
return winner_x * SOM_SIZE + winner_y; // 一维序号表示
}
void update_weights(node input, node som[SOM_SIZE][SOM_SIZE], int winner, double learning_rate, double sigma) {
int winner_x = winner / SOM_SIZE;
int winner_y = winner % SOM_SIZE;
for (int x = 0; x < SOM_SIZE; x++) {
for (int y = 0; y < SOM_SIZE; y++) {
double neighborhood_factor = neighborhood(som[winner_x][winner_y], som[x][y], sigma);
for (int i = 0; i < INPUT_SIZE; i++) {
som[x][y].vec[i] += learning_rate * neighborhood_factor * (input.vec[i] - som[x][y].vec[i]);
}
}
}
}
int main() {
node som[SOM_SIZE][SOM_SIZE];
srand(1234);
for (int x = 0; x < SOM_SIZE; x++) {
for (int y = 0; y < SOM_SIZE; y++) {
for (int i = 0; i < INPUT_SIZE; i++) {
som[x][y].vec[i] = rand_double(-1, 1);
}
som[x][y].x = x;
som[x][y].y = y;
}
}
node input[10];
input[0].vec[0] = 0.2; input[0].vec[1] = 0.4; input[0].vec[2] = 0.1; input[0].vec[3] = 0.9; input[0].vec[4] = 0.5;
input[1].vec[0] = 0.8; input[1].vec[1] = 0.1; input[1].vec[2] = 0.7; input[1].vec[3] = 0.2; input[1].vec[4] = 0.3;
input[2].vec[0] = 0.1; input[2].vec[1] = 0.5; input[2].vec[2] = 0.6; input[2].vec[3] = 0.4; input[2].vec[4] = 0.7;
input[3].vec[0] = 0.3; input[3].vec[1] = 0.7; input[3].vec[2] = 0.2; input[3].vec[3] = 0.8; input[3].vec[4] = 0.9;
input[4].vec[0] = 0.6; input[4].vec[1] = 0.2; input[4].vec[2] = 0.5; input[4].vec[3] = 0.1; input[4].vec[4] = 0.4;
input[5].vec[0] = 0.9; input[5].vec[1] = 0.3; input[5].vec[2] = 0.8; input[5].vec[3] = 0.7; input[5].vec[4] = 0.1;
input[6].vec[0] = 0.4; input[6].vec[1] = 0.8; input[6].vec[2] = 0.2; input[6].vec[3] = 0.5; input[6].vec[4] = 0.6;
input[7].vec[0] = 0.7; input[7].vec[1] = 0.6; input[7].vec[2] = 0.9; input[7].vec[3] = 0.3; input[7].vec[4] = 0.2;
input[8].vec[0] = 0.5; input[8].vec[1] = 0.1; input[8].vec[2] = 0.3; input[8].vec[3] = 0.6; input[8].vec[4] = 0.8;
input[9].vec[0] = 0.2; input[9].vec[1] = 0.9; input[9].vec[2] = 0.6; input[9].vec[3] = 0.4; input[9].vec[4] = 0.1;
for (int i = 0; i < 10; i++) {
int winner = get_winner(input[i], som);
printf("Winner node: (%d, %d)\n", winner / SOM_SIZE, winner % SOM_SIZE);
update_weights(input[i], som, winner, LEARNING_RATE, SIGMA);
}
return 0;
}
```
这段代码实现了一个10x10的SOM网络,输入节点为5维向量,包含10个不同的输入样本。在每一轮训练中,程序会计算每个输入样本与神经元节点之间的欧式距离,找到距离最近的神经元节点,并输出其所在位置的序号。然后,程序会根据学习率和邻域函数来更新对应神经元节点的向量值。
阅读全文