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

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

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