Я тестировал эту простую операцию нарезки в TF и PyTorch, которая должна совпадать в обоих случаях.
import tensorflow as tf
import numpy as np
import torch
tf_x = tf.random.uniform((4, 64, 64, 3))
pt_x = torch.Tensor(tf_x.numpy())
pt_x = pt_x.permute(0, 3, 1, 2)
# slicing operation
print(np.any(pt_x[:, :, 1:].permute(0, 2, 3, 1).numpy() - tf_x[:, 1:].numpy()))
# > False
pt_x = torch.Tensor(tf_x.numpy())
b, h, w, c = pt_x.shape
pt_x = pt_x.reshape((b, c, h, w))
print(np.any(pt_x.view(b, h, w, c).numpy() - tf_x.numpy())) # False
print(np.any(pt_x[:, :, 1:].reshape(4, 63, 64, 3).numpy() - tf_x[:, 1:].numpy()))
# > True
В последней строке кроется проблема. И PyTorch, и TF должны приводить к одному и тому же значению, но это не так. Это несоответствие вызвано, когда я пытаюсь изменить форму тензора?






С одной стороны, у вас pt_x равно tf_x, используйте np.isclose, чтобы проверить:
>>> np.isclose(pt_x.view(b, h, w, c).numpy(), tf_x.numpy()).all()
True
С другой стороны, вы нарезаете оба тензора по-разному: pt_x[:, :, 1:] удаляет первый элемент вдоль axis=2, а tf_x[:, 1:] удаляет первый элемент вдоль axis=1. Таким образом, вы получите два отдельных элемента с перекрывающимися значениями, например tf_x[:, 1:][0,-1,-1,-1] и pt_x[0,-1,-1,-1].
Также имейте в виду, что макеты тензоров различаются в Tensorflow и PyTorch, в то время как первый использует последний макет канала, а последний — первый канал. Операция, необходимая между этими двумя, представляет собой перестановку (а не изменение формы).
Спасибо. Перестановка работала нормально. Теперь я пытаюсь понять, как «изменить форму» работает под капотом. Кроме того, я не мог понять эту часть вашего ответа: «Поэтому вы получаете два разных элемента с перекрывающимися значениями, например tf_x[:, 1:][0,-1,-1,-1] и pt_x[0 ,-1,-1,-1]'. Если возможно, можете ли вы опубликовать ссылку, объясняющую эту концепцию?