Почему мой 2d автомобиль придерживается того же действия после обучения? - PullRequest
0 голосов
/ 23 февраля 2020

Я хочу научиться водить машину по прямой дороге, используя библиотеку Deeplearning4j (обучение подкреплению). Награды выдаются следующим образом: в случае автокатастрофы он получает -100, а если нет, то получает 1. Ожидающий автомобиль должен через некоторое время научиться ехать до конца дороги. Действия поворачиваются направо или налево на 4 градуса. Заметил, что автомобиль лучше совершает случайные действия, которые принимают меры на основе значений из q-таблицы, что я делаю не так? Обычно, если policy.EpsGreedy - EP: очень мало, он обычно придерживается одного действия. Ввод в непосредственной близости от машины - для оптимизации тренировочного процесса (20x20px).

Шаги агента:

public StepReply<Screen> step(Integer action) {
    final Car car = scene.getCar();
    final float speed = 4.0f;
    switch (action) {
        case ACTION_TOP_LEFT:
            car.addAngle(-ANGLE_ADDITION);
            computeNewLocation(car, speed);
            break;
        case ACTION_BOTTOM_RIGHT:
            car.addAngle(+ANGLE_ADDITION);
            computeNewLocation(car, speed);
            break;
    }
    scene.draw();
    double reward = scene.isCarScrashing() ? -100 : 1;

    return new StepReply<>(new Screen(scene.toByteArray()), reward, scene.isCarScrashing(), null);
}

private void computeNewLocation(Car car, float speed) {
    double x = car.getCurrentPositionX() + (speed * Math.cos(car.getRadianAngle().getValue()));
    double y = car.getCurrentPositionY() + (speed * Math.sin(car.getRadianAngle().getValue()));
    car.setCurrentPosition(x, y);
}

Конфигурация QL:

public static QLearning.QLConfiguration QL_CONFIGURATION =
        new QLearning.QLConfiguration(
                123,      //Random seed
                8000000,    //Max step By epoch
                8000000/2,  //Max step
                1000000/2,  //Max size of experience replay
                32,       //size of batches
                10000/2,    //target update (hard)
                500/2,      //num step noop warmup
                0.1,      //reward scaling
                0.99,     //gamma
                100.0,    //td-error clipping
                0.1f,     //min epsilon
                100000/2,   //num step for eps greedy anneal
                true      //double-dqn
        );

public static DQNFactoryStdConv.Configuration CONV = new DQNFactoryStdConv.Configuration(
        0.1, //learning rate
        0.000,   //l2 regularization
        null,
        null
);

Получение непосредственного окружения:

    public BufferedImage getCarView(Point sensorOrigin) {
    Graphics2D graphics2D = carSensorBuffer.createGraphics();
    graphics2D.clearRect(0, 0, SENSOR_WIDTH, SENSOR_HEIGHT);
    AffineTransform sensorTransform = AffineTransform.getTranslateInstance(-sensorOrigin.x + (SENSOR_WIDTH / 2), -sensorOrigin.y + (SENSOR_HEIGHT / 2));
    sensorTransform.rotate(-car.getRadianAngle().getValue(), sensorOrigin.x, sensorOrigin.y);
    graphics2D.drawRenderedImage(frontBuffer, sensorTransform);
    final BufferedImage scaledView = ImageUtil.scale(carSensorBuffer, SENSOR_WIDTH_OPTIMIZED, SENSOR_HEIGHT_OPTIMIZED);
    final Graphics2D graphics = carSensorBufferOptimized.createGraphics();
    graphics.drawImage(scaledView, 0, 0, null);

    return carSensorBufferOptimized;
}

    public byte[] toByteArray() {
    getCarView(car.getSensorOrigin());
    return ((DataBufferByte) carSensorBufferOptimized.getRaster().getDataBuffer()).getData();
}

Карта:

enter image description here

Пример ввода:

enter image description here

РЕДАКТИРОВАТЬ:

Забыл поделиться топологией нейронной сети:

    public static MultiLayerConfiguration MULTILAYER_CONFIGURATION = new NeuralNetConfiguration.Builder()
        .seed(12345)
        .optimizationAlgo(OptimizationAlgorithm.STOCHASTIC_GRADIENT_DESCENT)
        .l2(0.0)
        .updater((new Adam()))
        .weightInit(WeightInit.XAVIER)
        .l2(0.0)
        .list()
        .layer(0, new Convolution2D.Builder(new int[]{8, 8}).nIn(HISTORY_LENGTH).nOut(16).stride(new int[]{4, 4}).activation(Activation.RELU).build())
        .layer(1, new Convolution2D.Builder(new int[]{4, 4}).nOut(32).stride(new int[]{2, 2}).activation(Activation.RELU).build())
        .layer(2, new DenseLayer.Builder().nOut(256).activation(Activation.RELU).build())
        .layer(3, new OutputLayer.Builder(LossFunctions.LossFunction.MSE).activation(Activation.IDENTITY).nOut(CarMDP.NUM_ACTIONS).build())
        .setInputType(InputType.convolutional(20, 20, 3))
        .build();
...