gpt4 book ai didi

c - 使用小批量时如何更新权重?

转载 作者:太空宇宙 更新时间:2023-11-04 03:13:13 24 4
gpt4 key购买 nike

我正在尝试对我的神经网络实现小批量训练,而不是对每个训练样本更新权重的“在线”随机方法。

我用 C 语言开发了一个有点新手的神经网络,我可以通过它调整每层中的神经元数量、激活函数等。这有助于我理解神经网络。我已经在 mnist 数据集上训练了网络,但是它需要大约 200 个 epochs 才能在训练集上做 20% 的错误率,这对我来说很差。我目前正在使用在线随机梯度体面来训练网络。我想尝试的是改用小批量。我理解这样一个概念,即在传播回错误之前,我必须从每个训练样本中累积和平均错误。当我想计算我必须对权重所做的更改时,我的问题就来了。为了更好地解释这一点,请考虑一个非常简单的感知器模型。一个输入,一个隐藏层,一个输出。为了计算我需要对输入和隐藏单元之间的权重进行的更改,我将使用以下等式:

∂C/∂w1=∂C/∂O*∂O/∂h*∂h/∂w1

如果你做偏导数你会得到:

∂C/∂w1=(输出-预期答案)(w2)(输入)

现在这个公式表示您需要将反向传播误差乘以输入。对于有意义的在线随机训练,因为每次权重更新使用 1 个输入。对于小批量训练,您使用了很多输入,那么错误会乘以哪个输入?我希望你能帮助我。

void propogateBack(void){


//calculate 6C/6G
for (count=0;count<network.outputs;count++){
network.g_error[count] = derive_cost((training.answer[training_current])-(network.g[count]));
}



//calculate 6G/6O
for (count=0;count<network.outputs;count++){
network.o_error[count] = derive_activation(network.g[count])*(network.g_error[count]);
}


//calculate 6O/6S3
for (count=0;count<network.h3_neurons;count++){
network.s3_error[count] = 0;
for (count2=0;count2<network.outputs;count2++){
network.s3_error[count] += (network.w4[count2][count])*(network.o_error[count2]);
}
}


//calculate 6S3/6H3
for (count=0;count<network.h3_neurons;count++){
network.h3_error[count] = (derive_activation(network.s3[count]))*(network.s3_error[count]);
}


//calculate 6H3/6S2
network.s2_error[count] = = 0;
for (count=0;count<network.h2_neurons;count++){
for (count2=0;count2<network.h3_neurons;count2++){
network.s2_error[count] = += (network.w3[count2][count])*(network.h3_error[count2]);
}
}



//calculate 6S2/6H2
for (count=0;count<network.h2_neurons;count++){
network.h2_error[count] = (derive_activation(network.s2[count]))*(network.s2_error[count]);
}


//calculate 6H2/6S1
network.s1_error[count] = 0;
for (count=0;count<network.h1_neurons;count++){
for (count2=0;count2<network.h2_neurons;count2++){
buffer += (network.w2[count2][count])*network.h2_error[count2];
}
}


//calculate 6S1/6H1
for (count=0;count<network.h1_neurons;count++){
network.h1_error[count] = (derive_activation(network.s1[count]))*(network.s1_error[count]);

}


}





void updateWeights(void){


//////////////////w1
for(count=0;count<network.h1_neurons;count++){
for(count2=0;count2<network.inputs;count2++){
network.w1[count][count2] -= learning_rate*(network.h1_error[count]*network.input[count2]);
}

}





//////////////////w2
for(count=0;count<network.h2_neurons;count++){
for(count2=0;count2<network.h1_neurons;count2++){
network.w2[count][count2] -= learning_rate*(network.h2_error[count]*network.s1[count2]);
}

}



//////////////////w3
for(count=0;count<network.h3_neurons;count++){
for(count2=0;count2<network.h2_neurons;count2++){
network.w3[count][count2] -= learning_rate*(network.h3_error[count]*network.s2[count2]);
}

}


//////////////////w4
for(count=0;count<network.outputs;count++){
for(count2=0;count2<network.h3_neurons;count2++){
network.w4[count][count2] -= learning_rate*(network.o_error[count]*network.s3[count2]);
}

}
}

我附上的代码是我如何进行在线随机更新的。正如您在 updateWeights() 函数中看到的那样,权重更新基于输入值(取决于输入的样本)和隐藏单元值(也取决于输入的输入样本值)。所以当我有我传播的小批量平均梯度时,我将如何更新权重?我使用哪些输入值?

最佳答案

好的,我想通了。当使用小批量时,你不应该累积和平均网络输出的错误。每个训练示例错误都会像往常一样传播回来,除了不是更新权重,而是累积对每个权重所做的更改。当您循环遍历小批量时,您可以对累积进行平均并相应地更改权重。

我的印象是,在使用小批量时,在循环遍历小批量之前,您不必传回任何错误。我错了,你仍然需要这样做,唯一的区别是你只在循环了你的小批量大小后才更新权重。

关于c - 使用小批量时如何更新权重?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54332566/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com