Итак, я изучаю нейронные сети прямо сейчас, и я заметил что-то действительно очень странное в своей сети. У меня есть входной слой, созданный таким образом
convN1 = register_module("convN1", torch::nn::Conv2d(torch::nn::Conv2dOptions(4, 256, 3).padding(1)));
, и выходной слой, который является функцией tanh.
Итак, он ожидает torch :: Tensor of shape {/ batchSize /, 4, / sideLength /, / sideLength /} который является и будет выводить тензор всего 1 значения с плавающей запятой.
Таким образом, для тестирования I создали собственный тензор формы {4, 15, 15}.
Действительно странная часть - это то, что происходит ниже
auto inputTensor = torch::zeros({ 1, 4, 15, 15});
inputTensor[0] = customTensor;
std::cout << network->forward(inputTensor); // Outputs something like 0.94142
inputTensor = torch::zeros({ 32, 4, 15, 15});
inputTensor[0] = customTensor;
std::cout << network->forward(inputTensor); // Outputs something like 0.1234 then 0.8543 31 times
Итак, почему customTensor получает 2 разных значения из моей сети просто из-за того, что размер партии изменился? Разве я не понимаю некоторых частей того, как работают тензоры?
PS Я проверил, и приведенный выше блок кода работал в режиме eval.
Изменить: поскольку его спрашивали, вот более подробный взгляд в моей сети
convN1 = register_module("convN1", torch::nn::Conv2d(torch::nn::Conv2dOptions(4, 256, 3).padding(1)));
batchNorm1 = register_module("batchNorm1", torch::nn::BatchNorm2d(torch::nn::BatchNormOptions(256)));
m_residualBatch1 = register_module(batch1Name, torch::nn::BatchNorm2d(torch::nn::BatchNormOptions(256)));
m_residualBatch2 = register_module(batch2Name, torch::nn::BatchNorm2d(torch::nn::BatchNormOptions(256)));
m_residualConv1 = register_module(conv1Name, torch::nn::Conv2d(torch::nn::Conv2dOptions(256, 256, 3).padding(1)));
m_residualConv2 = register_module(conv2Name, torch::nn::Conv2d(torch::nn::Conv2dOptions(256, 256, 3).padding(1)));
valueN1 = register_module("valueN1", torch::nn::Conv2d(256, 2, 1));
batchNorm3 = register_module("batchNorm3", torch::nn::BatchNorm2d(torch::nn::BatchNormOptions(2)));
valueN2 = register_module("valueN2", torch::nn::Linear(2 * BOARD_LENGTH, 64));
valueN3 = register_module("valueN3", torch::nn::Linear(64, 1));
И как он пересылает так
torch::Tensor Net::forwadValue(torch::Tensor x)
{
x = convN1->forward(x);
x = batchNorm1->forward(x);
x = torch::relu(x);
torch::Tensor residualCopy = x.clone();
x = m_residualConv1->forward(x);
x = m_residualBatch1->forward(x);
x = torch::relu(x);
x = m_residualConv2->forward(x);
x = m_residualBatch2->forward(x);
x += residualCopy;
x = torch::relu(x);
x = valueN1->forward(x);
x = batchNorm3->forward(x)
x = torch::relu(x);
x = valueN2->forward(x.reshape({ x.sizes()[0], 30 }))
x = torch::relu(x);
x = valueN3->forward(x)
return torch::tanh(x);
}