Bug Description
`NeuralNetworkBase.GetOrCreateParameterBuffer()` permanently replaces layer tensor fields (`_weights`, `_biases`, etc.) with buffer-backed view tensors via `SetTrainableParameters()`. This breaks:
- Clone — GraphSAGE clone tries to reconstruct from the view tensors, which may have different metadata
- Shape assumptions — MemoryNetwork's `TensorMatMul` gets rank-1 views instead of rank-2 tensors
- Serialization — layers serialize the view tensor instead of the original data
Root Cause
`SetTrainableParameters(views)` replaces `_weights = views[0]` permanently. The replacement is meant for the tape to track operations, but it persists beyond the training step.
Proposed Fix
Scoped replacement — only replace during the training step scope:
```csharp
// Instead of permanent replacement:
trainable.SetTrainableParameters(views); // Mutates fields permanently
// Use scoped replacement that restores originals after training:
using var scope = trainable.UseParameterViews(views);
// ... tape forward + backward + update happens here ...
// scope.Dispose() restores original tensor references
```
This matches PyTorch where parameter buffers are contiguous storage but `nn.Parameter` objects maintain their identity.
Affected Models
MemoryNetwork (TensorMatMul rank mismatch), GraphSAGE (Clone constructor failure), DeepBelief (zero gradients), and potentially any model using Clone or serialization after training.
Bug Description
`NeuralNetworkBase.GetOrCreateParameterBuffer()` permanently replaces layer tensor fields (`_weights`, `_biases`, etc.) with buffer-backed view tensors via `SetTrainableParameters()`. This breaks:
Root Cause
`SetTrainableParameters(views)` replaces `_weights = views[0]` permanently. The replacement is meant for the tape to track operations, but it persists beyond the training step.
Proposed Fix
Scoped replacement — only replace during the training step scope:
```csharp
// Instead of permanent replacement:
trainable.SetTrainableParameters(views); // Mutates fields permanently
// Use scoped replacement that restores originals after training:
using var scope = trainable.UseParameterViews(views);
// ... tape forward + backward + update happens here ...
// scope.Dispose() restores original tensor references
```
This matches PyTorch where parameter buffers are contiguous storage but `nn.Parameter` objects maintain their identity.
Affected Models
MemoryNetwork (TensorMatMul rank mismatch), GraphSAGE (Clone constructor failure), DeepBelief (zero gradients), and potentially any model using Clone or serialization after training.