{ "cells": [ { "cell_type": "markdown", "id": "22cf7236", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "# Module 1: Tensor - Core Data Structure\n", "\n", "Welcome to the Tensor module! This is where TinyTorch really begins. You'll implement the fundamental data structure that powers all ML systems.\n", "\n", "## Learning Goals\n", "- Understand tensors as N-dimensional arrays with ML-specific operations\n", "- Implement a complete Tensor class with arithmetic operations\n", "- Handle shape management, data types, and memory layout\n", "- Build the foundation for neural networks and automatic differentiation\n", "- Master the NBGrader workflow with comprehensive testing\n", "\n", "## Build โ†’ Use โ†’ Understand\n", "1. **Build**: Create the Tensor class with core operations\n", "2. **Use**: Perform tensor arithmetic and transformations\n", "3. **Understand**: How tensors form the foundation of ML systems" ] }, { "cell_type": "code", "execution_count": null, "id": "e714bc97", "metadata": { "nbgrader": { "grade": false, "grade_id": "tensor-imports", "locked": false, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "#| default_exp core.tensor\n", "\n", "#| export\n", "import numpy as np\n", "import sys\n", "from typing import Union, List, Tuple, Optional, Any" ] }, { "cell_type": "code", "execution_count": null, "id": "a683e086", "metadata": { "nbgrader": { "grade": false, "grade_id": "tensor-setup", "locked": false, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "print(\"๐Ÿ”ฅ TinyTorch Tensor Module\")\n", "print(f\"NumPy version: {np.__version__}\")\n", "print(f\"Python version: {sys.version_info.major}.{sys.version_info.minor}\")\n", "print(\"Ready to build tensors!\")" ] }, { "cell_type": "markdown", "id": "d48cc258", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## ๐Ÿ“ฆ Where This Code Lives in the Final Package\n", "\n", "**Learning Side:** You work in `modules/source/01_tensor/tensor_dev.py` \n", "**Building Side:** Code exports to `tinytorch.core.tensor`\n", "\n", "```python\n", "# Final package structure:\n", "from tinytorch.core.tensor import Tensor # The foundation of everything!\n", "from tinytorch.core.activations import ReLU, Sigmoid, Tanh\n", "from tinytorch.core.layers import Dense, Conv2D\n", "```\n", "\n", "**Why this matters:**\n", "- **Learning:** Focused modules for deep understanding\n", "- **Production:** Proper organization like PyTorch's `torch.Tensor`\n", "- **Consistency:** All tensor operations live together in `core.tensor`\n", "- **Foundation:** Every other module depends on Tensor" ] }, { "cell_type": "markdown", "id": "aa5eb9a0", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## Step 1: What is a Tensor?\n", "\n", "### Definition\n", "A **tensor** is an N-dimensional array with ML-specific operations. Think of it as a container that can hold data in multiple dimensions:\n", "\n", "- **Scalar** (0D): A single number - `5.0`\n", "- **Vector** (1D): A list of numbers - `[1, 2, 3]` \n", "- **Matrix** (2D): A 2D array - `[[1, 2], [3, 4]]`\n", "- **Higher dimensions**: 3D, 4D, etc. for images, video, batches\n", "\n", "### The Mathematical Foundation: From Scalars to Tensors\n", "Understanding tensors requires building from mathematical fundamentals:\n", "\n", "#### **Scalars (Rank 0)**\n", "- **Definition**: A single number with no direction\n", "- **Examples**: Temperature (25ยฐC), mass (5.2 kg), probability (0.7)\n", "- **Operations**: Addition, multiplication, comparison\n", "- **ML Context**: Loss values, learning rates, regularization parameters\n", "\n", "#### **Vectors (Rank 1)**\n", "- **Definition**: An ordered list of numbers with direction and magnitude\n", "- **Examples**: Position [x, y, z], RGB color [255, 128, 0], word embedding [0.1, -0.5, 0.8]\n", "- **Operations**: Dot product, cross product, norm calculation\n", "- **ML Context**: Feature vectors, gradients, model parameters\n", "\n", "#### **Matrices (Rank 2)**\n", "- **Definition**: A 2D array organizing data in rows and columns\n", "- **Examples**: Image (height ร— width), weight matrix (input ร— output), covariance matrix\n", "- **Operations**: Matrix multiplication, transpose, inverse, eigendecomposition\n", "- **ML Context**: Linear layer weights, attention matrices, batch data\n", "\n", "#### **Higher-Order Tensors (Rank 3+)**\n", "- **Definition**: Multi-dimensional arrays extending matrices\n", "- **Examples**: \n", " - **3D**: Video frames (time ร— height ร— width), RGB images (height ร— width ร— channels)\n", " - **4D**: Image batches (batch ร— height ร— width ร— channels)\n", " - **5D**: Video batches (batch ร— time ร— height ร— width ร— channels)\n", "- **Operations**: Tensor products, contractions, decompositions\n", "- **ML Context**: Convolutional features, RNN states, transformer attention\n", "\n", "### Why Tensors Matter in ML: The Computational Foundation\n", "\n", "#### **1. Unified Data Representation**\n", "Tensors provide a consistent way to represent all ML data:\n", "```python\n", "# All of these are tensors with different shapes\n", "scalar_loss = Tensor(0.5) # Shape: ()\n", "feature_vector = Tensor([1, 2, 3]) # Shape: (3,)\n", "weight_matrix = Tensor([[1, 2], [3, 4]]) # Shape: (2, 2)\n", "image_batch = Tensor(np.random.rand(32, 224, 224, 3)) # Shape: (32, 224, 224, 3)\n", "```\n", "\n", "#### **2. Efficient Batch Processing**\n", "ML systems process multiple samples simultaneously:\n", "```python\n", "# Instead of processing one image at a time:\n", "for image in images:\n", " result = model(image) # Slow: 1000 separate operations\n", "\n", "# Process entire batch at once:\n", "batch_result = model(image_batch) # Fast: 1 vectorized operation\n", "```\n", "\n", "#### **3. Hardware Acceleration**\n", "Modern hardware (GPUs, TPUs) excels at tensor operations:\n", "- **Parallel processing**: Multiple operations simultaneously\n", "- **Vectorization**: SIMD (Single Instruction, Multiple Data) operations\n", "- **Memory optimization**: Contiguous memory layout for cache efficiency\n", "\n", "#### **4. Automatic Differentiation**\n", "Tensors enable gradient computation through computational graphs:\n", "```python\n", "# Each tensor operation creates a node in the computation graph\n", "x = Tensor([1, 2, 3])\n", "y = x * 2 # Node: multiplication\n", "z = y + 1 # Node: addition\n", "loss = z.sum() # Node: summation\n", "# Gradients flow backward through this graph\n", "```\n", "\n", "### Real-World Examples: Tensors in Action\n", "\n", "#### **Computer Vision**\n", "- **Grayscale image**: 2D tensor `(height, width)` - `(28, 28)` for MNIST\n", "- **Color image**: 3D tensor `(height, width, channels)` - `(224, 224, 3)` for RGB\n", "- **Image batch**: 4D tensor `(batch, height, width, channels)` - `(32, 224, 224, 3)`\n", "- **Video**: 5D tensor `(batch, time, height, width, channels)`\n", "\n", "#### **Natural Language Processing**\n", "- **Word embedding**: 1D tensor `(embedding_dim,)` - `(300,)` for Word2Vec\n", "- **Sentence**: 2D tensor `(sequence_length, embedding_dim)` - `(50, 768)` for BERT\n", "- **Batch of sentences**: 3D tensor `(batch, sequence_length, embedding_dim)`\n", "\n", "#### **Audio Processing**\n", "- **Audio signal**: 1D tensor `(time_steps,)` - `(16000,)` for 1 second at 16kHz\n", "- **Spectrogram**: 2D tensor `(time_frames, frequency_bins)`\n", "- **Batch of audio**: 3D tensor `(batch, time_steps, features)`\n", "\n", "#### **Time Series**\n", "- **Single series**: 2D tensor `(time_steps, features)`\n", "- **Multiple series**: 3D tensor `(batch, time_steps, features)`\n", "- **Multivariate forecasting**: 4D tensor `(batch, time_steps, features, predictions)`\n", "\n", "### Why Not Just Use NumPy?\n", "\n", "While we use NumPy internally, our Tensor class adds ML-specific functionality:\n", "\n", "#### **1. ML-Specific Operations**\n", "- **Gradient tracking**: For automatic differentiation (coming in Module 7)\n", "- **GPU support**: For hardware acceleration (future extension)\n", "- **Broadcasting semantics**: ML-friendly dimension handling\n", "\n", "#### **2. Consistent API**\n", "- **Type safety**: Predictable behavior across operations\n", "- **Error checking**: Clear error messages for debugging\n", "- **Integration**: Seamless work with other TinyTorch components\n", "\n", "#### **3. Educational Value**\n", "- **Conceptual clarity**: Understand what tensors really are\n", "- **Implementation insight**: See how frameworks work internally\n", "- **Debugging skills**: Trace through tensor operations step by step\n", "\n", "#### **4. Extensibility**\n", "- **Future features**: Ready for gradients, GPU, distributed computing\n", "- **Customization**: Add domain-specific operations\n", "- **Optimization**: Profile and optimize specific use cases\n", "\n", "### Performance Considerations: Building Efficient Tensors\n", "\n", "#### **Memory Layout**\n", "- **Contiguous arrays**: Better cache locality and performance\n", "- **Data types**: `float32` vs `float64` trade-offs\n", "- **Memory sharing**: Avoid unnecessary copies\n", "\n", "#### **Vectorization**\n", "- **SIMD operations**: Single Instruction, Multiple Data\n", "- **Broadcasting**: Efficient operations on different shapes\n", "- **Batch operations**: Process multiple samples simultaneously\n", "\n", "#### **Numerical Stability**\n", "- **Precision**: Balancing speed and accuracy\n", "- **Overflow/underflow**: Handling extreme values\n", "- **Gradient flow**: Maintaining numerical stability for training\n", "\n", "Let's start building our tensor foundation!" ] }, { "cell_type": "markdown", "id": "16bd4e86", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## ๐Ÿง  The Mathematical Foundation\n", "\n", "### Linear Algebra Refresher\n", "Tensors are generalizations of scalars, vectors, and matrices:\n", "\n", "```\n", "Scalar (0D): 5\n", "Vector (1D): [1, 2, 3]\n", "Matrix (2D): [[1, 2], [3, 4]]\n", "Tensor (3D): [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]\n", "```\n", "\n", "### Why This Matters for Neural Networks\n", "- **Forward Pass**: Matrix multiplication between layers\n", "- **Batch Processing**: Multiple samples processed simultaneously\n", "- **Convolutions**: 3D operations on image data\n", "- **Gradients**: Derivatives computed across all dimensions\n", "\n", "### Connection to Real ML Systems\n", "Every major ML framework uses tensors:\n", "- **PyTorch**: `torch.Tensor`\n", "- **TensorFlow**: `tf.Tensor`\n", "- **JAX**: `jax.numpy.ndarray`\n", "- **TinyTorch**: `tinytorch.core.tensor.Tensor` (what we're building!)\n", "\n", "### Performance Considerations\n", "- **Memory Layout**: Contiguous arrays for cache efficiency\n", "- **Vectorization**: SIMD operations for speed\n", "- **Broadcasting**: Efficient operations on different shapes\n", "- **Type Consistency**: Avoiding unnecessary conversions" ] }, { "cell_type": "markdown", "id": "4b17f982", "metadata": { "cell_marker": "\"\"\"", "lines_to_next_cell": 1 }, "source": [ "## Step 2: The Tensor Class Foundation\n", "\n", "### Core Concept: Wrapping NumPy with ML Intelligence\n", "Our Tensor class wraps NumPy arrays with ML-specific functionality. This design pattern is used by all major ML frameworks:\n", "\n", "- **PyTorch**: `torch.Tensor` wraps ATen (C++ tensor library)\n", "- **TensorFlow**: `tf.Tensor` wraps Eigen (C++ linear algebra library)\n", "- **JAX**: `jax.numpy.ndarray` wraps XLA (Google's linear algebra compiler)\n", "- **TinyTorch**: `Tensor` wraps NumPy (Python's numerical computing library)\n", "\n", "### Design Requirements Analysis\n", "\n", "#### **1. Input Flexibility**\n", "Our tensor must handle diverse input types:\n", "```python\n", "# Scalars (Python numbers)\n", "t1 = Tensor(5) # int โ†’ numpy array\n", "t2 = Tensor(3.14) # float โ†’ numpy array\n", "\n", "# Lists (Python sequences)\n", "t3 = Tensor([1, 2, 3]) # list โ†’ numpy array\n", "t4 = Tensor([[1, 2], [3, 4]]) # nested list โ†’ 2D array\n", "\n", "# NumPy arrays (existing arrays)\n", "t5 = Tensor(np.array([1, 2, 3])) # array โ†’ tensor wrapper\n", "```\n", "\n", "#### **2. Type Management**\n", "ML systems need consistent, predictable types:\n", "- **Default behavior**: Auto-detect appropriate types\n", "- **Explicit control**: Allow manual type specification\n", "- **Performance optimization**: Prefer `float32` over `float64`\n", "- **Memory efficiency**: Use appropriate precision\n", "\n", "#### **3. Property Access**\n", "Essential tensor properties for ML operations:\n", "- **Shape**: Dimensions for compatibility checking\n", "- **Size**: Total elements for memory estimation\n", "- **Data type**: For numerical computation planning\n", "- **Data access**: For integration with other libraries\n", "\n", "#### **4. Arithmetic Operations**\n", "Support for mathematical operations:\n", "- **Element-wise**: Addition, multiplication, subtraction, division\n", "- **Broadcasting**: Operations on different shapes\n", "- **Type promotion**: Consistent result types\n", "- **Error handling**: Clear messages for incompatible operations\n", "\n", "### Implementation Strategy\n", "\n", "#### **Memory Management**\n", "- **Copy vs. Reference**: When to copy data vs. share memory\n", "- **Type conversion**: Efficient dtype changes\n", "- **Contiguous layout**: Ensure optimal memory access patterns\n", "\n", "#### **Error Handling**\n", "- **Input validation**: Check for valid input types\n", "- **Shape compatibility**: Verify operations are mathematically valid\n", "- **Informative messages**: Help users debug issues quickly\n", "\n", "#### **Performance Optimization**\n", "- **Lazy evaluation**: Defer expensive operations when possible\n", "- **Vectorization**: Use NumPy's optimized operations\n", "- **Memory reuse**: Minimize unnecessary allocations\n", "\n", "### Learning Objectives for Implementation\n", "\n", "By implementing this Tensor class, you'll learn:\n", "1. **Wrapper pattern**: How to extend existing libraries\n", "2. **Type system design**: Managing data types in numerical computing\n", "3. **API design**: Creating intuitive, consistent interfaces\n", "4. **Performance considerations**: Balancing flexibility and speed\n", "5. **Error handling**: Providing helpful feedback to users\n", "\n", "Let's implement our tensor foundation!" ] }, { "cell_type": "code", "execution_count": null, "id": "979e5313", "metadata": { "lines_to_next_cell": 1, "nbgrader": { "grade": false, "grade_id": "tensor-class", "locked": false, "schema_version": 3, "solution": true, "task": false } }, "outputs": [], "source": [ "#| export\n", "class Tensor:\n", " \"\"\"\n", " TinyTorch Tensor: N-dimensional array with ML operations.\n", " \n", " The fundamental data structure for all TinyTorch operations.\n", " Wraps NumPy arrays with ML-specific functionality.\n", " \"\"\"\n", " \n", " def __init__(self, data: Union[int, float, List, np.ndarray], dtype: Optional[str] = None):\n", " \"\"\"\n", " Create a new tensor from data.\n", " \n", " Args:\n", " data: Input data (scalar, list, or numpy array)\n", " dtype: Data type ('float32', 'int32', etc.). Defaults to auto-detect.\n", " \n", " TODO: Implement tensor creation with proper type handling.\n", " \n", " STEP-BY-STEP:\n", " 1. Check if data is a scalar (int/float) - convert to numpy array\n", " 2. Check if data is a list - convert to numpy array \n", " 3. Check if data is already a numpy array - use as-is\n", " 4. Apply dtype conversion if specified\n", " 5. Store the result in self._data\n", " \n", " EXAMPLE:\n", " Tensor(5) โ†’ stores np.array(5)\n", " Tensor([1, 2, 3]) โ†’ stores np.array([1, 2, 3])\n", " Tensor(np.array([1, 2, 3])) โ†’ stores the array directly\n", " \n", " HINTS:\n", " - Use isinstance() to check data types\n", " - Use np.array() for conversion\n", " - Handle dtype parameter for type conversion\n", " - Store the array in self._data\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " # Convert input to numpy array\n", " if isinstance(data, (int, float, np.number)):\n", " # Handle Python and NumPy scalars\n", " if dtype is None:\n", " # Auto-detect type: int for integers, float32 for floats\n", " if isinstance(data, int) or (isinstance(data, np.number) and np.issubdtype(type(data), np.integer)):\n", " dtype = 'int32'\n", " else:\n", " dtype = 'float32'\n", " self._data = np.array(data, dtype=dtype)\n", " elif isinstance(data, list):\n", " # Let NumPy auto-detect type, then convert if needed\n", " temp_array = np.array(data)\n", " if dtype is None:\n", " # Use NumPy's auto-detected type, but prefer float32 for floats\n", " if temp_array.dtype == np.float64:\n", " dtype = 'float32'\n", " else:\n", " dtype = str(temp_array.dtype)\n", " self._data = np.array(data, dtype=dtype)\n", " elif isinstance(data, np.ndarray):\n", " # Already a numpy array\n", " if dtype is None:\n", " # Keep existing dtype, but prefer float32 for float64\n", " if data.dtype == np.float64:\n", " dtype = 'float32'\n", " else:\n", " dtype = str(data.dtype)\n", " self._data = data.astype(dtype) if dtype != data.dtype else data.copy()\n", " else:\n", " # Try to convert unknown types\n", " self._data = np.array(data, dtype=dtype)\n", " ### END SOLUTION\n", "\n", " @property\n", " def data(self) -> np.ndarray:\n", " \"\"\"\n", " Access underlying numpy array.\n", " \n", " TODO: Return the stored numpy array.\n", " \n", " HINT: Return self._data (the array you stored in __init__)\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " return self._data\n", " ### END SOLUTION\n", " \n", " @property\n", " def shape(self) -> Tuple[int, ...]:\n", " \"\"\"\n", " Get tensor shape.\n", " \n", " TODO: Return the shape of the stored numpy array.\n", " \n", " HINT: Use .shape attribute of the numpy array\n", " EXAMPLE: Tensor([1, 2, 3]).shape should return (3,)\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " return self._data.shape\n", " ### END SOLUTION\n", " \n", " @property\n", " def size(self) -> int:\n", " \"\"\"\n", " Get total number of elements.\n", " \n", " TODO: Return the total number of elements in the tensor.\n", " \n", " HINT: Use .size attribute of the numpy array\n", " EXAMPLE: Tensor([1, 2, 3]).size should return 3\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " return self._data.size\n", " ### END SOLUTION\n", " \n", " @property\n", " def dtype(self) -> np.dtype:\n", " \"\"\"\n", " Get data type as numpy dtype.\n", " \n", " TODO: Return the data type of the stored numpy array.\n", " \n", " HINT: Use .dtype attribute of the numpy array\n", " EXAMPLE: Tensor([1, 2, 3]).dtype should return dtype('int32')\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " return self._data.dtype\n", " ### END SOLUTION\n", " \n", " def __repr__(self) -> str:\n", " \"\"\"\n", " String representation.\n", " \n", " TODO: Create a clear string representation of the tensor.\n", " \n", " APPROACH:\n", " 1. Convert the numpy array to a list for readable output\n", " 2. Include the shape and dtype information\n", " 3. Format: \"Tensor([data], shape=shape, dtype=dtype)\"\n", " \n", " EXAMPLE:\n", " Tensor([1, 2, 3]) โ†’ \"Tensor([1, 2, 3], shape=(3,), dtype=int32)\"\n", " \n", " HINTS:\n", " - Use .tolist() to convert numpy array to list\n", " - Include shape and dtype information\n", " - Keep format consistent and readable\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " return f\"Tensor({self._data.tolist()}, shape={self.shape}, dtype={self.dtype})\"\n", " ### END SOLUTION\n", "\n", " def add(self, other: 'Tensor') -> 'Tensor':\n", " \"\"\"\n", " Add two tensors element-wise.\n", " \n", " TODO: Implement tensor addition.\n", " \n", " APPROACH:\n", " 1. Add the numpy arrays using +\n", " 2. Return a new Tensor with the result\n", " 3. Handle broadcasting automatically\n", " \n", " EXAMPLE:\n", " Tensor([1, 2]) + Tensor([3, 4]) โ†’ Tensor([4, 6])\n", " \n", " HINTS:\n", " - Use self._data + other._data\n", " - Return Tensor(result)\n", " - NumPy handles broadcasting automatically\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " result = self._data + other._data\n", " return Tensor(result)\n", " ### END SOLUTION\n", "\n", " def multiply(self, other: 'Tensor') -> 'Tensor':\n", " \"\"\"\n", " Multiply two tensors element-wise.\n", " \n", " TODO: Implement tensor multiplication.\n", " \n", " APPROACH:\n", " 1. Multiply the numpy arrays using *\n", " 2. Return a new Tensor with the result\n", " 3. Handle broadcasting automatically\n", " \n", " EXAMPLE:\n", " Tensor([1, 2]) * Tensor([3, 4]) โ†’ Tensor([3, 8])\n", " \n", " HINTS:\n", " - Use self._data * other._data\n", " - Return Tensor(result)\n", " - This is element-wise, not matrix multiplication\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " result = self._data * other._data\n", " return Tensor(result)\n", " ### END SOLUTION\n", "\n", " def __add__(self, other: Union['Tensor', int, float]) -> 'Tensor':\n", " \"\"\"\n", " Addition operator: tensor + other\n", " \n", " TODO: Implement + operator for tensors.\n", " \n", " APPROACH:\n", " 1. If other is a Tensor, use tensor addition\n", " 2. If other is a scalar, convert to Tensor first\n", " 3. Return the result\n", " \n", " EXAMPLE:\n", " Tensor([1, 2]) + Tensor([3, 4]) โ†’ Tensor([4, 6])\n", " Tensor([1, 2]) + 5 โ†’ Tensor([6, 7])\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " if isinstance(other, Tensor):\n", " return self.add(other)\n", " else:\n", " return self.add(Tensor(other))\n", " ### END SOLUTION\n", "\n", " def __mul__(self, other: Union['Tensor', int, float]) -> 'Tensor':\n", " \"\"\"\n", " Multiplication operator: tensor * other\n", " \n", " TODO: Implement * operator for tensors.\n", " \n", " APPROACH:\n", " 1. If other is a Tensor, use tensor multiplication\n", " 2. If other is a scalar, convert to Tensor first\n", " 3. Return the result\n", " \n", " EXAMPLE:\n", " Tensor([1, 2]) * Tensor([3, 4]) โ†’ Tensor([3, 8])\n", " Tensor([1, 2]) * 3 โ†’ Tensor([3, 6])\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " if isinstance(other, Tensor):\n", " return self.multiply(other)\n", " else:\n", " return self.multiply(Tensor(other))\n", " ### END SOLUTION\n", "\n", " def __sub__(self, other: Union['Tensor', int, float]) -> 'Tensor':\n", " \"\"\"\n", " Subtraction operator: tensor - other\n", " \n", " TODO: Implement - operator for tensors.\n", " \n", " APPROACH:\n", " 1. Convert other to Tensor if needed\n", " 2. Subtract using numpy arrays\n", " 3. Return new Tensor with result\n", " \n", " EXAMPLE:\n", " Tensor([5, 6]) - Tensor([1, 2]) โ†’ Tensor([4, 4])\n", " Tensor([5, 6]) - 1 โ†’ Tensor([4, 5])\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " if isinstance(other, Tensor):\n", " result = self._data - other._data\n", " else:\n", " result = self._data - other\n", " return Tensor(result)\n", " ### END SOLUTION\n", "\n", " def __truediv__(self, other: Union['Tensor', int, float]) -> 'Tensor':\n", " \"\"\"\n", " Division operator: tensor / other\n", " \n", " TODO: Implement / operator for tensors.\n", " \n", " APPROACH:\n", " 1. Convert other to Tensor if needed\n", " 2. Divide using numpy arrays\n", " 3. Return new Tensor with result\n", " \n", " EXAMPLE:\n", " Tensor([6, 8]) / Tensor([2, 4]) โ†’ Tensor([3, 2])\n", " Tensor([6, 8]) / 2 โ†’ Tensor([3, 4])\n", " \"\"\"\n", " ### BEGIN SOLUTION\n", " if isinstance(other, Tensor):\n", " result = self._data / other._data\n", " else:\n", " result = self._data / other\n", " return Tensor(result)\n", " ### END SOLUTION" ] }, { "cell_type": "markdown", "id": "21e8f8e5", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "### ๐Ÿงช Unit Test: Tensor Creation\n", "\n", "Let's test your tensor creation implementation right away! This gives you immediate feedback on whether your `__init__` method works correctly.\n", "\n", "**This is a unit test** - it tests one specific function (tensor creation) in isolation." ] }, { "cell_type": "code", "execution_count": null, "id": "671ef61a", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-creation-immediate", "locked": true, "points": 5, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "# Test tensor creation immediately after implementation\n", "print(\"๐Ÿ”ฌ Unit Test: Tensor Creation...\")\n", "\n", "# Test basic tensor creation\n", "try:\n", " # Test scalar\n", " scalar = Tensor(5.0)\n", " assert hasattr(scalar, '_data'), \"Tensor should have _data attribute\"\n", " assert scalar._data.shape == (), f\"Scalar should have shape (), got {scalar._data.shape}\"\n", " print(\"โœ… Scalar creation works\")\n", " \n", " # Test vector\n", " vector = Tensor([1, 2, 3])\n", " assert vector._data.shape == (3,), f\"Vector should have shape (3,), got {vector._data.shape}\"\n", " print(\"โœ… Vector creation works\")\n", " \n", " # Test matrix\n", " matrix = Tensor([[1, 2], [3, 4]])\n", " assert matrix._data.shape == (2, 2), f\"Matrix should have shape (2, 2), got {matrix._data.shape}\"\n", " print(\"โœ… Matrix creation works\")\n", " \n", " print(\"๐Ÿ“ˆ Progress: Tensor Creation โœ“\")\n", " \n", "except Exception as e:\n", " print(f\"โŒ Tensor creation test failed: {e}\")\n", " raise\n", "\n", "print(\"๐ŸŽฏ Tensor creation behavior:\")\n", "print(\" Converts data to NumPy arrays\")\n", "print(\" Preserves shape and data type\")\n", "print(\" Stores in _data attribute\")" ] }, { "cell_type": "markdown", "id": "2c573d4c", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "### ๐Ÿงช Unit Test: Tensor Properties\n", "\n", "Now let's test that your tensor properties work correctly. This tests the @property methods you implemented.\n", "\n", "**This is a unit test** - it tests specific properties (shape, size, dtype, data) in isolation." ] }, { "cell_type": "code", "execution_count": null, "id": "3433a093", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-properties-immediate", "locked": true, "points": 5, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "# Test tensor properties immediately after implementation\n", "print(\"๐Ÿ”ฌ Unit Test: Tensor Properties...\")\n", "\n", "# Test properties with simple examples\n", "try:\n", " # Test with a simple matrix\n", " tensor = Tensor([[1, 2, 3], [4, 5, 6]])\n", " \n", " # Test shape property\n", " assert tensor.shape == (2, 3), f\"Shape should be (2, 3), got {tensor.shape}\"\n", " print(\"โœ… Shape property works\")\n", " \n", " # Test size property\n", " assert tensor.size == 6, f\"Size should be 6, got {tensor.size}\"\n", " print(\"โœ… Size property works\")\n", " \n", " # Test data property\n", " assert np.array_equal(tensor.data, np.array([[1, 2, 3], [4, 5, 6]])), \"Data property should return numpy array\"\n", " print(\"โœ… Data property works\")\n", " \n", " # Test dtype property\n", " assert tensor.dtype in [np.int32, np.int64], f\"Dtype should be int32 or int64, got {tensor.dtype}\"\n", " print(\"โœ… Dtype property works\")\n", " \n", " print(\"๐Ÿ“ˆ Progress: Tensor Properties โœ“\")\n", " \n", "except Exception as e:\n", " print(f\"โŒ Tensor properties test failed: {e}\")\n", " raise\n", "\n", "print(\"๐ŸŽฏ Tensor properties behavior:\")\n", "print(\" shape: Returns tuple of dimensions\")\n", "print(\" size: Returns total number of elements\")\n", "print(\" data: Returns underlying NumPy array\")\n", "print(\" dtype: Returns NumPy data type\")" ] }, { "cell_type": "markdown", "id": "bd229d8f", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "### ๐Ÿงช Unit Test: Tensor Arithmetic\n", "\n", "Let's test your tensor arithmetic operations. This tests the __add__, __mul__, __sub__, __truediv__ methods.\n", "\n", "**This is a unit test** - it tests specific arithmetic operations in isolation." ] }, { "cell_type": "code", "execution_count": null, "id": "44f8bbe9", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-arithmetic-immediate", "locked": true, "points": 5, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "# Test tensor arithmetic immediately after implementation\n", "print(\"๐Ÿ”ฌ Unit Test: Tensor Arithmetic...\")\n", "\n", "# Test basic arithmetic with simple examples\n", "try:\n", " # Test addition\n", " a = Tensor([1, 2, 3])\n", " b = Tensor([4, 5, 6])\n", " result = a + b\n", " expected = np.array([5, 7, 9])\n", " assert np.array_equal(result.data, expected), f\"Addition failed: expected {expected}, got {result.data}\"\n", " print(\"โœ… Addition works\")\n", " \n", " # Test scalar addition\n", " result_scalar = a + 10\n", " expected_scalar = np.array([11, 12, 13])\n", " assert np.array_equal(result_scalar.data, expected_scalar), f\"Scalar addition failed: expected {expected_scalar}, got {result_scalar.data}\"\n", " print(\"โœ… Scalar addition works\")\n", " \n", " # Test multiplication\n", " result_mul = a * b\n", " expected_mul = np.array([4, 10, 18])\n", " assert np.array_equal(result_mul.data, expected_mul), f\"Multiplication failed: expected {expected_mul}, got {result_mul.data}\"\n", " print(\"โœ… Multiplication works\")\n", " \n", " # Test scalar multiplication\n", " result_scalar_mul = a * 2\n", " expected_scalar_mul = np.array([2, 4, 6])\n", " assert np.array_equal(result_scalar_mul.data, expected_scalar_mul), f\"Scalar multiplication failed: expected {expected_scalar_mul}, got {result_scalar_mul.data}\"\n", " print(\"โœ… Scalar multiplication works\")\n", " \n", " print(\"๐Ÿ“ˆ Progress: Tensor Arithmetic โœ“\")\n", " \n", "except Exception as e:\n", " print(f\"โŒ Tensor arithmetic test failed: {e}\")\n", " raise\n", "\n", "print(\"๐ŸŽฏ Tensor arithmetic behavior:\")\n", "print(\" Element-wise operations on tensors\")\n", "print(\" Broadcasting with scalars\")\n", "print(\" Returns new Tensor objects\")" ] }, { "cell_type": "markdown", "id": "17ec3cdc", "metadata": { "cell_marker": "\"\"\"", "lines_to_next_cell": 1 }, "source": [ "### ๐Ÿงช Comprehensive Test: Tensor Creation\n", "\n", "Let's thoroughly test your tensor creation to make sure it handles all the cases you'll encounter in ML.\n", "This tests the foundation of everything else we'll build." ] }, { "cell_type": "code", "execution_count": null, "id": "3936f449", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-creation-comprehensive", "locked": true, "points": 15, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "def test_tensor_creation():\n", " \"\"\"Comprehensive test of tensor creation with all data types and shapes.\"\"\"\n", " print(\"๐Ÿ”ฌ Testing comprehensive tensor creation...\")\n", " \n", " tests_passed = 0\n", " total_tests = 8\n", " \n", " # Test 1: Scalar creation (0D tensor)\n", " try:\n", " scalar_int = Tensor(42)\n", " scalar_float = Tensor(3.14)\n", " scalar_zero = Tensor(0)\n", " \n", " assert hasattr(scalar_int, '_data'), \"Tensor should have _data attribute\"\n", " assert scalar_int._data.shape == (), f\"Scalar should have shape (), got {scalar_int._data.shape}\"\n", " assert scalar_float._data.shape == (), f\"Float scalar should have shape (), got {scalar_float._data.shape}\"\n", " assert scalar_zero._data.shape == (), f\"Zero scalar should have shape (), got {scalar_zero._data.shape}\"\n", " \n", " print(\"โœ… Scalar creation: integers, floats, and zero\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Scalar creation failed: {e}\")\n", " \n", " # Test 2: Vector creation (1D tensor)\n", " try:\n", " vector_int = Tensor([1, 2, 3, 4, 5])\n", " vector_float = Tensor([1.0, 2.5, 3.7])\n", " vector_single = Tensor([42])\n", " vector_empty = Tensor([])\n", " \n", " assert vector_int._data.shape == (5,), f\"Int vector should have shape (5,), got {vector_int._data.shape}\"\n", " assert vector_float._data.shape == (3,), f\"Float vector should have shape (3,), got {vector_float._data.shape}\"\n", " assert vector_single._data.shape == (1,), f\"Single element vector should have shape (1,), got {vector_single._data.shape}\"\n", " assert vector_empty._data.shape == (0,), f\"Empty vector should have shape (0,), got {vector_empty._data.shape}\"\n", " \n", " print(\"โœ… Vector creation: integers, floats, single element, and empty\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Vector creation failed: {e}\")\n", " \n", " # Test 3: Matrix creation (2D tensor)\n", " try:\n", " matrix_2x2 = Tensor([[1, 2], [3, 4]])\n", " matrix_3x2 = Tensor([[1, 2], [3, 4], [5, 6]])\n", " matrix_1x3 = Tensor([[1, 2, 3]])\n", " \n", " assert matrix_2x2._data.shape == (2, 2), f\"2x2 matrix should have shape (2, 2), got {matrix_2x2._data.shape}\"\n", " assert matrix_3x2._data.shape == (3, 2), f\"3x2 matrix should have shape (3, 2), got {matrix_3x2._data.shape}\"\n", " assert matrix_1x3._data.shape == (1, 3), f\"1x3 matrix should have shape (1, 3), got {matrix_1x3._data.shape}\"\n", " \n", " print(\"โœ… Matrix creation: 2x2, 3x2, and 1x3 matrices\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Matrix creation failed: {e}\")\n", " \n", " # Test 4: Data type handling\n", " try:\n", " int_tensor = Tensor([1, 2, 3])\n", " float_tensor = Tensor([1.0, 2.0, 3.0])\n", " mixed_tensor = Tensor([1, 2.5, 3]) # Should convert to float\n", " \n", " # Check that data types are reasonable\n", " assert int_tensor._data.dtype in [np.int32, np.int64], f\"Int tensor has unexpected dtype: {int_tensor._data.dtype}\"\n", " assert float_tensor._data.dtype in [np.float32, np.float64], f\"Float tensor has unexpected dtype: {float_tensor._data.dtype}\"\n", " assert mixed_tensor._data.dtype in [np.float32, np.float64], f\"Mixed tensor should be float, got: {mixed_tensor._data.dtype}\"\n", " \n", " print(\"โœ… Data type handling: integers, floats, and mixed types\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Data type handling failed: {e}\")\n", " \n", " # Test 5: NumPy array input\n", " try:\n", " np_array = np.array([1, 2, 3, 4])\n", " tensor_from_np = Tensor(np_array)\n", " \n", " assert tensor_from_np._data.shape == (4,), f\"Tensor from NumPy should have shape (4,), got {tensor_from_np._data.shape}\"\n", " assert np.array_equal(tensor_from_np._data, np_array), \"Tensor from NumPy should preserve data\"\n", " \n", " print(\"โœ… NumPy array input: conversion works correctly\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ NumPy array input failed: {e}\")\n", " \n", " # Test 6: Large tensor creation\n", " try:\n", " large_tensor = Tensor(list(range(1000)))\n", " assert large_tensor._data.shape == (1000,), f\"Large tensor should have shape (1000,), got {large_tensor._data.shape}\"\n", " assert large_tensor._data[0] == 0, \"Large tensor should start with 0\"\n", " assert large_tensor._data[-1] == 999, \"Large tensor should end with 999\"\n", " \n", " print(\"โœ… Large tensor creation: 1000 elements\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Large tensor creation failed: {e}\")\n", " \n", " # Test 7: Negative numbers\n", " try:\n", " negative_tensor = Tensor([-1, -2, -3])\n", " mixed_signs = Tensor([-1, 0, 1])\n", " \n", " assert negative_tensor._data.shape == (3,), f\"Negative tensor should have shape (3,), got {negative_tensor._data.shape}\"\n", " assert np.array_equal(negative_tensor._data, np.array([-1, -2, -3])), \"Negative numbers should be preserved\"\n", " assert np.array_equal(mixed_signs._data, np.array([-1, 0, 1])), \"Mixed signs should be preserved\"\n", " \n", " print(\"โœ… Negative numbers: handled correctly\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Negative numbers failed: {e}\")\n", " \n", " # Test 8: Edge cases\n", " try:\n", " # Very large numbers\n", " big_tensor = Tensor([1e6, 1e-6])\n", " assert big_tensor._data.shape == (2,), \"Big numbers tensor should have correct shape\"\n", " \n", " # Zero tensor\n", " zero_tensor = Tensor([0, 0, 0])\n", " assert np.all(zero_tensor._data == 0), \"Zero tensor should contain all zeros\"\n", " \n", " print(\"โœ… Edge cases: large numbers and zeros\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Edge cases failed: {e}\")\n", " \n", " # Results summary\n", " print(f\"\\n๐Ÿ“Š Tensor Creation Results: {tests_passed}/{total_tests} tests passed\")\n", " \n", " if tests_passed == total_tests:\n", " print(\"๐ŸŽ‰ All tensor creation tests passed! Your Tensor class can handle:\")\n", " print(\" โ€ข Scalars, vectors, and matrices\")\n", " print(\" โ€ข Different data types (int, float)\")\n", " print(\" โ€ข NumPy arrays\")\n", " print(\" โ€ข Large tensors and edge cases\")\n", " print(\"๐Ÿ“ˆ Progress: Tensor Creation โœ“\")\n", " return True\n", " else:\n", " print(\"โš ๏ธ Some tensor creation tests failed. Common issues:\")\n", " print(\" โ€ข Check your __init__ method implementation\")\n", " print(\" โ€ข Make sure you're storing data in self._data\")\n", " print(\" โ€ข Verify NumPy array conversion works correctly\")\n", " print(\" โ€ข Test with different input types (int, float, list, np.array)\")\n", " return False\n", "\n", "# Run the comprehensive test\n", "success = test_tensor_creation()" ] }, { "cell_type": "markdown", "id": "da372e0a", "metadata": { "cell_marker": "\"\"\"", "lines_to_next_cell": 1 }, "source": [ "### ๐Ÿงช Comprehensive Test: Tensor Properties\n", "\n", "Now let's test all the properties your tensor should have. These properties are essential for ML operations." ] }, { "cell_type": "code", "execution_count": null, "id": "725ac665", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-properties-comprehensive", "locked": true, "points": 15, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "def test_tensor_properties():\n", " \"\"\"Comprehensive test of tensor properties (shape, size, dtype, data access).\"\"\"\n", " print(\"๐Ÿ”ฌ Testing comprehensive tensor properties...\")\n", " \n", " tests_passed = 0\n", " total_tests = 6\n", " \n", " # Test 1: Shape property\n", " try:\n", " scalar = Tensor(5.0)\n", " vector = Tensor([1, 2, 3])\n", " matrix = Tensor([[1, 2], [3, 4]])\n", " tensor_3d = Tensor([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])\n", " \n", " assert scalar.shape == (), f\"Scalar shape should be (), got {scalar.shape}\"\n", " assert vector.shape == (3,), f\"Vector shape should be (3,), got {vector.shape}\"\n", " assert matrix.shape == (2, 2), f\"Matrix shape should be (2, 2), got {matrix.shape}\"\n", " assert tensor_3d.shape == (2, 2, 2), f\"3D tensor shape should be (2, 2, 2), got {tensor_3d.shape}\"\n", " \n", " print(\"โœ… Shape property: scalar, vector, matrix, and 3D tensor\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Shape property failed: {e}\")\n", " \n", " # Test 2: Size property\n", " try:\n", " scalar = Tensor(5.0)\n", " vector = Tensor([1, 2, 3])\n", " matrix = Tensor([[1, 2], [3, 4]])\n", " empty = Tensor([])\n", " \n", " assert scalar.size == 1, f\"Scalar size should be 1, got {scalar.size}\"\n", " assert vector.size == 3, f\"Vector size should be 3, got {vector.size}\"\n", " assert matrix.size == 4, f\"Matrix size should be 4, got {matrix.size}\"\n", " assert empty.size == 0, f\"Empty tensor size should be 0, got {empty.size}\"\n", " \n", " print(\"โœ… Size property: scalar, vector, matrix, and empty tensor\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Size property failed: {e}\")\n", " \n", " # Test 3: Data type property\n", " try:\n", " int_tensor = Tensor([1, 2, 3])\n", " float_tensor = Tensor([1.0, 2.0, 3.0])\n", " \n", " # Check that dtype is accessible and reasonable\n", " assert hasattr(int_tensor, 'dtype'), \"Tensor should have dtype property\"\n", " assert hasattr(float_tensor, 'dtype'), \"Tensor should have dtype property\"\n", " \n", " # Data types should be NumPy dtypes\n", " assert isinstance(int_tensor.dtype, np.dtype), f\"dtype should be np.dtype, got {type(int_tensor.dtype)}\"\n", " assert isinstance(float_tensor.dtype, np.dtype), f\"dtype should be np.dtype, got {type(float_tensor.dtype)}\"\n", " \n", " print(f\"โœ… Data type property: int tensor is {int_tensor.dtype}, float tensor is {float_tensor.dtype}\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Data type property failed: {e}\")\n", " \n", " # Test 4: Data access property\n", " try:\n", " scalar = Tensor(5.0)\n", " vector = Tensor([1, 2, 3])\n", " matrix = Tensor([[1, 2], [3, 4]])\n", " \n", " # Test data access\n", " assert hasattr(scalar, 'data'), \"Tensor should have data property\"\n", " assert hasattr(vector, 'data'), \"Tensor should have data property\"\n", " assert hasattr(matrix, 'data'), \"Tensor should have data property\"\n", " \n", " # Test data content\n", " assert scalar.data.item() == 5.0, f\"Scalar data should be 5.0, got {scalar.data.item()}\"\n", " assert np.array_equal(vector.data, np.array([1, 2, 3])), \"Vector data mismatch\"\n", " assert np.array_equal(matrix.data, np.array([[1, 2], [3, 4]])), \"Matrix data mismatch\"\n", " \n", " print(\"โœ… Data access: scalar, vector, and matrix data retrieval\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Data access failed: {e}\")\n", " \n", " # Test 5: String representation\n", " try:\n", " scalar = Tensor(5.0)\n", " vector = Tensor([1, 2, 3])\n", " \n", " # Test that __repr__ works\n", " scalar_str = str(scalar)\n", " vector_str = str(vector)\n", " \n", " assert isinstance(scalar_str, str), \"Tensor string representation should be a string\"\n", " assert isinstance(vector_str, str), \"Tensor string representation should be a string\"\n", " assert len(scalar_str) > 0, \"Tensor string representation should not be empty\"\n", " assert len(vector_str) > 0, \"Tensor string representation should not be empty\"\n", " \n", " print(f\"โœ… String representation: scalar={scalar_str[:50]}{'...' if len(scalar_str) > 50 else ''}\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ String representation failed: {e}\")\n", " \n", " # Test 6: Property consistency\n", " try:\n", " test_cases = [\n", " Tensor(42),\n", " Tensor([1, 2, 3, 4, 5]),\n", " Tensor([[1, 2, 3], [4, 5, 6]]),\n", " Tensor([])\n", " ]\n", " \n", " for i, tensor in enumerate(test_cases):\n", " # Size should equal product of shape\n", " expected_size = np.prod(tensor.shape) if tensor.shape else 1\n", " assert tensor.size == expected_size, f\"Test case {i}: size {tensor.size} doesn't match shape {tensor.shape}\"\n", " \n", " # Data shape should match tensor shape\n", " assert tensor.data.shape == tensor.shape, f\"Test case {i}: data shape {tensor.data.shape} doesn't match tensor shape {tensor.shape}\"\n", " \n", " print(\"โœ… Property consistency: size matches shape, data shape matches tensor shape\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Property consistency failed: {e}\")\n", " \n", " # Results summary\n", " print(f\"\\n๐Ÿ“Š Tensor Properties Results: {tests_passed}/{total_tests} tests passed\")\n", " \n", " if tests_passed == total_tests:\n", " print(\"๐ŸŽ‰ All tensor property tests passed! Your tensor has:\")\n", " print(\" โ€ข Correct shape property for all dimensions\")\n", " print(\" โ€ข Accurate size calculation\")\n", " print(\" โ€ข Proper data type handling\")\n", " print(\" โ€ข Working data access\")\n", " print(\" โ€ข Good string representation\")\n", " print(\"๐Ÿ“ˆ Progress: Tensor Creation โœ“, Properties โœ“\")\n", " return True\n", " else:\n", " print(\"โš ๏ธ Some property tests failed. Common issues:\")\n", " print(\" โ€ข Check your @property decorators\")\n", " print(\" โ€ข Verify shape returns self._data.shape\")\n", " print(\" โ€ข Make sure size returns self._data.size\")\n", " print(\" โ€ข Ensure dtype returns self._data.dtype\")\n", " print(\" โ€ข Test your __repr__ method\")\n", " return False\n", "\n", "# Run the comprehensive test\n", "success = test_tensor_properties() and success" ] }, { "cell_type": "markdown", "id": "9c4fff8a", "metadata": { "cell_marker": "\"\"\"", "lines_to_next_cell": 1 }, "source": [ "### ๐Ÿงช Comprehensive Test: Tensor Arithmetic\n", "\n", "Let's test all arithmetic operations. These are the foundation of neural network computations!" ] }, { "cell_type": "code", "execution_count": null, "id": "6cde218c", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-arithmetic-comprehensive", "locked": true, "points": 20, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "def test_tensor_arithmetic():\n", " \"\"\"Comprehensive test of tensor arithmetic operations.\"\"\"\n", " print(\"๐Ÿ”ฌ Testing comprehensive tensor arithmetic...\")\n", " \n", " tests_passed = 0\n", " total_tests = 8\n", " \n", " # Test 1: Basic addition method\n", " try:\n", " a = Tensor([1, 2, 3])\n", " b = Tensor([4, 5, 6])\n", " c = a.add(b)\n", " \n", " expected = np.array([5, 7, 9])\n", " assert np.array_equal(c.data, expected), f\"Addition method failed: expected {expected}, got {c.data}\"\n", " assert isinstance(c, Tensor), \"Addition should return a Tensor\"\n", " \n", " print(f\"โœ… Addition method: {a.data} + {b.data} = {c.data}\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Addition method failed: {e}\")\n", " \n", " # Test 2: Basic multiplication method\n", " try:\n", " a = Tensor([1, 2, 3])\n", " b = Tensor([4, 5, 6])\n", " c = a.multiply(b)\n", " \n", " expected = np.array([4, 10, 18])\n", " assert np.array_equal(c.data, expected), f\"Multiplication method failed: expected {expected}, got {c.data}\"\n", " assert isinstance(c, Tensor), \"Multiplication should return a Tensor\"\n", " \n", " print(f\"โœ… Multiplication method: {a.data} * {b.data} = {c.data}\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Multiplication method failed: {e}\")\n", " \n", " # Test 3: Addition operator (+)\n", " try:\n", " a = Tensor([1, 2, 3])\n", " b = Tensor([4, 5, 6])\n", " c = a + b\n", " \n", " expected = np.array([5, 7, 9])\n", " assert np.array_equal(c.data, expected), f\"+ operator failed: expected {expected}, got {c.data}\"\n", " assert isinstance(c, Tensor), \"+ operator should return a Tensor\"\n", " \n", " print(f\"โœ… + operator: {a.data} + {b.data} = {c.data}\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ + operator failed: {e}\")\n", " \n", " # Test 4: Multiplication operator (*)\n", " try:\n", " a = Tensor([1, 2, 3])\n", " b = Tensor([4, 5, 6])\n", " c = a * b\n", " \n", " expected = np.array([4, 10, 18])\n", " assert np.array_equal(c.data, expected), f\"* operator failed: expected {expected}, got {c.data}\"\n", " assert isinstance(c, Tensor), \"* operator should return a Tensor\"\n", " \n", " print(f\"โœ… * operator: {a.data} * {b.data} = {c.data}\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ * operator failed: {e}\")\n", " \n", " # Test 5: Subtraction operator (-)\n", " try:\n", " a = Tensor([1, 2, 3])\n", " b = Tensor([4, 5, 6])\n", " c = b - a\n", " \n", " expected = np.array([3, 3, 3])\n", " assert np.array_equal(c.data, expected), f\"- operator failed: expected {expected}, got {c.data}\"\n", " assert isinstance(c, Tensor), \"- operator should return a Tensor\"\n", " \n", " print(f\"โœ… - operator: {b.data} - {a.data} = {c.data}\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ - operator failed: {e}\")\n", " \n", " # Test 6: Division operator (/)\n", " try:\n", " a = Tensor([1, 2, 4])\n", " b = Tensor([2, 4, 8])\n", " c = b / a\n", " \n", " expected = np.array([2.0, 2.0, 2.0])\n", " assert np.allclose(c.data, expected), f\"/ operator failed: expected {expected}, got {c.data}\"\n", " assert isinstance(c, Tensor), \"/ operator should return a Tensor\"\n", " \n", " print(f\"โœ… / operator: {b.data} / {a.data} = {c.data}\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ / operator failed: {e}\")\n", " \n", " # Test 7: Scalar operations\n", " try:\n", " a = Tensor([1, 2, 3])\n", " \n", " # Addition with scalar\n", " b = a + 10\n", " expected_add = np.array([11, 12, 13])\n", " assert np.array_equal(b.data, expected_add), f\"Scalar addition failed: expected {expected_add}, got {b.data}\"\n", " \n", " # Multiplication with scalar\n", " c = a * 2\n", " expected_mul = np.array([2, 4, 6])\n", " assert np.array_equal(c.data, expected_mul), f\"Scalar multiplication failed: expected {expected_mul}, got {c.data}\"\n", " \n", " # Subtraction with scalar\n", " d = a - 1\n", " expected_sub = np.array([0, 1, 2])\n", " assert np.array_equal(d.data, expected_sub), f\"Scalar subtraction failed: expected {expected_sub}, got {d.data}\"\n", " \n", " # Division with scalar\n", " e = a / 2\n", " expected_div = np.array([0.5, 1.0, 1.5])\n", " assert np.allclose(e.data, expected_div), f\"Scalar division failed: expected {expected_div}, got {e.data}\"\n", " \n", " print(f\"โœ… Scalar operations: +10, *2, -1, /2 all work correctly\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Scalar operations failed: {e}\")\n", " \n", " # Test 8: Matrix operations\n", " try:\n", " matrix_a = Tensor([[1, 2], [3, 4]])\n", " matrix_b = Tensor([[5, 6], [7, 8]])\n", " \n", " # Matrix addition\n", " c = matrix_a + matrix_b\n", " expected = np.array([[6, 8], [10, 12]])\n", " assert np.array_equal(c.data, expected), f\"Matrix addition failed: expected {expected}, got {c.data}\"\n", " assert c.shape == (2, 2), f\"Matrix addition should preserve shape, got {c.shape}\"\n", " \n", " # Matrix multiplication (element-wise)\n", " d = matrix_a * matrix_b\n", " expected_mul = np.array([[5, 12], [21, 32]])\n", " assert np.array_equal(d.data, expected_mul), f\"Matrix multiplication failed: expected {expected_mul}, got {d.data}\"\n", " \n", " print(f\"โœ… Matrix operations: 2x2 matrix addition and multiplication\")\n", " tests_passed += 1\n", " except Exception as e:\n", " print(f\"โŒ Matrix operations failed: {e}\")\n", " \n", " # Results summary\n", " print(f\"\\n๐Ÿ“Š Tensor Arithmetic Results: {tests_passed}/{total_tests} tests passed\")\n", " \n", " if tests_passed == total_tests:\n", " print(\"๐ŸŽ‰ All tensor arithmetic tests passed! Your tensor supports:\")\n", " print(\" โ€ข Basic methods: add(), multiply()\")\n", " print(\" โ€ข Python operators: +, -, *, /\")\n", " print(\" โ€ข Scalar operations: tensor + number\")\n", " print(\" โ€ข Matrix operations: element-wise operations\")\n", " print(\"๐Ÿ“ˆ Progress: Tensor Creation โœ“, Properties โœ“, Arithmetic โœ“\")\n", " return True\n", " else:\n", " print(\"โš ๏ธ Some arithmetic tests failed. Common issues:\")\n", " print(\" โ€ข Check your add() and multiply() methods\")\n", " print(\" โ€ข Verify operator overloading (__add__, __mul__, __sub__, __truediv__)\")\n", " print(\" โ€ข Make sure scalar operations work (convert scalar to Tensor)\")\n", " print(\" โ€ข Test with different tensor shapes\")\n", " return False\n", "\n", "# Run the comprehensive test\n", "success = test_tensor_arithmetic() and success" ] }, { "cell_type": "markdown", "id": "3f47b9eb", "metadata": { "cell_marker": "\"\"\"", "lines_to_next_cell": 1 }, "source": [ "### ๐Ÿงช Comprehensive Test: Real ML Scenario\n", "\n", "Let's test your tensor with a realistic machine learning scenario to make sure everything works together." ] }, { "cell_type": "code", "execution_count": null, "id": "f8886c53", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-comprehensive", "locked": true, "points": 10, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "def test_tensor():\n", " \"\"\"Comprehensive test with realistic ML scenario.\"\"\"\n", " print(\"๐Ÿ”ฌ Testing tensor comprehensively with ML scenario...\")\n", " \n", " try:\n", " print(\"๐Ÿง  Simulating a simple neural network forward pass...\")\n", " \n", " # Simulate input data (batch of 2 samples, 3 features each)\n", " X = Tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])\n", " print(f\"๐Ÿ“Š Input data shape: {X.shape}\")\n", " \n", " # Simulate weights (3 input features, 2 output neurons)\n", " W = Tensor([[0.1, 0.2], [0.3, 0.4], [0.5, 0.6]])\n", " print(f\"๐ŸŽฏ Weights shape: {W.shape}\")\n", " \n", " # Simulate bias (2 output neurons)\n", " b = Tensor([0.1, 0.2])\n", " print(f\"โš–๏ธ Bias shape: {b.shape}\")\n", " \n", " # Simple linear transformation: y = X * W + b\n", " # Note: This is a simplified version - real matrix multiplication would be different\n", " # But we can test element-wise operations\n", " \n", " # Test that we can do basic operations needed for ML\n", " sample = Tensor([1.0, 2.0, 3.0]) # Single sample\n", " weight_col = Tensor([0.1, 0.3, 0.5]) # First column of weights\n", " \n", " # Compute dot product manually using element-wise operations\n", " products = sample * weight_col # Element-wise multiplication\n", " print(f\"โœ… Element-wise multiplication works: {products.data}\")\n", " \n", " # Test addition for bias\n", " result = products + Tensor([0.1, 0.1, 0.1])\n", " print(f\"โœ… Bias addition works: {result.data}\")\n", " \n", " # Test with different shapes\n", " matrix_a = Tensor([[1, 2], [3, 4]])\n", " matrix_b = Tensor([[0.1, 0.2], [0.3, 0.4]])\n", " matrix_result = matrix_a * matrix_b\n", " print(f\"โœ… Matrix operations work: {matrix_result.data}\")\n", " \n", " # Test scalar operations (common in ML)\n", " scaled = sample * 0.5 # Learning rate scaling\n", " print(f\"โœ… Scalar scaling works: {scaled.data}\")\n", " \n", " # Test normalization-like operations\n", " mean_val = Tensor([2.0, 2.0, 2.0]) # Simulate mean\n", " normalized = sample - mean_val\n", " print(f\"โœ… Mean subtraction works: {normalized.data}\")\n", " \n", " print(\"\\n๐ŸŽ‰ Comprehensive test passed! Your tensor class can handle:\")\n", " print(\" โ€ข Multi-dimensional data (batches, features)\")\n", " print(\" โ€ข Element-wise operations needed for ML\")\n", " print(\" โ€ข Scalar operations (learning rates, normalization)\")\n", " print(\" โ€ข Matrix operations (weights, transformations)\")\n", " print(\"๐Ÿ“ˆ Progress: All tensor functionality โœ“\")\n", " print(\"๐Ÿš€ Ready for neural network layers!\")\n", " \n", " return True\n", " \n", " except Exception as e:\n", " print(f\"โŒ Comprehensive test failed: {e}\")\n", " print(\"\\n๐Ÿ’ก This suggests an issue with:\")\n", " print(\" โ€ข Basic tensor operations not working together\")\n", " print(\" โ€ข Shape handling problems\")\n", " print(\" โ€ข Arithmetic operation implementation\")\n", " print(\" โ€ข Check your tensor creation and arithmetic methods\")\n", " return False\n", "\n", "# Run the comprehensive test\n", "success = test_tensor() and success\n", "\n", "# Print final summary\n", "print(f\"\\n{'='*60}\")\n", "print(\"๐ŸŽฏ TENSOR MODULE TESTING COMPLETE\")\n", "print(f\"{'='*60}\")\n", "\n", "if success:\n", " print(\"๐ŸŽ‰ CONGRATULATIONS! All tensor tests passed!\")\n", " print(\"\\nโœ… Your Tensor class successfully implements:\")\n", " print(\" โ€ข Comprehensive tensor creation (scalars, vectors, matrices)\")\n", " print(\" โ€ข All essential properties (shape, size, dtype, data access)\")\n", " print(\" โ€ข Complete arithmetic operations (methods and operators)\")\n", " print(\" โ€ข Scalar and matrix operations\")\n", " print(\" โ€ข Real ML scenario compatibility\")\n", " print(\"\\n๐Ÿš€ You're ready to move to the next module!\")\n", " print(\"๐Ÿ“ˆ Final Progress: Tensor Module โœ“ COMPLETE\")\n", "else:\n", " print(\"โš ๏ธ Some tests failed. Please review the error messages above.\")\n", " print(\"\\n๐Ÿ”ง To fix issues:\")\n", " print(\" 1. Check the specific test that failed\")\n", " print(\" 2. Review the error message and hints\")\n", " print(\" 3. Fix your implementation\")\n", " print(\" 4. Re-run the notebook cells\")\n", " print(\"\\n๐Ÿ’ช Don't give up! Debugging is part of learning.\")" ] }, { "cell_type": "markdown", "id": "3b57c9d6", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## Step 3: Tensor Arithmetic Operations\n", "\n", "### Why Arithmetic Matters\n", "Tensor arithmetic is the foundation of all neural network operations:\n", "- **Forward pass**: Matrix multiplications and additions\n", "- **Activation functions**: Element-wise operations\n", "- **Loss computation**: Differences and squares\n", "- **Gradient computation**: Chain rule applications\n", "\n", "### Operations We'll Implement\n", "- **Addition**: Element-wise addition of tensors\n", "- **Multiplication**: Element-wise multiplication\n", "- **Python operators**: `+`, `-`, `*`, `/` for natural syntax\n", "- **Broadcasting**: Handle different shapes automatically" ] }, { "cell_type": "markdown", "id": "3f0eb365", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## Step 3: Tensor Arithmetic Methods\n", "\n", "The arithmetic methods are now part of the Tensor class above. Let's test them!" ] }, { "cell_type": "markdown", "id": "40cdfddf", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## Step 4: Python Operator Overloading\n", "\n", "### Why Operator Overloading?\n", "Python's magic methods allow us to use natural syntax:\n", "- `a + b` instead of `a.add(b)`\n", "- `a * b` instead of `a.multiply(b)`\n", "- `a - b` for subtraction\n", "- `a / b` for division\n", "\n", "This makes tensor operations feel natural and readable." ] }, { "cell_type": "markdown", "id": "304dbd38", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## Step 4: Operator Overloading\n", "\n", "The operator methods (__add__, __mul__, __sub__, __truediv__) are now part of the Tensor class above. This enables natural syntax like `a + b` and `a * b`." ] }, { "cell_type": "markdown", "id": "e84fa07f", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "### ๐Ÿงช Test Your Tensor Implementation\n", "\n", "Once you implement the Tensor class above, run these cells to test your implementation:" ] }, { "cell_type": "code", "execution_count": null, "id": "0c9d0587", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-creation", "locked": true, "points": 25, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "# Test tensor creation and properties\n", "print(\"๐Ÿ”ฌ Unit Test: Tensor Creation...\")\n", "\n", "# Test scalar creation\n", "scalar = Tensor(5.0)\n", "assert scalar.shape == (), f\"Scalar shape should be (), got {scalar.shape}\"\n", "assert scalar.size == 1, f\"Scalar size should be 1, got {scalar.size}\"\n", "assert scalar.data.item() == 5.0, f\"Scalar value should be 5.0, got {scalar.data.item()}\"\n", "\n", "# Test vector creation\n", "vector = Tensor([1, 2, 3])\n", "assert vector.shape == (3,), f\"Vector shape should be (3,), got {vector.shape}\"\n", "assert vector.size == 3, f\"Vector size should be 3, got {vector.size}\"\n", "assert np.array_equal(vector.data, np.array([1, 2, 3])), \"Vector data mismatch\"\n", "\n", "# Test matrix creation\n", "matrix = Tensor([[1, 2], [3, 4]])\n", "assert matrix.shape == (2, 2), f\"Matrix shape should be (2, 2), got {matrix.shape}\"\n", "assert matrix.size == 4, f\"Matrix size should be 4, got {matrix.size}\"\n", "assert np.array_equal(matrix.data, np.array([[1, 2], [3, 4]])), \"Matrix data mismatch\"\n", "\n", "# Test dtype handling\n", "float_tensor = Tensor([1.0, 2.0, 3.0])\n", "assert float_tensor.dtype == np.float32, f\"Float tensor dtype should be float32, got {float_tensor.dtype}\"\n", "\n", "int_tensor = Tensor([1, 2, 3])\n", "# Note: NumPy may default to int64 on some systems, so we check for integer types\n", "assert int_tensor.dtype in [np.int32, np.int64], f\"Int tensor dtype should be int32 or int64, got {int_tensor.dtype}\"\n", "\n", "print(\"โœ… Tensor creation tests passed!\")\n", "print(f\"โœ… Scalar: {scalar}\")\n", "print(f\"โœ… Vector: {vector}\")\n", "print(f\"โœ… Matrix: {matrix}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "fad1b147", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-arithmetic", "locked": true, "points": 25, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "# Test tensor arithmetic operations\n", "print(\"๐Ÿ”ฌ Unit Test: Tensor Arithmetic...\")\n", "\n", "# Test addition\n", "a = Tensor([1, 2, 3])\n", "b = Tensor([4, 5, 6])\n", "c = a + b\n", "expected = np.array([5, 7, 9])\n", "assert np.array_equal(c.data, expected), f\"Addition failed: expected {expected}, got {c.data}\"\n", "\n", "# Test multiplication\n", "d = a * b\n", "expected = np.array([4, 10, 18])\n", "assert np.array_equal(d.data, expected), f\"Multiplication failed: expected {expected}, got {d.data}\"\n", "\n", "# Test subtraction\n", "e = b - a\n", "expected = np.array([3, 3, 3])\n", "assert np.array_equal(e.data, expected), f\"Subtraction failed: expected {expected}, got {e.data}\"\n", "\n", "# Test division\n", "f = b / a\n", "expected = np.array([4.0, 2.5, 2.0])\n", "assert np.allclose(f.data, expected), f\"Division failed: expected {expected}, got {f.data}\"\n", "\n", "# Test scalar operations\n", "g = a + 10\n", "expected = np.array([11, 12, 13])\n", "assert np.array_equal(g.data, expected), f\"Scalar addition failed: expected {expected}, got {g.data}\"\n", "\n", "h = a * 2\n", "expected = np.array([2, 4, 6])\n", "assert np.array_equal(h.data, expected), f\"Scalar multiplication failed: expected {expected}, got {h.data}\"\n", "\n", "print(\"โœ… Tensor arithmetic tests passed!\")\n", "print(f\"โœ… Addition: {a} + {b} = {c}\")\n", "print(f\"โœ… Multiplication: {a} * {b} = {d}\")\n", "print(f\"โœ… Subtraction: {b} - {a} = {e}\")\n", "print(f\"โœ… Division: {b} / {a} = {f}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "49a4cb30", "metadata": { "nbgrader": { "grade": true, "grade_id": "test-tensor-broadcasting", "locked": true, "points": 25, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "# Test tensor broadcasting\n", "print(\"๐Ÿ”ฌ Unit Test: Tensor Broadcasting...\")\n", "\n", "# Test scalar broadcasting\n", "matrix = Tensor([[1, 2], [3, 4]])\n", "scalar = Tensor(10)\n", "result = matrix + scalar\n", "expected = np.array([[11, 12], [13, 14]])\n", "assert np.array_equal(result.data, expected), f\"Scalar broadcasting failed: expected {expected}, got {result.data}\"\n", "\n", "# Test vector broadcasting\n", "vector = Tensor([1, 2])\n", "result = matrix + vector\n", "expected = np.array([[2, 4], [4, 6]])\n", "assert np.array_equal(result.data, expected), f\"Vector broadcasting failed: expected {expected}, got {result.data}\"\n", "\n", "# Test different shapes\n", "a = Tensor([[1], [2], [3]]) # (3, 1)\n", "b = Tensor([10, 20]) # (2,)\n", "result = a + b\n", "expected = np.array([[11, 21], [12, 22], [13, 23]])\n", "assert np.array_equal(result.data, expected), f\"Shape broadcasting failed: expected {expected}, got {result.data}\"\n", "\n", "print(\"โœ… Tensor broadcasting tests passed!\")\n", "print(f\"โœ… Matrix + Scalar: {matrix} + {scalar} = {result}\")\n", "print(f\"โœ… Broadcasting works correctly!\")" ] }, { "cell_type": "markdown", "id": "be4f5e01", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## ๐ŸŽฏ Module Summary\n", "\n", "Congratulations! You've successfully implemented the core Tensor class for TinyTorch:\n", "\n", "### What You've Accomplished\n", "โœ… **Tensor Creation**: Handle scalars, vectors, matrices, and higher-dimensional arrays \n", "โœ… **Data Types**: Proper dtype handling with auto-detection and conversion \n", "โœ… **Properties**: Shape, size, dtype, and data access \n", "โœ… **Arithmetic**: Addition, multiplication, subtraction, division \n", "โœ… **Operators**: Natural Python syntax with `+`, `-`, `*`, `/` \n", "โœ… **Broadcasting**: Automatic shape compatibility like NumPy \n", "\n", "### Key Concepts You've Learned\n", "- **Tensors** are the fundamental data structure for ML systems\n", "- **NumPy backend** provides efficient computation with ML-friendly API\n", "- **Operator overloading** makes tensor operations feel natural\n", "- **Broadcasting** enables flexible operations between different shapes\n", "- **Type safety** ensures consistent behavior across operations" ] }, { "cell_type": "markdown", "id": "7821d8f9", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## ๐Ÿงช Module Testing\n", "\n", "Time to test your implementation! This section uses TinyTorch's standardized testing framework to ensure your implementation works correctly.\n", "\n", "**This testing section is locked** - it provides consistent feedback across all modules and cannot be modified." ] }, { "cell_type": "code", "execution_count": null, "id": "06c37168", "metadata": { "nbgrader": { "grade": false, "grade_id": "standardized-testing", "locked": true, "schema_version": 3, "solution": false, "task": false } }, "outputs": [], "source": [ "# =============================================================================\n", "# STANDARDIZED MODULE TESTING - DO NOT MODIFY\n", "# This cell is locked to ensure consistent testing across all TinyTorch modules\n", "# =============================================================================\n", "\n", "if __name__ == \"__main__\":\n", " from tito.tools.testing import run_module_tests_auto\n", " \n", " # Automatically discover and run all tests in this module\n", " success = run_module_tests_auto(\"Tensor\")" ] }, { "cell_type": "markdown", "id": "9ce729cc", "metadata": { "cell_marker": "\"\"\"" }, "source": [ "## ๐ŸŽฏ Module Summary\n", "\n", "Congratulations! You've successfully implemented the core Tensor class for TinyTorch:\n", "\n", "### What You've Accomplished\n", "โœ… **Tensor Creation**: Handle scalars, vectors, matrices, and higher-dimensional arrays \n", "โœ… **Data Types**: Proper dtype handling with auto-detection and conversion \n", "โœ… **Properties**: Shape, size, dtype, and data access \n", "โœ… **Arithmetic**: Addition, multiplication, subtraction, division \n", "โœ… **Operators**: Natural Python syntax with `+`, `-`, `*`, `/` \n", "โœ… **Broadcasting**: Automatic shape compatibility like NumPy \n", "\n", "### Key Concepts You've Learned\n", "- **Tensors** are the fundamental data structure for ML systems\n", "- **NumPy backend** provides efficient computation with ML-friendly API\n", "- **Operator overloading** makes tensor operations feel natural\n", "- **Broadcasting** enables flexible operations between different shapes\n", "- **Type safety** ensures consistent behavior across operations\n", "\n", "### Next Steps\n", "1. **Export your code**: `tito package nbdev --export 01_tensor`\n", "2. **Test your implementation**: `tito module test 01_tensor`\n", "3. **Use your tensors**: \n", " ```python\n", " from tinytorch.core.tensor import Tensor\n", " t = Tensor([1, 2, 3])\n", " print(t + 5) # Your tensor in action!\n", " ```\n", "4. **Move to Module 2**: Start building activation functions!\n", "\n", "**Ready for the next challenge?** Let's add the mathematical functions that make neural networks powerful!" ] } ], "metadata": { "jupytext": { "main_language": "python" } }, "nbformat": 4, "nbformat_minor": 5 }