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.

+2

當我們看不到整個代碼時,真的很難調試。這是西洋雙陸棋嗎?你確定你的遊戲代碼沒有錯嗎?另外,我會分開關注點。將神經網絡代碼與TD學習代碼分開,並且還將遊戲邏輯代碼分開。然後,我也可以分別驗證代碼段。對我來說,就像你不知道你的錯誤在哪裏。 (我也會在TD(lambda)之前實現TD(0)。請看[Sutton&Barto] http://webdocs.cs.ualberta.ca/~sutton/book/the-book.html)第6章。 – oysteijo

+0

這些已經分開。我將它用於兩種不同的遊戲(跳棋和四合一),並且我確信遊戲中沒有錯誤。如果遊戲結束,我用獎勵(1,0,0爲贏; 0,1,0爲輸; 0,0,1爲抽獎)調用updateToNextState方法,否則通常在下一個狀態輸出。並且要知道什麼是一個狀態的當前值,我稱之爲其他方法,通過網絡給出狀態的輸出而不更新網絡。 – Asqan

回答

0

問題主要是你不能調整你的神經網絡函數逼近器,並且從你所說的我可以假設「它不學習」,意味着算法不會收斂。

當我們一起使用TD和NN時,會發生這種情況。之前這發生在我身上,我搜索了很長時間。我學到的教訓如下:

根據理查德薩頓:不要嘗試使用神經網絡作爲函數逼近器,與TD方法一起,除非您知道正好如何調整您的神經網絡。否則,這會造成很多問題。

要了解更多信息,請在YouTube上查找薩頓的話題。