Реализация обучения разнице во времени на Java
Приведенный ниже код является моей реализацией обучения разнице во времени. Агент, который использует алгоритм TD, играет более 750000 игр против агента, который использует процедуру mini-max для игры, но проблема в том, что TD-агент не учится... Что не так с этой реализацией?
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;
}
Я использовал эту ссылку в качестве ориентира. Я пробовал разные значения для ALPHA & BETA, количество скрытых нейронов. Следы соответствия инициализируются до 0.
1 ответ
Проблема в основном в том, что вы не можете настроить аппроксиматор функции своей нейронной сети, и из того, что вы сказали, я могу предположить, что "он не учится" означает, что алгоритм не сходится.
Это происходит, когда мы используем, используя TD и NN вместе. И это случилось со мной ранее, и я долго искал это. Урок, который я усвоил, заключается в следующем:
По словам Ричарда Саттона: не пытайтесь использовать нейронные сети в качестве аппроксиматоров функций вместе с методами TD, если вы не знаете точно, как настроить свою нейронную сеть. В противном случае это вызовет много проблем.
Чтобы узнать больше об этом, найдите разговор Саттона на YouTube.