ANN: 学习向量量化未能正常工作

希望这里有人能帮我:我正在尝试实现一个神经网络来寻找数据的聚类,这些数据以二维聚类的形式呈现。我试图按照维基百科上描述的标准算法进行操作:我寻找每个数据点的最小距离,并将这个神经元的权重更新为朝向该数据点。我会在总距离足够小时停止这个过程。

我的结果是找到了大部分聚类,但在一些聚类上出现了错误,尽管它计算了一个恒定的距离,但不再收敛。我的错误出在哪里?

typedef struct{    double x;    double y;}Data;typedef struct{    double x;    double y;}Neuron;typedef struct{    size_t numNeurons;    Neuron* neurons;}Network;int main(void){    srand(time(NULL));    Data trainingData[1000];    size_t sizeTrainingData = 0;    size_t sizeClasses = 0;    Network network;    getData(trainingData, &sizeTrainingData, &sizeClasses);    initializeNetwork(&network, sizeClasses);    normalizeData(trainingData, sizeTrainingData);    train(&network, trainingData, sizeTrainingData);    return 0;}void train(Network* network, Data trainingData[], size_t sizeTrainingData){    for(int epoch=0; epoch<TRAINING_EPOCHS; ++epoch){        double learningRate = getLearningRate(epoch);        double totalDistance = 0;        for(int i=0; i<sizeTrainingData; ++i){            Data currentData = trainingData[i];            int winningNeuron = 0;            totalDistance += findWinningNeuron(network, currentData, &winningNeuron);            //更新权重            network->neurons[i].x += learningRate * (currentData.x - network->neurons[i].x);            network->neurons[i].y += learningRate * (currentData.y - network->neurons[i].y);        }        if(totalDistance<MIN_TOTAL_DISTANCE) break;    }}double getLearningRate(int epoch){    return LEARNING_RATE * exp(-log(LEARNING_RATE/LEARNING_RATE_MIN_VALUE)*((double)epoch/TRAINING_EPOCHS));}double findWinningNeuron(Network* network, Data data, int* winningNeuron){    double smallestDistance = 9999;    for(unsigned int currentNeuronIndex=0; currentNeuronIndex<network->numNeurons; ++currentNeuronIndex){        Neuron neuron = network->neurons[currentNeuronIndex];        double distance = sqrt(pow(data.x-neuron.x,2)+pow(data.y-neuron.y,2));        if(distance<smallestDistance){            smallestDistance = distance;            *winningNeuron = currentNeuronIndex;        }    }    return smallestDistance;}

initializeNetwork(...) 用-1到1之间的随机权重初始化所有神经元。normalizeData(...) 以最大值为1的方式进行归一化处理。

一个例子:如果我向网络输入大约50个(归一化后的)数据点,这些数据点分成3个聚类,剩余的totaldistance保持在约7.3。当我检查应该代表聚类中心的神经元位置时,有两个是完美的,一个在聚类的边缘。难道算法不应该将其更多地移向中心吗?我多次重复了这个算法,输出总是相似的(在完全相同的错误点上)


回答:

你的代码看起来不像是LVQ,特别是你从未使用获胜的神经元,而你应该只移动这个神经元

void train(Network* network, Data trainingData[], size_t sizeTrainingData){    for(int epoch=0; epoch<TRAINING_EPOCHS; ++epoch){        double learningRate = getLearningRate(epoch);        double totalDistance = 0;        for(int i=0; i<sizeTrainingData; ++i){            Data currentData = trainingData[i];            int winningNeuron = 0;            totalDistance += findWinningNeuron(network, currentData, &winningNeuron);            //更新权重            network->neurons[i].x += learningRate * (currentData.x - network->neurons[i].x);            network->neurons[i].y += learningRate * (currentData.y - network->neurons[i].y);        }        if(totalDistance<MIN_TOTAL_DISTANCE) break;    }}

你要移动的神经元在winningNeuron中,但你更新的是第i个神经元,而i实际上是在遍历训练样本,我很惊讶你没有超出内存(network->neurons应该小于sizeTrainingData)。我猜你原本的意思是这样的

void train(Network* network, Data trainingData[], size_t sizeTrainingData){    for(int epoch=0; epoch<TRAINING_EPOCHS; ++epoch){        double learningRate = getLearningRate(epoch);        double totalDistance = 0;        for(int i=0; i<sizeTrainingData; ++i){            Data currentData = trainingData[i];            int winningNeuron = 0;            totalDistance += findWinningNeuron(network, currentData, &winningNeuron);            //更新权重            network->neurons[winningNeuron].x += learningRate * (currentData.x - network->neurons[winningNeuron].x);            network->neurons[winningNeuron].y += learningRate * (currentData.y - network->neurons[winningNeuron].y);        }        if(totalDistance<MIN_TOTAL_DISTANCE) break;    }}

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注