Я пытаюсь заставить ИИ играть в простую игру Snake, следуя этой статье . С моим текущим решением змея может набрать около 35 баллов. По какой-то причине он будет правильно обрабатывать стены, но почти каждый раз d ie, ударяя своим собственным хвостом. Я не могу точно определить свою ошибку, но я предполагаю, что я использую функцию подгонки в нейронной сети.
for (int i = 0; i < EPOCHS; i++) {
epsilon = 0.9;
board.initGame();
State state = board.getState();
while (state.isInGame()) {
// Get next action to perform
final Action action = epsilonGreedyAction(state);
// Play action and get reward
final double reward = board.getRewardForAction(state, action);
// Get next state
final State nextState = board.getState();
// Update neural network
update(state, action, reward, nextState);
// Apply next state
state = nextState;
}
}
private Action epsilonGreedyAction(final State state) {
epsilon -=0.001;
double random = SnakeUtil.getRandom();
if (random < epsilon) {
randomActions++;
return Action.randomAction(state);
}
return SnakeUtil.getMaxQAction(state, Q_TABLE);
}
getMaxQAction вернет любое действие, которое есть в Q_TABLE для это состояние, которое до сих пор имело высокую награду (максимальное вознаграждение). Q_TABLE обновляется также в методе обновления
private void update(final State state, final Action action, final double reward, final State nextState) {
MaxQ maxQ = SnakeUtil.getMaxQ(nextState, Q_TABLE);
double targetReward = reward + (0.90 * maxQ.getReward());
SnakeUtil.updateQTable(state, action, targetReward, Q_TABLE);
net.fit(buildObservation(state).getData(), Nd4j.create(fromAction(action)));
}
private double[][] fromAction(final Action action) {
return new double[][] {
{
action.equals(Action.UP) ? 1 : 0,
action.equals(Action.RIGHT) ? 1 : 0,
action.equals(Action.DOWN) ? 1 : 0,
action.equals(Action.LEFT) ? 1 : 0
}
};
}
private Observation buildObservation(final State state) {
return new Observation(Nd4j.create(new boolean[][]{
{
state.isCanGoUp(),
state.isCanGoRight(),
state.isCanGoDown(),
state.isCanGoLeft(),
state.isFoodUp(),
state.isFoodUpRight(),
state.isFoodRight(),
state.isFoodDownRight(),
state.isFoodDown(),
state.isFoodDownLeft(),
state.isFoodLeft(),
state.isFoodUpLeft()
}
}));
}
Мой вопрос заключается в том, получает ли метод подбора правильные параметры. Если да, то моя проблема должна быть где-то еще.
Кроме того, награда рассчитывается таким образом, что каждый раз, когда змея шагает в направлении еды, она вознаграждается 1, в противном случае она наказывается -1,5. Если он ест еду, он получает 30 баллов. Любые советы и пожелания приветствуются.