0
下面的代碼是我對時間差異學習的實現。使用TD算法的代理與使用迷你最大程序玩遊戲的代理玩超過750,000個遊戲,但問題是TD代理不學習......這種實現有什麼問題?Java中時間差異學習的實現
當代理選擇下一步移動時,會調用updateToNextState。
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;
}
我用this link爲指導。我已經嘗試了ALPHA &測試版的不同值,隱藏的神經元的數量。資格痕跡初始化爲0.
當我們看不到整個代碼時,真的很難調試。這是西洋雙陸棋嗎?你確定你的遊戲代碼沒有錯嗎?另外,我會分開關注點。將神經網絡代碼與TD學習代碼分開,並且還將遊戲邏輯代碼分開。然後,我也可以分別驗證代碼段。對我來說,就像你不知道你的錯誤在哪裏。 (我也會在TD(lambda)之前實現TD(0)。請看[Sutton&Barto] http://webdocs.cs.ualberta.ca/~sutton/book/the-book.html)第6章。 – oysteijo
這些已經分開。我將它用於兩種不同的遊戲(跳棋和四合一),並且我確信遊戲中沒有錯誤。如果遊戲結束,我用獎勵(1,0,0爲贏; 0,1,0爲輸; 0,0,1爲抽獎)調用updateToNextState方法,否則通常在下一個狀態輸出。並且要知道什麼是一個狀態的當前值,我稱之爲其他方法,通過網絡給出狀態的輸出而不更新網絡。 – Asqan