What is the difference between .flatten and .view-1 in PyTorch?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
When building neural networks in PyTorch, you frequently need to reshape tensors into one dimension, for example before passing a feature map into a fully connected layer. The two most common ways to do this are .flatten() and .view(-1). They look similar and often produce the same result, but they behave differently under the hood, especially when tensors are not contiguous in memory. This article explains exactly when each method works, when it fails, and which one you should prefer.
What Contiguous Means
Before comparing the two methods, you need to understand memory layout. A tensor is "contiguous" when its elements are stored in a single, unbroken block of memory in row-major (C) order. Most tensors you create are contiguous by default:
However, certain operations like .transpose(), .permute(), or .narrow() return views that share the same underlying data but with a different stride pattern. These views are often non-contiguous:
How .view(-1) Works
.view() reshapes a tensor by reinterpreting its underlying data buffer. The -1 argument tells PyTorch to infer the size of that dimension automatically. For a full flatten, you use .view(-1) to collapse all dimensions into one:
The critical requirement is that .view() only works on contiguous tensors. If the tensor is not contiguous, it raises a RuntimeError:
To fix this, you must call .contiguous() first:
How .flatten() Works
.flatten() collapses one or more dimensions into a single dimension. By default, it flattens all dimensions:
The key difference is that .flatten() handles non-contiguous tensors automatically. If the tensor is already contiguous, it returns a view (no data copy). If it is not contiguous, it creates a contiguous copy and then returns the flattened result:
Partial Flattening
.flatten() supports flattening a specific range of dimensions, which .view(-1) cannot do as cleanly:
This is common in convolutional neural networks where you want to flatten spatial dimensions while keeping the batch dimension intact:
To achieve the same with .view(), you need to calculate the size manually:
Performance Considerations
When the tensor is contiguous, both .flatten() and .view(-1) return a view of the same data without copying. Performance is identical in this case.
When the tensor is non-contiguous, .flatten() creates a copy to make the data contiguous. This involves a memory allocation and a data copy, which adds overhead. The .view(-1) approach forces you to call .contiguous() explicitly, making the copy visible in your code:
Neither is faster than the other for non-contiguous tensors, since both need to copy data. The difference is only in explicitness.
Using .reshape() as an Alternative
PyTorch also provides .reshape(), which behaves like .view() when possible (returns a view) and falls back to copying when the tensor is non-contiguous. It is effectively the same behavior as .flatten() when used with -1:
The trade-off is that .reshape() does not guarantee a view, so if you need to ensure that changes to the reshaped tensor are reflected in the original, use .view().
Common Pitfalls
- Silent copies with
.flatten()and.reshape(): Because these methods handle non-contiguous tensors by copying, you might not realize you are working with a copy. Modifications to the flattened tensor will not affect the original. - RuntimeError with
.view(): If you call.view()on a non-contiguous tensor without.contiguous(), your code crashes at runtime. This is a frequent source of bugs after transpose or permute operations. - Forgetting
start_dimin CNNs: Calling.flatten()without arguments flattens the batch dimension too, which almost always causes a shape mismatch in the next layer. Use.flatten(1)to preserve the batch dimension. - Gradient flow: All three methods (
.view(),.flatten(),.reshape()) support autograd. Gradients flow through them correctly, so they are safe to use in training.
Summary
Use .flatten() when you want a safe, readable way to collapse dimensions that works regardless of memory layout. Use .view(-1) when you know the tensor is contiguous and you want to make that assumption explicit. For partial flattening in CNNs, .flatten(start_dim=1) is the cleanest option. When in doubt, prefer .flatten() because it handles edge cases automatically.

