Java 深度Q模型不学习
我正试图用我自己的ANN实现,通过深度Q学习来解决这个问题。这是任务的要求,因此没有TF、PyTorch或Keras 我将状态编码为一个4×4×7的热编码向量,该向量为游戏中的每个单元格设置一个可能的状态(wumpus、gold、breeze、pit、player、empty、恶臭)为1,例如wumpus位于(1,1)->编码[1][1]=[1,0,0,0,0]。这会被展平为一个向量,以馈送到我的网络中 由于博弈具有不完全信息,最初,对于未知状态,该向量大多为1s 游戏未结束时,代理每次执行其Java 深度Q模型不学习,java,reinforcement-learning,Java,Reinforcement Learning,我正试图用我自己的ANN实现,通过深度Q学习来解决这个问题。这是任务的要求,因此没有TF、PyTorch或Keras 我将状态编码为一个4×4×7的热编码向量,该向量为游戏中的每个单元格设置一个可能的状态(wumpus、gold、breeze、pit、player、empty、恶臭)为1,例如wumpus位于(1,1)->编码[1][1]=[1,0,0,0,0]。这会被展平为一个向量,以馈送到我的网络中 由于博弈具有不完全信息,最初,对于未知状态,该向量大多为1s 游戏未结束时,代理每次执行其d
doAction()
方法,然后调用其train()
方法
“Trainer”或主循环实质上是在i
上循环,并为每一集创建一个新游戏,然后在游戏尚未结束时循环,并在代理上调用doAction()
和train()
。如果我们达到了某个任意阈值,我将使用策略网络的参数更新代理中的目标网络
我为每个游戏添加了最大步数,我认为这不应该存在,但这说明了问题:即使将epsilon贪婪参数设置为1,它似乎永远不会赢(或输)。最大步长是为了解决这一问题,目前
我选择使用的分数(奖励)是一个简单的-每移动一次-1,如果代理在坑中,-100,如果代理捡到了金子+1000,如果代理降落在Wumpus上,-1000(游戏结束)
我开始明白,由于TF和我自己的网络在速度上有着几乎无法比拟的差异,相信我可以用DQ解决这个问题是完全不可行的,然而,在我看来,如果这个项目不能以某种方式解决,我将不会被分配到这个项目
以下是相关代码:
DQNTrainer.java
public void train(int its) {
for (int i = 0; i < its; i++) {
double meanReward = 0;
World game = MapGenerator.getRandomMap((int) System.currentTimeMillis())
.generateWorld();
this.agent.setWorld(game);
int steps = 0;
while (!game.gameOver()) {
agent.doAction();
agent.train();
meanReward = meanReward + (agent.getScore());
if (steps > MAX_STEPS) {
break;
}
steps++;
}
rewards.add(Pair.of(i, (meanReward) / steps));
if (i % TARGET_UPDATE == 0) {
this.agent.updateTargetModel();
}
}
}
公共无效列车(int its){
for(int i=0;i最大步数){
打破
}
steps++;
}
奖励。添加(一对(平均奖励)/步骤);
如果(i%TARGET\u UPDATE==0){
this.agent.updateTargetModel();
}
}
}
DQNAgent.java
void train() {
if (memoryReplay.size() < BATCH_SIZE) {
return;
}
var sample = memoryReplay.sample(BATCH_SIZE);
// Old state predictions
List<Matrix<Primitive64Matrix>> oldStates = new ArrayList<>();
List<Matrix<Primitive64Matrix>> oldPredictions = new ArrayList<>();
for (Transition transition : sample) {
OjAlgoMatrix prevState = transition.prevState;
oldStates.add(prevState); // raw state
oldPredictions.add(this.policyModel.predict(prevState)); // predicted action
}
// New state predictions
List<Matrix<Primitive64Matrix>> newPredictions = new ArrayList<>();
for (var e : sample) {
if (!e.isDone()) {
Matrix<Primitive64Matrix> prediction = this.targetModel.predict(e.prevState);
// add target network's prediction of actions for next state
newPredictions.add(prediction);
} else {
double[][] zeroes = new double[6][1];
newPredictions.add((new OjAlgoMatrix(zeroes)));
}
}
List<NetworkInput<Primitive64Matrix>> training = new ArrayList<>();
for (int i = 0; i < sample.length; i++) {
var transition = sample[i];
var actionIndex = transition.action.index;
double[][] currentQState = oldPredictions.get(i).rawCopy();
if (transition.isDone()) {
currentQState[actionIndex][0] = transition.reward;
} else {
double maxFutureQ = newPredictions.get(i).max();
double gamma = 0.999;
currentQState[actionIndex][0] = transition.reward + (gamma * maxFutureQ);
}
Matrix<Primitive64Matrix> currentQ = new OjAlgoMatrix(currentQState);
training.add(new NetworkInput<>(oldStates.get(i), currentQ));
}
// Train with 90% as training, 10% as validation, one epoch and a batch size of 25.
// true is non-verbose mode.
this.policyModel
.train(training.subList(0, (int) (BATCH_SIZE * 0.7)),
training.subList((int) (BATCH_SIZE * 0.7), training.size()),
1, 25, true);
if (trainingIndex % 10 == 0) {
double total = 0;
for (int i = 0; i < 10; i++) {
Collections.shuffle(training);
total += this.policyModel.testLoss(training);
}
lossData.add(Pair.of(trainingIndex, total / 100));
}
trainingIndex++;
}
void列(){
if(memoryReplay.size()