3.1.1. clumsygrad.tensor#
This module contains the Tensor class implementation for automatic differentiation. It supports basic tensor operations, tracks gradients, and can be used to build computational graphs for backpropagation. It also contains some utility functions for managing tensors and their gradients.
- class clumsygrad.tensor.TensorType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]#
Bases:
IntEnumDefines tensor types in the computational graph. Each type controls gradient computation and tensor behavior.
Examples
>>> input_tensor = Tensor([1, 2, 3], tensor_type=TensorType.INPUT) >>> param_tensor = Tensor([0.5, 0.3], tensor_type=TensorType.PARAMETER) >>> result = input_tensor + param_tensor # Creates INTERMEDIATE tensor
- INPUT = 0#
Input tensor that feeds data into the computation graph.
Use when: - You do not need gradients for this tensor. - It should be a constant or a placeholder within the computation graph.
- PARAMETER = 1#
Trainable parameter tensor (weights, biases).
Use when: - You want calculate gradients for this tensor. - You want to optimize this tensor during training.
- INTERMEDIATE = 2#
Intermediate computation result.
You are recommended not to use this type.
- class clumsygrad.tensor.Tensor(data: ndarray | list | float, tensor_type: TensorType = TensorType.INPUT)[source]#
Bases:
objectThe main Tensor class, comprising the core functionality for creation and manipulation of tensors in the computational graph.
- __init__(data: ndarray | list | float, tensor_type: TensorType = TensorType.INPUT)[source]#
Initialize a new tensor.
- Parameters:
data – The initial data for the tensor.
tensor_type (
TensorType) – The type of the tensor, as TensorType.INPUT/PARAMETER/INTERMEDIATE (default is INPUT).
Note
The tensor will not track/propagate gradients if it is of type INPUT.
If it is of type PARAMETER, it will be treated as a trainable parameter.
Do not use INTERMEDIATE type unless you are explicitly creating a node in the graph.
By default, data type is set to float32.
- reshape(new_shape: Tuple[int, ...]) Tensor[source]#
Reshape the tensor to a new shape.
- Parameters:
new_shape – The desired shape for the tensor.
- Returns:
A new Tensor with the reshaped data.
- Raises:
ValueError – If the new shape does not have the same number of elements as the original shape.
- backward(gradient: ndarray | float | None = None, keep_graph: bool = False)[source]#
backward pass to compute gradients. Once the backward pass is completed, the graph is freed from memory unless keep_graph is set to True. Only the current tensor and all INPUT/PARAMETER tensors will be retained in memory.
- Parameters:
gradient – Optional gradient to start the backward pass. If None, it assumes a scalar output and uses ones.
keep_graph – If True, keeps the computational graph for further backward passes.
- Raises:
RuntimeError – If the tensor does not require gradients or if the gradient is not compatible.
Note
Setting keep_graph=True inside a training loop can lead to memory leaks.
Example
>>> t = Tensor(np.array([1.0, 2.0, 3.0]), tensor_type=TensorType.PARAMETER) >>> y = t ** 2 + 3 * t + 2 >>> y.backward()
- class clumsygrad.tensor.TensorUtils[source]#
Bases:
object- static get_parameters(tensor: Tensor) List[Tensor][source]#
Collect all parameters in the computational graph starting from the given tensor.
- Parameters:
tensor – The starting tensor from which to collect parameters.
- Returns:
A list of Tensor objects that are parameters in the graph.
- static count_by_type(tensor: Tensor) Dict[TensorType, int][source]#
Counts the number of tensors of each type in the computational graph starting from the given tensor.
- Parameters:
tensor – The starting tensor from which to count tensor types.
- Returns:
A dictionary with counts of each tensor type (INPUT, PARAMETER, INTERMEDIATE).