时态差分学习在Java中的实现
下面的代码是我对时差学习的实现。使用TD算法的代理与使用mini-max程序玩游戏的代理进行了超过750000场游戏,但问题是TD代理不学习。。。这种实现有什么问题 当代理选择下一步移动时,将调用updateToNextState时态差分学习在Java中的实现,java,machine-learning,artificial-intelligence,neural-network,temporal-difference,Java,Machine Learning,Artificial Intelligence,Neural Network,Temporal Difference,下面的代码是我对时差学习的实现。使用TD算法的代理与使用mini-max程序玩游戏的代理进行了超过750000场游戏,但问题是TD代理不学习。。。这种实现有什么问题 当代理选择下一步移动时,将调用updateToNextState public void updateToNextState(int[] currentState, double[] nextStateOutput) { double[] outputOfNext = nextStateOutput; double[
public void updateToNextState(int[] currentState, double[] nextStateOutput) {
double[] outputOfNext = nextStateOutput;
double[] outputOfCurrent = getOutput(currentState);
double[] error = getDifferenceOfOutputs(outputOfNext, outputOfCurrent);
lastHandledState = currentState;
for (int j = 0; j < layers[HIDDEN].neurons.length; j++) {
for (int k = 0; k < layers[OUTPUT].neurons.length; k++) {
double toBeUpdatedValueForJToK = BETA * error[k]
* eligibilityTraces.getEjk(j, k);
layers[HIDDEN].neurons[j].updateWeightToNeuron(
layers[OUTPUT].neurons[k].getNeuronId(),
toBeUpdatedValueForJToK);
for (int i = 0; i < layers[INPUT].neurons.length; i++) {
double toBeUpdatedValueForIToJ = ALPHA * error[k]
* eligibilityTraces.getEijk(i, j, k);
layers[INPUT].neurons[i].updateWeightToNeuron(
layers[HIDDEN].neurons[j].getNeuronId(),
toBeUpdatedValueForIToJ);
}
}
}
updateEligibilityTraces(currentState);
}
private void updateEligibilityTraces(int[] currentState) {
// to ensure that the values in neurons are originated from current
// state
feedForward(currentState);
for (int j = 0; j < layers[HIDDEN].neurons.length; j++) {
for (int k = 0; k < layers[OUTPUT].neurons.length; k++) {
double toBeUpdatedValueForJK = gradient(layers[OUTPUT].neurons[k])
* layers[HIDDEN].neurons[j].output;
eligibilityTraces.updateEjk(j, k, toBeUpdatedValueForJK);
for (int i = 0; i < layers[INPUT].neurons.length; i++) {
double toBeUpdatedValueForIJK = gradient(layers[OUTPUT].neurons[k])
* gradient(layers[HIDDEN].neurons[j])
* layers[INPUT].neurons[i].output
* layers[HIDDEN].neurons[j]
.getWeightToNeuron(layers[OUTPUT].neurons[k]
.getNeuronId());
eligibilityTraces.updateEijk(i, j, k,
toBeUpdatedValueForIJK);
}
}
}
}
private double gradient(Neuron neuron) {
return neuron.output * (1 - neuron.output);
}
public void updateToNextWhenOpponentEndsGame(double[] outputOfEndState) {
updateToNextState(lastHandledState, outputOfEndState);
}
private double[] getDifferenceOfOutputs(double[] outputNext,
double[] outputCurrent) {
double[] differencesVector = new double[outputNext.length];
for (int i = 0; i < outputNext.length; i++) {
double difference = outputNext[i] - outputCurrent[i];
differencesVector[i] = difference;
}
return differencesVector;
}
public void updateToNextState(int[]currentState,double[]NextState输出){
double[]OutputFNext=nextStateOutput;
double[]OutputOfcCurrent=getOutput(currentState);
double[]error=GetDifferenceFoutput(outputOfNext,outputOfCurrent);
lastHandledState=当前状态;
对于(int j=0;j
我用它作为指导线。我尝试了不同的ALPHA和BETA值,即隐藏神经元的数量。资格跟踪已初始化为0 问题主要在于你不能调整你的神经网络函数逼近器,根据你所说的,我可以假设“它不学习”,这意味着算法不收敛 当我们同时使用TD和NN时,就会发生这种情况。这件事以前发生在我身上,我找了很长时间。我学到的教训如下: Richard Sutton表示:不要尝试将神经网络与TD方法一起用作函数逼近器,除非你确切地知道如何调整你的神经网络。否则,这将导致很多问题
要了解更多信息,请在youtube上找到Sutton的演讲。当我们看不到完整的代码时,我们真的很难调试。这是双陆棋吗?你确定你的游戏代码没有错吗?另外,我会把这些顾虑分开一点。将神经网络代码与TD学习代码分离,并保持游戏逻辑代码也分离。然后我还可以单独验证代码片段。在我看来,你好像不知道自己身在何处。(在我实现TD(lambda)之前,我也会实现TD(0)。看看[Sutton&Barto])第6章。它们已经分开了。我将它用于两种不同的游戏(跳棋和四连击),我确信游戏中没有bug。如果游戏结束,我调用updateToNextState方法进行奖励(1,0,0表示赢;0,1,0表示输;0,0,1表示平局),否则正常情况下会输出下一个状态。为了知道什么是状态的当前值,我调用了另一种方法,它通过网络给出状态的输出,而不更新网络。