Почему моя программа аварийно завершает работу при выполнении loss.backward()?C++

Программы на C++. Форум разработчиков
Anonymous
Почему моя программа аварийно завершает работу при выполнении loss.backward()?

Сообщение Anonymous »

Я пытаюсь понять, почему моя программа выходит из строя при выполнении loss.backward(), но мне кажется, что я делаю что-то не так, и у меня заканчиваются идеи. Можете ли вы предложить, как решить эту проблему?
Вот код:

Код: Выделить всё

Trainer::Trainer(int64_t input_channels, int64_t num_actions, int64_t capacity) :     buffer(capacity),
network1(input_channels, num_actions),
target_network1(input_channels, num_actions),
dqn_optimizer(network1.parameters(), torch::optim::AdamOptions(0.001).betas({ 0.9, 0.999 })) {}

Код: Выделить всё

torch::Tensor Trainer::compute_td_loss(int64_t batch_size, float gamma) {

std::vector batch =
buffer.sample_queue(batch_size);

std::vector states;
std::vector new_states;
std::vector actions;
std::vector rewards;

for (auto i : batch) {
states.push_back(std::get(i).to(torch::kCPU));
new_states.push_back(std::get(i).to(torch::kCPU));
actions.push_back(std::get(i).to(torch::kCPU));
rewards.push_back(std::get(i).to(torch::kCPU));
}

torch::Tensor states_tensor;
torch::Tensor new_states_tensor;
torch::Tensor actions_tensor;
torch::Tensor rewards_tensor;

states_tensor = torch::cat(states, 0);
new_states_tensor = torch::cat(new_states, 0);
rewards_tensor = torch::cat(rewards, 0);
actions_tensor = torch::cat(actions, 0);

torch::Tensor q_values = network1.forward(states_tensor);
torch::Tensor next_target_q_values = target_network1.forward(new_states_tensor);
torch::Tensor next_q_values = network1.forward(new_states_tensor);
actions_tensor = actions_tensor.to(torch::kInt64);

for (int i = 0; i < batch_size; ++i) {
// Extraire l'indice de l'action pour l'élément i
int action_index = actions_tensor[i][0].item();

// Afficher action_index

int j;

if (action_index == 0) j = 0;
else if (action_index == 12) j = 1;
else if (action_index == 25) j = 2;
else if (action_index == 50) j = 3;
else if (action_index == 75) j = 4;
else if (action_index == 88) j = 5;
else j = 6;

// Extraire la valeur Q correspondante de q_values pour l'indice d'action spécifié
q_value[i] = q_values[i][j];
}

torch::Tensor maximum = std::get(next_q_values.max(1));

torch::Tensor next_q_value = torch::empty({ batch_size }, torch::kCPU);

// Parcourir chaque élément du batch
for (int i = 0; i < batch_size; ++i) {
// Extraire l'indice de l'action pour l'élément i
int action_index = maximum[i].item();

// Afficher action_index

// Extraire la valeur Q correspondante de q_values pour l'indice d'action spécifié
next_q_value[i] = next_target_q_values[i][action_index];
}

torch::Tensor expected_q_value = rewards_tensor.squeeze(1) + gamma * next_q_value;

torch::Tensor loss = torch::mse_loss(q_value, expected_q_value);

for (const auto& param : network1.parameters()) {
if (!param.requires_grad()) {
::MessageBox(NULL, L"Paramètre n'a pas requires_grad défini sur true", L"compute_td_loss", MB_OK);
}
}

dqn_optimizer.zero_grad();
loss.backward();
dqn_optimizer.step();

return loss;
}

Код: Выделить всё

struct LinearModel : torch::nn::Module {
torch::nn::Linear linear;

LinearModel(int64_t input_size, int64_t output_size)
: linear(register_module("linear", torch::nn::Linear(input_size, output_size))) {

// Setting requires_grad=True for all parameters
for (auto&  param : linear->parameters()) {
param.requires_grad_(true);
}

}

torch::Tensor forward(torch::Tensor input) {

torch::DeviceType device_type;
device_type = torch::kCPU;
torch::Device device(device_type);

input = torch::relu(linear(input));

return input;
}

Код: Выделить всё

class Trainer {

private: ExperienceReplay buffer;
private: LinearModel network1, target_network1;
private: torch::optim::Adam dqn_optimizer;
private: double epsilon_start = 1.0;
private: double epsilon_final = 0.01;
private: int64_t epsilon_decay = 30000;
private: int64_t batch_size = 32;
private: float gamma = 0.99;

public:

Trainer(int64_t input_channels, int64_t num_actions, int64_t capacity);

torch::Tensor compute_td_loss(int64_t batch_size, float gamma);
double epsilon_by_frame(int64_t frame_id);
void loadstatedict(torch::nn::Module& model,
torch::nn::Module& target_model);
void Trainer::ddqn(struct_matrix* state, int indice, struct_matrix* nb_pos, struct_matrix* data, sortie* sortie0);
};
Я пытался поместить все тензоры в kCPU; Я попытался отсоединить тензор next_q_value; Я проверяю размеры q_value и next_q_value; они имеют одинаковую размерность {32} и не имеют NaN ; Я проверяю значение потери (=2,70521); Я попытался добавить require_grad = True, чтобы позволить потере распространяться

Подробнее здесь: https://stackoverflow.com/questions/786 ... s-backward

Вернуться в «C++»