Игра в змею с использованием обучения подкреплению и DQN (с deeplearning4j) - PullRequest
1 голос
/ 22 марта 2020

Я пытаюсь заставить ИИ играть в простую игру 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 баллов. Любые советы и пожелания приветствуются.

...