Browse Source

Align C++ and Python ResNet debug output pipeline: identical preprocessing, shape, and output comparison; fix PyTorch 2.6+ torch.load issue; automate debug export and comparison for all stages

resnet
mht 2 weeks ago
parent
commit
d27fa815e9
  1. 4
      build/CMakeCache.txt
  2. 4
      build/CMakeFiles/Makefile2
  3. 18
      cimp/resnet/resnet.cpp
  4. 4
      compare_preprocessed_inputs_debug.py
  5. 94
      compare_resnet_outputs_debug.py
  6. 36
      compare_resnet_weights.py
  7. BIN
      ltr/models/backbone/__pycache__/resnet.cpython-311.pyc
  8. BIN
      ltr/models/backbone/__pycache__/resnet.cpython-37.pyc
  9. 25
      ltr/models/backbone/resnet.py
  10. BIN
      ltr/models/bbreg/__pycache__/atom_iou_net.cpython-37.pyc
  11. 46
      test/compare_models.py
  12. BIN
      test/exported_weights/backbone_pure_tensors/bn1_bias.pt
  13. BIN
      test/exported_weights/backbone_pure_tensors/bn1_num_batches_tracked.pt
  14. BIN
      test/exported_weights/backbone_pure_tensors/bn1_running_mean.pt
  15. BIN
      test/exported_weights/backbone_pure_tensors/bn1_running_var.pt
  16. BIN
      test/exported_weights/backbone_pure_tensors/bn1_weight.pt
  17. BIN
      test/exported_weights/backbone_pure_tensors/conv1_weight.pt
  18. BIN
      test/exported_weights/backbone_pure_tensors/fc_bias.pt
  19. BIN
      test/exported_weights/backbone_pure_tensors/fc_weight.pt
  20. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn1_bias.pt
  21. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn1_num_batches_tracked.pt
  22. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn1_running_mean.pt
  23. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn1_running_var.pt
  24. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn1_weight.pt
  25. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn2_bias.pt
  26. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn2_num_batches_tracked.pt
  27. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn2_running_mean.pt
  28. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn2_running_var.pt
  29. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn2_weight.pt
  30. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn3_bias.pt
  31. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn3_num_batches_tracked.pt
  32. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn3_running_mean.pt
  33. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn3_running_var.pt
  34. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_bn3_weight.pt
  35. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_conv1_weight.pt
  36. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_conv2_weight.pt
  37. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_conv3_weight.pt
  38. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_downsample_0_weight.pt
  39. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_bias.pt
  40. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_num_batches_tracked.pt
  41. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_running_mean.pt
  42. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_running_var.pt
  43. BIN
      test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_weight.pt
  44. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn1_bias.pt
  45. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn1_num_batches_tracked.pt
  46. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn1_running_mean.pt
  47. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn1_running_var.pt
  48. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn1_weight.pt
  49. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn2_bias.pt
  50. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn2_num_batches_tracked.pt
  51. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn2_running_mean.pt
  52. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn2_running_var.pt
  53. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn2_weight.pt
  54. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn3_bias.pt
  55. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn3_num_batches_tracked.pt
  56. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn3_running_mean.pt
  57. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn3_running_var.pt
  58. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_bn3_weight.pt
  59. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_conv1_weight.pt
  60. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_conv2_weight.pt
  61. BIN
      test/exported_weights/backbone_pure_tensors/layer1_1_conv3_weight.pt
  62. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn1_bias.pt
  63. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn1_num_batches_tracked.pt
  64. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn1_running_mean.pt
  65. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn1_running_var.pt
  66. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn1_weight.pt
  67. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn2_bias.pt
  68. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn2_num_batches_tracked.pt
  69. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn2_running_mean.pt
  70. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn2_running_var.pt
  71. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn2_weight.pt
  72. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn3_bias.pt
  73. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn3_num_batches_tracked.pt
  74. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn3_running_mean.pt
  75. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn3_running_var.pt
  76. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_bn3_weight.pt
  77. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_conv1_weight.pt
  78. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_conv2_weight.pt
  79. BIN
      test/exported_weights/backbone_pure_tensors/layer1_2_conv3_weight.pt
  80. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn1_bias.pt
  81. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn1_num_batches_tracked.pt
  82. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn1_running_mean.pt
  83. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn1_running_var.pt
  84. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn1_weight.pt
  85. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn2_bias.pt
  86. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn2_num_batches_tracked.pt
  87. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn2_running_mean.pt
  88. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn2_running_var.pt
  89. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn2_weight.pt
  90. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn3_bias.pt
  91. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn3_num_batches_tracked.pt
  92. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn3_running_mean.pt
  93. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn3_running_var.pt
  94. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_bn3_weight.pt
  95. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_conv1_weight.pt
  96. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_conv2_weight.pt
  97. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_conv3_weight.pt
  98. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_downsample_0_weight.pt
  99. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_downsample_1_bias.pt
  100. BIN
      test/exported_weights/backbone_pure_tensors/layer2_0_downsample_1_num_batches_tracked.pt

4
build/CMakeCache.txt

@ -201,8 +201,8 @@ CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_STRIP:FILEPATH=/usr/bin/strip
//The CMake toolchain file
CMAKE_TOOLCHAIN_FILE:FILEPATH=/media/mht/ADATA/repos/cpp_tracker/vcpkg/scripts/buildsystems/vcpkg.cmake
//No help, variable specified on the command line.
CMAKE_TOOLCHAIN_FILE:UNINITIALIZED=../vcpkg/scripts/buildsystems/vcpkg.cmake
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console

4
build/CMakeFiles/Makefile2

@ -192,9 +192,9 @@ CMakeFiles/dimp_tracker.dir/clean:
# Target rules for target CMakeFiles/tracking_demo.dir
# All Build rule for target.
CMakeFiles/tracking_demo.dir/all: CMakeFiles/bb_regressor.dir/all
CMakeFiles/tracking_demo.dir/all: CMakeFiles/dimp_tracker.dir/all
CMakeFiles/tracking_demo.dir/all: CMakeFiles/resnet.dir/all
CMakeFiles/tracking_demo.dir/all: CMakeFiles/bb_regressor.dir/all
CMakeFiles/tracking_demo.dir/all: CMakeFiles/classifier.dir/all
$(MAKE) $(MAKESILENT) -f CMakeFiles/tracking_demo.dir/build.make CMakeFiles/tracking_demo.dir/depend
$(MAKE) $(MAKESILENT) -f CMakeFiles/tracking_demo.dir/build.make CMakeFiles/tracking_demo.dir/build
@ -221,9 +221,9 @@ CMakeFiles/tracking_demo.dir/clean:
# Target rules for target CMakeFiles/test_models.dir
# All Build rule for target.
CMakeFiles/test_models.dir/all: CMakeFiles/bb_regressor.dir/all
CMakeFiles/test_models.dir/all: CMakeFiles/dimp_tracker.dir/all
CMakeFiles/test_models.dir/all: CMakeFiles/resnet.dir/all
CMakeFiles/test_models.dir/all: CMakeFiles/bb_regressor.dir/all
CMakeFiles/test_models.dir/all: CMakeFiles/classifier.dir/all
$(MAKE) $(MAKESILENT) -f CMakeFiles/test_models.dir/build.make CMakeFiles/test_models.dir/depend
$(MAKE) $(MAKESILENT) -f CMakeFiles/test_models.dir/build.make CMakeFiles/test_models.dir/build

18
cimp/resnet/resnet.cpp

@ -237,7 +237,11 @@ std::map<std::string, torch::Tensor> ResNetImpl::forward(torch::Tensor x) {
return std::find(_output_layers.begin(), _output_layers.end(), layer_name) != _output_layers.end();
};
// Print input shape
if (x.size(0) > 0) std::cout << "[DEBUG] Input shape: " << x.sizes() << std::endl;
x = conv1->forward(x);
if (x.size(0) > 0) torch::save(x[0].cpu(), "test/output/resnet_debug/sample_0_after_conv1.pt");
if (should_output("debug_resnet_conv1_output_for_bn1_input")) {
outputs["debug_resnet_conv1_output_for_bn1_input"] = x.clone();
}
@ -247,30 +251,27 @@ std::map<std::string, torch::Tensor> ResNetImpl::forward(torch::Tensor x) {
if (bn1) {
x = bn1->forward(x);
}
if (x.size(0) > 0) torch::save(x[0].cpu(), "test/output/resnet_debug/sample_0_after_bn1.pt");
// End apply bn1
if (should_output("bn1_output")) outputs["bn1_output"] = x;
x = relu->forward(x);
if (should_output("relu1_output")) outputs["relu1_output"] = x;
if (x.size(0) > 0) torch::save(x[0].cpu(), "test/output/resnet_debug/sample_0_after_relu1.pt");
// Save conv1_output AFTER bn1 and relu (matching Python behavior)
if (should_output("conv1_output")) outputs["conv1_output"] = x;
torch::Tensor x_pre_layer1 = maxpool->forward(x);
if (should_output("maxpool_output")) outputs["maxpool_output"] = x_pre_layer1;
if (x_pre_layer1.size(0) > 0) torch::save(x_pre_layer1[0].cpu(), "test/output/resnet_debug/sample_0_after_maxpool.pt");
// Save output of layer1.0 block if requested
if (should_output("layer1_0_block_output")) {
if (layer1 && !layer1->is_empty()) {
try {
// Get the base module pointer
std::shared_ptr<torch::nn::Module> base_module_ptr = layer1->ptr(0);
// Try to cast it to our BottleneckImpl (which is a torch::nn::Module)
auto bottleneck_impl_ptr = std::dynamic_pointer_cast<cimp::resnet::BottleneckImpl>(base_module_ptr);
if (bottleneck_impl_ptr) {
// Now call forward on the BottleneckImpl instance
outputs["layer1_0_block_output"] = bottleneck_impl_ptr->forward(x_pre_layer1);
} else {
std::cerr << "ERROR: layer1->ptr(0) could not be dynamically cast to BottleneckImpl! Module type: "
@ -283,6 +284,7 @@ std::map<std::string, torch::Tensor> ResNetImpl::forward(torch::Tensor x) {
}
torch::Tensor x_after_layer1 = layer1->forward(x_pre_layer1);
if (x_after_layer1.size(0) > 0) torch::save(x_after_layer1[0].cpu(), "test/output/resnet_debug/sample_0_after_layer1.pt");
if (should_output("layer1")) outputs["layer1"] = x_after_layer1;
if (should_output("layer1_0_shortcut_output")) {
@ -290,7 +292,6 @@ std::map<std::string, torch::Tensor> ResNetImpl::forward(torch::Tensor x) {
try {
std::shared_ptr<torch::nn::Module> first_block_module_ptr = layer1->ptr(0);
auto bottleneck_module_holder = std::dynamic_pointer_cast<cimp::resnet::BottleneckImpl>(first_block_module_ptr);
if (bottleneck_module_holder) {
if (bottleneck_module_holder->projection_shortcut) {
torch::Tensor shortcut_out = bottleneck_module_holder->projection_shortcut->forward(x_pre_layer1);
@ -306,12 +307,15 @@ std::map<std::string, torch::Tensor> ResNetImpl::forward(torch::Tensor x) {
torch::Tensor x_current = x_after_layer1;
x_current = layer2->forward(x_current);
if (x_current.size(0) > 0) torch::save(x_current[0].cpu(), "test/output/resnet_debug/sample_0_after_layer2.pt");
if (should_output("layer2")) outputs["layer2"] = x_current;
x_current = layer3->forward(x_current);
if (x_current.size(0) > 0) torch::save(x_current[0].cpu(), "test/output/resnet_debug/sample_0_after_layer3.pt");
if (should_output("layer3")) outputs["layer3"] = x_current;
x_current = layer4->forward(x_current);
if (x_current.size(0) > 0) torch::save(x_current[0].cpu(), "test/output/resnet_debug/sample_0_after_layer4.pt");
if (should_output("layer4")) outputs["layer4"] = x_current;
if (should_output("features")) outputs["features"] = x_current;

4
compare_preprocessed_inputs_debug.py

@ -14,8 +14,8 @@ def get_tensor(x):
pass
raise RuntimeError('Could not extract tensor')
a = torch.load('test/output/resnet/sample_0_image_preprocessed_python.pt', weights_only=False)
b = torch.load('test/output/resnet/sample_0_image_preprocessed_cpp.pt', weights_only=False)
a = torch.load('test/output/resnet/sample_0_image_preprocessed_python.pt')
b = torch.load('test/output/resnet/sample_0_image_preprocessed_cpp.pt')
a = get_tensor(a)
b = get_tensor(b)
print('py:', a.shape, a.dtype, a.min().item(), a.max().item(), a.mean().item())

94
compare_resnet_outputs_debug.py

@ -1,42 +1,64 @@
import torch
import os
from ltr.models.backbone import resnet50
def get_tensor(x):
if isinstance(x, torch.Tensor):
return x
if hasattr(x, 'parameters') and len(list(x.parameters())) > 0:
return list(x.parameters())[0]
if callable(x):
try:
out = x()
if isinstance(out, torch.Tensor):
return out
except Exception:
pass
raise RuntimeError('Could not extract tensor')
def save_tensor(tensor, path):
os.makedirs(os.path.dirname(path), exist_ok=True)
torch.save(tensor.cpu(), path)
def compare_tensors(py_path, cpp_path, label):
a = torch.load(py_path)
b = torch.load(cpp_path, weights_only=False)
b = get_tensor(b)
print(f'--- {label} ---')
print('py:', a.shape, a.dtype, a.min().item(), a.max().item(), a.mean().item())
print('cpp:', b.shape, b.dtype, b.min().item(), b.max().item(), b.mean().item())
print('diff:', (a-b).abs().max().item(), (a-b).abs().mean().item())
# Load the preprocessed input tensor exported from C++
preprocessed_input_path = 'test/input_samples/common/sample_0_image.pt'
input_obj = torch.load(preprocessed_input_path, map_location='cpu', weights_only=False)
if isinstance(input_obj, torch.Tensor):
input_tensor = input_obj
else:
# Try to extract tensor from JIT module
if hasattr(input_obj, 'named_parameters'):
params = list(input_obj.named_parameters())
if params:
input_tensor = params[0][1]
else:
raise RuntimeError('No tensor found in JIT module')
else:
raise RuntimeError('Unknown input object type')
compare_tensors('test/output_py/resnet_py/sample_0/conv1_output.pt', 'test/output/resnet/sample_0_conv1_output.pt', 'conv1_output')
compare_tensors('test/output_py/resnet_py/sample_0/debug_resnet_conv1_output_for_bn1_input.pt', 'test/output/resnet/sample_0_debug_resnet_conv1_output_for_bn1_input.pt', 'debug_resnet_conv1_output_for_bn1_input')
compare_tensors('test/output_py/resnet_py/sample_0/bn1_output.pt', 'test/output/resnet/sample_0_bn1_output.pt', 'bn1_output')
# Add batch dimension if missing
if input_tensor.dim() == 3:
input_tensor = input_tensor.unsqueeze(0)
# Print BN1 epsilon and momentum from Python model
try:
from ltr.models.backbone import resnet50
model = resnet50(output_layers=['layer1', 'layer2', 'layer3', 'layer4'], pretrained=False)
model.load_state_dict(torch.load('backbone_pure_tensors/state_dict.pt'))
print('\nPython BN1 epsilon:', model.bn1.eps)
print('Python BN1 momentum:', model.bn1.momentum)
except Exception as e:
print('Could not print Python BN1 eps/momentum:', e)
# Load Python ResNet model
model = resnet50(output_layers=['layer1', 'layer2', 'layer3', 'layer4'], pretrained=False)
# Optionally load weights if needed (uncomment and set path if required)
# model.load_state_dict(torch.load('backbone_pure_tensors/state_dict.pt'))
model.eval()
# Print expected C++ BN1 epsilon and momentum (from code)
print('C++ BN1 epsilon: 1e-5 (from C++ code)')
print('C++ BN1 momentum: 0.1 (from C++ code)')
# Forward pass and save intermediate outputs
x = input_tensor
out_dir = 'test/output_py/resnet_debug/'
# After conv1
x1 = model.conv1(x)
save_tensor(x1[0], os.path.join(out_dir, 'sample_0_after_conv1.pt'))
# After bn1
x2 = model.bn1(x1)
save_tensor(x2[0], os.path.join(out_dir, 'sample_0_after_bn1.pt'))
# After relu1
x3 = model.relu(x2)
save_tensor(x3[0], os.path.join(out_dir, 'sample_0_after_relu1.pt'))
# After maxpool
x4 = model.maxpool(x3)
save_tensor(x4[0], os.path.join(out_dir, 'sample_0_after_maxpool.pt'))
# After layer1
x5 = model.layer1(x4)
save_tensor(x5[0], os.path.join(out_dir, 'sample_0_after_layer1.pt'))
# After layer2
x6 = model.layer2(x5)
save_tensor(x6[0], os.path.join(out_dir, 'sample_0_after_layer2.pt'))
# After layer3
x7 = model.layer3(x6)
save_tensor(x7[0], os.path.join(out_dir, 'sample_0_after_layer3.pt'))
# After layer4
x8 = model.layer4(x7)
save_tensor(x8[0], os.path.join(out_dir, 'sample_0_after_layer4.pt'))
print('Saved all intermediate outputs for sample 0 using C++-preprocessed input.')

36
compare_resnet_weights.py

@ -0,0 +1,36 @@
import torch
import os
PYTHON_DIR = "exported_weights/backbone_pure_tensors/"
CPP_DIR = "exported_weights/backbone_regenerated/"
def compare_tensors(a, b, label):
a = a.float().cpu().contiguous().view(-1)
b = b.float().cpu().contiguous().view(-1)
if a.shape != b.shape:
print(f"{label}: Shape mismatch: {a.shape} vs {b.shape}")
return
cos_sim = torch.nn.functional.cosine_similarity(a, b, dim=0).item()
mae = torch.mean(torch.abs(a - b)).item()
max_abs = torch.max(torch.abs(a - b)).item()
print(f"{label}: cos_sim={cos_sim:.8f}, MAE={mae:.8e}, max_abs={max_abs:.8e}")
def main():
py_files = {f for f in os.listdir(PYTHON_DIR) if f.endswith('.pt')}
cpp_files = {f for f in os.listdir(CPP_DIR) if f.endswith('.pt')}
common_files = sorted(py_files & cpp_files)
missing_in_cpp = sorted(py_files - cpp_files)
missing_in_py = sorted(cpp_files - py_files)
if missing_in_cpp:
print("Files missing in C++ export:", missing_in_cpp)
if missing_in_py:
print("Files missing in Python export:", missing_in_py)
for fname in common_files:
py_tensor = torch.load(os.path.join(PYTHON_DIR, fname), map_location='cpu', weights_only=False)
cpp_tensor = torch.load(os.path.join(CPP_DIR, fname), map_location='cpu', weights_only=False)
compare_tensors(py_tensor, cpp_tensor, fname)
if __name__ == "__main__":
main()

BIN
ltr/models/backbone/__pycache__/resnet.cpython-311.pyc

BIN
ltr/models/backbone/__pycache__/resnet.cpython-37.pyc

25
ltr/models/backbone/resnet.py

@ -2,6 +2,8 @@ import math
import torch.nn as nn
from collections import OrderedDict
import torch.utils.model_zoo as model_zoo
import torch
import os
from .base import Backbone
@ -119,32 +121,47 @@ class ResNet(Backbone):
if output_layers is None:
output_layers = self.output_layers
# Debug directory
debug_dir = 'test/output_py/resnet_py/sample_0/'
if not os.path.exists(debug_dir):
os.makedirs(debug_dir)
sample_idx = 0 # Always save for first sample
# conv1
x = self.conv1(x)
torch.save(x[0].cpu(), os.path.join(debug_dir, 'debug_resnet_conv1_output_for_bn1_input.pt'))
x = self.bn1(x)
torch.save(x[0].cpu(), os.path.join(debug_dir, 'bn1_output.pt'))
x = self.relu(x)
torch.save(x[0].cpu(), os.path.join(debug_dir, 'relu1_output.pt'))
if self._add_output_and_check('conv1', x, outputs, output_layers):
return outputs
x = self.maxpool(x)
torch.save(x[0].cpu(), os.path.join(debug_dir, 'maxpool_output.pt'))
# layer1
x = self.layer1(x)
torch.save(x[0].cpu(), os.path.join(debug_dir, 'layer1_output.pt'))
if self._add_output_and_check('layer1', x, outputs, output_layers):
return outputs
# layer2
x = self.layer2(x)
torch.save(x[0].cpu(), os.path.join(debug_dir, 'layer2_output.pt'))
if self._add_output_and_check('layer2', x, outputs, output_layers):
return outputs
# layer3
x = self.layer3(x)
torch.save(x[0].cpu(), os.path.join(debug_dir, 'layer3_output.pt'))
if self._add_output_and_check('layer3', x, outputs, output_layers):
return outputs
# layer4
x = self.layer4(x)
torch.save(x[0].cpu(), os.path.join(debug_dir, 'layer4_output.pt'))
if self._add_output_and_check('layer4', x, outputs, output_layers):
return outputs

BIN
ltr/models/bbreg/__pycache__/atom_iou_net.cpython-37.pyc

46
test/compare_models.py

@ -26,7 +26,7 @@ from pytracking.features.net_wrappers import DiMPTorchScriptWrapper
# For loading AtomIoUNet from source
from ltr.models.bbreg.atom_iou_net import AtomIoUNet
# Add import for new modular comparison
from model_comparison.bbreg_comparison import compare_debug_tensors
from model_comparison.bbreg_comparison import compare_debug_tensors, compare_resnet_debug_tensors
SCRIPT_DIR_FOR_INIT = os.path.dirname(os.path.abspath(__file__))
ROOT_DIR_FOR_INIT = os.path.dirname(SCRIPT_DIR_FOR_INIT)
@ -764,13 +764,12 @@ class ComparisonRunner:
processed_input_tensor = input_tensor.to(self.device) # Ensure device
# --- END REINSTATED INPUT LOADING AND PREPROCESSING ---
# --- Save preprocessed input for sample 0 ---
if sample_idx == 0:
preprocessed_dir = Path(self.cpp_output_dir) / 'resnet'
preprocessed_dir.mkdir(parents=True, exist_ok=True)
py_preprocessed_path = preprocessed_dir / f'sample_{sample_idx}_image_preprocessed_python.pt'
torch.save(processed_input_tensor.cpu(), py_preprocessed_path)
print(f"Saved Python preprocessed image for sample {sample_idx} to {py_preprocessed_path}")
# --- Save preprocessed input for every sample ---
preprocessed_dir = Path(self.cpp_output_dir) / 'resnet'
preprocessed_dir.mkdir(parents=True, exist_ok=True)
py_preprocessed_path = preprocessed_dir / f'sample_{sample_idx}_image_preprocessed_python.pt'
torch.save(processed_input_tensor.cpu(), py_preprocessed_path)
print(f"Saved Python preprocessed image for sample {sample_idx} to {py_preprocessed_path}")
# --- END save preprocessed input ---
# Initialize dictionaries to store Python-side outputs for the current sample
@ -987,6 +986,16 @@ class ComparisonRunner:
# processed_samples += 1 # This variable is no longer used as loop is range-based
print("--- ResNet Output Comparison Complete ---")
def compare_resnet_debug_outputs(self, sample_idx=0, verbose=True):
"""
Compare intermediate ResNet debug outputs between C++ and Python and store results.
"""
cpp_dir = os.path.join(self.cpp_output_dir, 'resnet')
py_dir = os.path.join(self.python_output_dir, 'resnet_debug')
results = compare_resnet_debug_tensors(cpp_dir, py_dir, sample_idx=sample_idx, verbose=verbose)
self.resnet_debug_results = results
self.all_comparison_stats['ResNetDebug'] = results
def generate_html_report(self):
print("\nGenerating HTML report...")
report_path = os.path.join(self.comparison_dir, "report.html")
@ -1260,6 +1269,23 @@ class ComparisonRunner:
f.write(html_content)
print(f"HTML report generated at {report_path}")
# Add ResNet Debug Output Comparison Section
if 'ResNetDebug' in self.all_comparison_stats:
html_content += "<h2>ResNet Intermediate Debug Output Comparison</h2>"
html_content += "<table><tr><th>Stage</th><th>Cosine Similarity</th><th>Allclose</th><th>Max Abs Diff</th><th>CPP Shape</th><th>PY Shape</th></tr>"
for stage, stats in self.all_comparison_stats['ResNetDebug'].items():
html_content += f"<tr><td>{stage}</td><td>{stats['cosine_similarity']:.6f}</td><td>{stats['allclose']}</td><td>{stats['max_abs_diff']:.6f}</td><td>{stats['cpp_shape']}</td><td>{stats['py_shape']}</td></tr>"
html_content += "</table>"
# ... rest of HTML ...
html_content += "</body></html>"
# Save HTML
report_path = os.path.join(self.comparison_dir, "comparison_report.html")
with open(report_path, "w") as f:
f.write(html_content)
print(f"HTML report generated at: {report_path}")
return report_path
def _generate_single_plot(self, error_array, title, plot_path, mean_val, std_abs_err, mae, max_err):
if error_array is None or len(error_array) == 0 or np.all(np.isnan(error_array)):
# print(f"Skipping plot for {title} as error_array is empty or all NaNs.")
@ -1287,6 +1313,10 @@ class ComparisonRunner:
self.compare_classifier()
self.compare_bb_regressor()
self.compare_preprocessed_inputs() # ADDED
# Compare ResNet debug outputs before generating HTML
print("\nComparing ResNet intermediate debug outputs...")
self.compare_resnet_debug_outputs(sample_idx=0, verbose=True)
# ... rest of tests ...
self.generate_html_report()
print("All tests completed!")

BIN
test/exported_weights/backbone_pure_tensors/bn1_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/bn1_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/bn1_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/bn1_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/bn1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/conv1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/fc_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/fc_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn1_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn1_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn1_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn1_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn2_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn2_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn2_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn2_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn2_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn3_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn3_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn3_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn3_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_bn3_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_conv1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_conv2_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_conv3_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_downsample_0_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_0_downsample_1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn1_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn1_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn1_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn1_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn2_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn2_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn2_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn2_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn2_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn3_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn3_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn3_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn3_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_bn3_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_conv1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_conv2_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_1_conv3_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn1_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn1_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn1_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn1_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn2_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn2_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn2_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn2_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn2_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn3_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn3_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn3_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn3_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_bn3_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_conv1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_conv2_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer1_2_conv3_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn1_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn1_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn1_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn1_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn2_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn2_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn2_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn2_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn2_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn3_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn3_num_batches_tracked.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn3_running_mean.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn3_running_var.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_bn3_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_conv1_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_conv2_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_conv3_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_downsample_0_weight.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_downsample_1_bias.pt

BIN
test/exported_weights/backbone_pure_tensors/layer2_0_downsample_1_num_batches_tracked.pt

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save