├── Deep Learning ├── .ipynb_checkpoints │ ├── PyTorch 1-checkpoint.ipynb │ ├── PyTorch 2-checkpoint.ipynb │ └── PyTorch-checkpoint.ipynb ├── PyTorch 1.ipynb ├── PyTorch 2.ipynb └── PyTorch.ipynb ├── ML ├── .ipynb_checkpoints │ └── Linear Regression-checkpoint.ipynb └── Linear Regression.ipynb ├── Python ├── Python Day1.ipynb ├── Python Day2.ipynb └── Python Day3.ipynb ├── README.md └── requirements.txt /Deep Learning/.ipynb_checkpoints/PyTorch 1-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | {"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[],"dockerImageVersionId":30699,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":5,"nbformat":4,"cells":[{"cell_type":"markdown","source":"#### What is PyTorch ? \nPyTorch is an open source machine learning and deep leaning framework. ","metadata":{}},{"cell_type":"markdown","source":"#### What can PyTorch be used for?\nPyTorch allows you to manipulate and process data and write machine learning algorithms using Python code.","metadata":{}},{"cell_type":"markdown","source":"#### Why use PyTorch?\nMachine learning researchers love using PyTorch. PyTorch is the most used deep learning framework on Papers With Code, a website for tracking machine learning research papers and the code repositories attached with them.\n\nPyTorch also helps take care of many things such as GPU acceleration (making your code run faster) behind the scenes.\n\nSo you can focus on manipulating data and writing algorithms and PyTorch will make sure it runs fast.\n\nAnd if companies such as Tesla and Meta (Facebook) use it to build models they deploy to power hundreds of applications, drive thousands of cars and deliver content to billions of people, it's clearly capable on the development front too.","metadata":{}},{"cell_type":"markdown","source":"#### Importing PyTorch ","metadata":{}},{"cell_type":"code","source":"import torch\n\n# check the version \ntorch.__version__","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:25.439679Z","iopub.execute_input":"2024-05-18T06:15:25.440019Z","iopub.status.idle":"2024-05-18T06:15:29.501840Z","shell.execute_reply.started":"2024-05-18T06:15:25.439990Z","shell.execute_reply":"2024-05-18T06:15:29.500850Z"},"trusted":true},"execution_count":1,"outputs":[{"execution_count":1,"output_type":"execute_result","data":{"text/plain":"'2.1.2'"},"metadata":{}}]},{"cell_type":"markdown","source":"#### Introduction to Tensor \nTensors are n-dimensional array. ","metadata":{}},{"cell_type":"markdown","source":"#### Creating Tensor ","metadata":{}},{"cell_type":"code","source":"# scalar \n# A scalar is a single number and in tensor-speak it's a zero dimension tensor.\nscalar = torch.tensor(7)\nprint(scalar)","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:32.673323Z","iopub.execute_input":"2024-05-18T06:15:32.674246Z","iopub.status.idle":"2024-05-18T06:15:32.718263Z","shell.execute_reply.started":"2024-05-18T06:15:32.674214Z","shell.execute_reply":"2024-05-18T06:15:32.717365Z"},"trusted":true},"execution_count":2,"outputs":[{"name":"stdout","text":"tensor(7)\n","output_type":"stream"}]},{"cell_type":"code","source":"scalar.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:33.093395Z","iopub.execute_input":"2024-05-18T06:15:33.093763Z","iopub.status.idle":"2024-05-18T06:15:33.099502Z","shell.execute_reply.started":"2024-05-18T06:15:33.093735Z","shell.execute_reply":"2024-05-18T06:15:33.098551Z"},"trusted":true},"execution_count":3,"outputs":[{"execution_count":3,"output_type":"execute_result","data":{"text/plain":"0"},"metadata":{}}]},{"cell_type":"code","source":"# now if I want to retrieve the number from tensor \n# Get the Python number within a tensor (only works with one-element tensors)\nscalar.item()","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:33.363545Z","iopub.execute_input":"2024-05-18T06:15:33.363837Z","iopub.status.idle":"2024-05-18T06:15:33.369688Z","shell.execute_reply.started":"2024-05-18T06:15:33.363813Z","shell.execute_reply":"2024-05-18T06:15:33.368638Z"},"trusted":true},"execution_count":4,"outputs":[{"execution_count":4,"output_type":"execute_result","data":{"text/plain":"7"},"metadata":{}}]},{"cell_type":"code","source":"# vector \n# A vector is a single dimension tensor but can contain many numbers.\nvector = torch.tensor([1,3,4])\nprint(vector)","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:33.650909Z","iopub.execute_input":"2024-05-18T06:15:33.651256Z","iopub.status.idle":"2024-05-18T06:15:33.660079Z","shell.execute_reply.started":"2024-05-18T06:15:33.651228Z","shell.execute_reply":"2024-05-18T06:15:33.658977Z"},"trusted":true},"execution_count":5,"outputs":[{"name":"stdout","text":"tensor([1, 3, 4])\n","output_type":"stream"}]},{"cell_type":"markdown","source":"**How does the shape affects the dimension of the tensor ?** \nA tensor can have more than two dimensions. The dimensionality (or rank) of a tensor is the number of indices required to uniquely specify an element of the tensor.\n\nWhat does this means ? \nLet's say we have an array of a= [1,2,3]. So now if we are trying to access the element then\na[0] = 1 \na[1] = 2\na[2] = 3 \nHere, we can access the element with single indices. ","metadata":{}},{"cell_type":"code","source":"vector.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:34.153788Z","iopub.execute_input":"2024-05-18T06:15:34.154132Z","iopub.status.idle":"2024-05-18T06:15:34.159832Z","shell.execute_reply.started":"2024-05-18T06:15:34.154105Z","shell.execute_reply":"2024-05-18T06:15:34.158912Z"},"trusted":true},"execution_count":6,"outputs":[{"execution_count":6,"output_type":"execute_result","data":{"text/plain":"1"},"metadata":{}}]},{"cell_type":"code","source":"# check the shape of the vector \nvector.shape ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:34.395982Z","iopub.execute_input":"2024-05-18T06:15:34.396501Z","iopub.status.idle":"2024-05-18T06:15:34.402242Z","shell.execute_reply.started":"2024-05-18T06:15:34.396471Z","shell.execute_reply":"2024-05-18T06:15:34.401329Z"},"trusted":true},"execution_count":7,"outputs":[{"execution_count":7,"output_type":"execute_result","data":{"text/plain":"torch.Size([3])"},"metadata":{}}]},{"cell_type":"markdown","source":"**Fun Fact: Shape of a Vector**\n\n- One-Dimensional Vector:\n\nWhen we talk about a vector such as [1,3,4], it is commonly considered a one-dimensional array.\nIn this context, its shape is simply (3,), indicating it has 3 elements in one dimension.\n\n- Matrix Interpretation:\n\nIf we interpret [1,3,4] as a row vector in the context of a matrix, then it can indeed be viewed as a matrix with 1 row and 3 columns.\nIn this case, the shape would be (1,3).\n\n> Detailed Examples\n- As a One-Dimensional Vector:\n\nConsider [1,3,4] as a 1D array.\nShape: (3,), indicating a single dimension with 3 elements.\n\n- As a Row Vector in a Matrix:\n\nInterpreting [1,3,4] as a row vector in matrix form:\nShape: (1,3), indicating 1 row and 3 columns.\n\n- As a Column Vector:\n\nIf [1,3,4] were instead considered a column vector.\nShape: (3,1), indicating 3 rows and 1 column.","metadata":{}},{"cell_type":"markdown","source":"vector has a shape of [3]. This is because of the two elements we placed inside the square brackets ([1,3,4]).","metadata":{}},{"cell_type":"code","source":"# Matrix \nmatrix = torch.tensor([[1,2],\n [4,5]])\nmatrix ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:35.045008Z","iopub.execute_input":"2024-05-18T06:15:35.045366Z","iopub.status.idle":"2024-05-18T06:15:35.052716Z","shell.execute_reply.started":"2024-05-18T06:15:35.045338Z","shell.execute_reply":"2024-05-18T06:15:35.051701Z"},"trusted":true},"execution_count":8,"outputs":[{"execution_count":8,"output_type":"execute_result","data":{"text/plain":"tensor([[1, 2],\n [4, 5]])"},"metadata":{}}]},{"cell_type":"code","source":"matrix.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:35.272881Z","iopub.execute_input":"2024-05-18T06:15:35.273449Z","iopub.status.idle":"2024-05-18T06:15:35.278910Z","shell.execute_reply.started":"2024-05-18T06:15:35.273419Z","shell.execute_reply":"2024-05-18T06:15:35.278040Z"},"trusted":true},"execution_count":9,"outputs":[{"execution_count":9,"output_type":"execute_result","data":{"text/plain":"2"},"metadata":{}}]},{"cell_type":"code","source":"print(matrix[0][0]) \nprint(matrix[1][0])","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:35.478700Z","iopub.execute_input":"2024-05-18T06:15:35.479005Z","iopub.status.idle":"2024-05-18T06:15:35.485098Z","shell.execute_reply.started":"2024-05-18T06:15:35.478981Z","shell.execute_reply":"2024-05-18T06:15:35.484050Z"},"trusted":true},"execution_count":10,"outputs":[{"name":"stdout","text":"tensor(1)\ntensor(4)\n","output_type":"stream"}]},{"cell_type":"markdown","source":"Here we need two indices to access the element. Thus the dimension of the tensor is 2. ","metadata":{}},{"cell_type":"markdown","source":"The matrix having the shape of (2,2) is considered as 2 dimensional as it has two directions x and y. ","metadata":{}},{"cell_type":"code","source":"matrix.shape","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.080224Z","iopub.execute_input":"2024-05-18T06:15:36.080574Z","iopub.status.idle":"2024-05-18T06:15:36.086334Z","shell.execute_reply.started":"2024-05-18T06:15:36.080547Z","shell.execute_reply":"2024-05-18T06:15:36.085482Z"},"trusted":true},"execution_count":11,"outputs":[{"execution_count":11,"output_type":"execute_result","data":{"text/plain":"torch.Size([2, 2])"},"metadata":{}}]},{"cell_type":"code","source":"# Tensor \ntensor = torch.tensor([[[1,2,3],\n [3,3,3],\n [6,6,8]]])\ntensor ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.282112Z","iopub.execute_input":"2024-05-18T06:15:36.282453Z","iopub.status.idle":"2024-05-18T06:15:36.289820Z","shell.execute_reply.started":"2024-05-18T06:15:36.282426Z","shell.execute_reply":"2024-05-18T06:15:36.288768Z"},"trusted":true},"execution_count":12,"outputs":[{"execution_count":12,"output_type":"execute_result","data":{"text/plain":"tensor([[[1, 2, 3],\n [3, 3, 3],\n [6, 6, 8]]])"},"metadata":{}}]},{"cell_type":"code","source":"tensor.shape ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.503955Z","iopub.execute_input":"2024-05-18T06:15:36.504237Z","iopub.status.idle":"2024-05-18T06:15:36.509848Z","shell.execute_reply.started":"2024-05-18T06:15:36.504212Z","shell.execute_reply":"2024-05-18T06:15:36.508941Z"},"trusted":true},"execution_count":13,"outputs":[{"execution_count":13,"output_type":"execute_result","data":{"text/plain":"torch.Size([1, 3, 3])"},"metadata":{}}]},{"cell_type":"code","source":"tensor[0][2][2]\n# [0]: Accesses the first (and only) matrix in the tensor.\n# [2]: Accesses the third row of the matrix.\n# [2]: Accesses the third element in that row, which is 8.","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.692975Z","iopub.execute_input":"2024-05-18T06:15:36.693332Z","iopub.status.idle":"2024-05-18T06:15:36.700571Z","shell.execute_reply.started":"2024-05-18T06:15:36.693294Z","shell.execute_reply":"2024-05-18T06:15:36.699463Z"},"trusted":true},"execution_count":14,"outputs":[{"execution_count":14,"output_type":"execute_result","data":{"text/plain":"tensor(8)"},"metadata":{}}]},{"cell_type":"code","source":"tensor.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.894775Z","iopub.execute_input":"2024-05-18T06:15:36.895146Z","iopub.status.idle":"2024-05-18T06:15:36.901369Z","shell.execute_reply.started":"2024-05-18T06:15:36.895115Z","shell.execute_reply":"2024-05-18T06:15:36.900337Z"},"trusted":true},"execution_count":15,"outputs":[{"execution_count":15,"output_type":"execute_result","data":{"text/plain":"3"},"metadata":{}}]},{"cell_type":"markdown","source":"The dimensions go outer to inner.\n\nThat means there's 1 dimension of 3 by 3.","metadata":{}},{"cell_type":"code","source":"# when to use [1][][]\ntensor_list = [\n torch.tensor([[1, 2, 3],\n [3, 3, 3],\n [6, 6, 8]]),\n torch.tensor([[9, 10, 11],\n [12, 13, 14],\n [15, 16, 17]])\n]\n\nelement = tensor_list[1][2][2]\nprint(element) ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:37.294778Z","iopub.execute_input":"2024-05-18T06:15:37.295114Z","iopub.status.idle":"2024-05-18T06:15:37.301984Z","shell.execute_reply.started":"2024-05-18T06:15:37.295085Z","shell.execute_reply":"2024-05-18T06:15:37.301058Z"},"trusted":true},"execution_count":16,"outputs":[{"name":"stdout","text":"tensor(17)\n","output_type":"stream"}]},{"cell_type":"code","source":"tensor = torch.tensor([[1,2],\n [3,4],\n [6,7]])\ntensor ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:37.502885Z","iopub.execute_input":"2024-05-18T06:15:37.503165Z","iopub.status.idle":"2024-05-18T06:15:37.510139Z","shell.execute_reply.started":"2024-05-18T06:15:37.503134Z","shell.execute_reply":"2024-05-18T06:15:37.509293Z"},"trusted":true},"execution_count":17,"outputs":[{"execution_count":17,"output_type":"execute_result","data":{"text/plain":"tensor([[1, 2],\n [3, 4],\n [6, 7]])"},"metadata":{}}]},{"cell_type":"code","source":"tensor.shape ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:37.699194Z","iopub.execute_input":"2024-05-18T06:15:37.699527Z","iopub.status.idle":"2024-05-18T06:15:37.705255Z","shell.execute_reply.started":"2024-05-18T06:15:37.699503Z","shell.execute_reply":"2024-05-18T06:15:37.704422Z"},"trusted":true},"execution_count":18,"outputs":[{"execution_count":18,"output_type":"execute_result","data":{"text/plain":"torch.Size([3, 2])"},"metadata":{}}]},{"cell_type":"code","source":"# random tensor \nrandom_tensor = torch.randn(3,4)\nrandom_tensor , random_tensor.dtype","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:37.907121Z","iopub.execute_input":"2024-05-18T06:15:37.907418Z","iopub.status.idle":"2024-05-18T06:15:37.992924Z","shell.execute_reply.started":"2024-05-18T06:15:37.907392Z","shell.execute_reply":"2024-05-18T06:15:37.992059Z"},"trusted":true},"execution_count":19,"outputs":[{"execution_count":19,"output_type":"execute_result","data":{"text/plain":"(tensor([[ 0.0079, -0.1512, -0.2071, -0.3022],\n [-0.0874, 0.7005, 0.7586, 1.3575],\n [-0.6072, 0.5573, 2.7717, -0.5877]]),\n torch.float32)"},"metadata":{}}]},{"cell_type":"code","source":"# Create a random tensor of size (224, 224, 3) = img size \nrandom_image_size_tensor = torch.rand(size=(224, 224, 3))\nrandom_image_size_tensor.shape, random_image_size_tensor.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:38.118772Z","iopub.execute_input":"2024-05-18T06:15:38.119393Z","iopub.status.idle":"2024-05-18T06:15:38.127532Z","shell.execute_reply.started":"2024-05-18T06:15:38.119365Z","shell.execute_reply":"2024-05-18T06:15:38.126639Z"},"trusted":true},"execution_count":20,"outputs":[{"execution_count":20,"output_type":"execute_result","data":{"text/plain":"(torch.Size([224, 224, 3]), 3)"},"metadata":{}}]},{"cell_type":"markdown","source":"#### Zeros and ones ","metadata":{}},{"cell_type":"code","source":"zeros_tensor = torch.zeros(3,4)\nzeros_tensor","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:38.532535Z","iopub.execute_input":"2024-05-18T06:15:38.533229Z","iopub.status.idle":"2024-05-18T06:15:38.540257Z","shell.execute_reply.started":"2024-05-18T06:15:38.533197Z","shell.execute_reply":"2024-05-18T06:15:38.539300Z"},"trusted":true},"execution_count":21,"outputs":[{"execution_count":21,"output_type":"execute_result","data":{"text/plain":"tensor([[0., 0., 0., 0.],\n [0., 0., 0., 0.],\n [0., 0., 0., 0.]])"},"metadata":{}}]},{"cell_type":"code","source":"ones_tensor = torch.ones(3,4)\nones_tensor","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:38.728571Z","iopub.execute_input":"2024-05-18T06:15:38.728848Z","iopub.status.idle":"2024-05-18T06:15:38.737154Z","shell.execute_reply.started":"2024-05-18T06:15:38.728825Z","shell.execute_reply":"2024-05-18T06:15:38.736195Z"},"trusted":true},"execution_count":22,"outputs":[{"execution_count":22,"output_type":"execute_result","data":{"text/plain":"tensor([[1., 1., 1., 1.],\n [1., 1., 1., 1.],\n [1., 1., 1., 1.]])"},"metadata":{}}]},{"cell_type":"markdown","source":"#### Tensor DataType \nThere are many different tensor datatypes available in PyTorch.\n\nSome are specific for CPU and some are better for GPU.\n\nGetting to know which is which can take some time.\n\nGenerally if you see torch.cuda anywhere, the tensor is being used for GPU (since Nvidia GPUs use a computing toolkit called CUDA).\n\nThe most common type (and generally the default) is torch.float32 or torch.float.\n\nThis is referred to as \"32-bit floating point\".\n\nBut there's also 16-bit floating point (torch.float16 or torch.half) and 64-bit floating point (torch.float64 or torch.double).\n\nAnd to confuse things even more there's also 8-bit, 16-bit, 32-bit and 64-bit integers.","metadata":{}},{"cell_type":"code","source":"float32_tensor = torch.tensor([3.0, 6.0 ,9.0],\n requires_grad = False,\n device = None,\n dtype = None)\n\nfloat32_tensor","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:39.166966Z","iopub.execute_input":"2024-05-18T06:15:39.167291Z","iopub.status.idle":"2024-05-18T06:15:39.174427Z","shell.execute_reply.started":"2024-05-18T06:15:39.167252Z","shell.execute_reply":"2024-05-18T06:15:39.173614Z"},"trusted":true},"execution_count":23,"outputs":[{"execution_count":23,"output_type":"execute_result","data":{"text/plain":"tensor([3., 6., 9.])"},"metadata":{}}]},{"cell_type":"code","source":"float32_tensor.shape, float32_tensor.dtype, float32_tensor.device","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:39.389336Z","iopub.execute_input":"2024-05-18T06:15:39.389639Z","iopub.status.idle":"2024-05-18T06:15:39.395246Z","shell.execute_reply.started":"2024-05-18T06:15:39.389613Z","shell.execute_reply":"2024-05-18T06:15:39.394400Z"},"trusted":true},"execution_count":24,"outputs":[{"execution_count":24,"output_type":"execute_result","data":{"text/plain":"(torch.Size([3]), torch.float32, device(type='cpu'))"},"metadata":{}}]},{"cell_type":"markdown","source":"Aside from shape issues (tensor shapes don't match up), two of the other most common issues you'll come across in PyTorch are datatype and device issues.\n\nFor example, one of tensors is torch.float32 and the other is torch.float16 (PyTorch often likes tensors to be the same format).\n\nOr one of your tensors is on the CPU and the other is on the GPU (PyTorch likes calculations between tensors to be on the same device).","metadata":{}},{"cell_type":"markdown","source":"#### Tensor Multiplication ","metadata":{}},{"cell_type":"code","source":"tensor = torch.tensor([1,2,3])\ntensor.shape ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:39.994315Z","iopub.execute_input":"2024-05-18T06:15:39.994626Z","iopub.status.idle":"2024-05-18T06:15:40.000884Z","shell.execute_reply.started":"2024-05-18T06:15:39.994602Z","shell.execute_reply":"2024-05-18T06:15:39.999982Z"},"trusted":true},"execution_count":25,"outputs":[{"execution_count":25,"output_type":"execute_result","data":{"text/plain":"torch.Size([3])"},"metadata":{}}]},{"cell_type":"code","source":"# Element-wise matrix multiplication\ntensor * tensor ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:40.196112Z","iopub.execute_input":"2024-05-18T06:15:40.196863Z","iopub.status.idle":"2024-05-18T06:15:40.205169Z","shell.execute_reply.started":"2024-05-18T06:15:40.196830Z","shell.execute_reply":"2024-05-18T06:15:40.203830Z"},"trusted":true},"execution_count":26,"outputs":[{"execution_count":26,"output_type":"execute_result","data":{"text/plain":"tensor([1, 4, 9])"},"metadata":{}}]},{"cell_type":"code","source":"# Matrix multiplication\ntorch.matmul(tensor, tensor)","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:40.412301Z","iopub.execute_input":"2024-05-18T06:15:40.412578Z","iopub.status.idle":"2024-05-18T06:15:40.421135Z","shell.execute_reply.started":"2024-05-18T06:15:40.412553Z","shell.execute_reply":"2024-05-18T06:15:40.420327Z"},"trusted":true},"execution_count":27,"outputs":[{"execution_count":27,"output_type":"execute_result","data":{"text/plain":"tensor(14)"},"metadata":{}}]},{"cell_type":"code","source":"# Can also use the \"@\" symbol for matrix multiplication, though not recommended\ntensor @ tensor","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:40.628661Z","iopub.execute_input":"2024-05-18T06:15:40.629029Z","iopub.status.idle":"2024-05-18T06:15:40.636021Z","shell.execute_reply.started":"2024-05-18T06:15:40.628997Z","shell.execute_reply":"2024-05-18T06:15:40.634989Z"},"trusted":true},"execution_count":28,"outputs":[{"execution_count":28,"output_type":"execute_result","data":{"text/plain":"tensor(14)"},"metadata":{}}]},{"cell_type":"markdown","source":"The in-built torch.matmul() method is faster","metadata":{}},{"cell_type":"code","source":"tensor = torch.tensor([1, 2, 3])\ntensor.shape","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:41.063534Z","iopub.execute_input":"2024-05-18T06:15:41.063859Z","iopub.status.idle":"2024-05-18T06:15:41.070020Z","shell.execute_reply.started":"2024-05-18T06:15:41.063836Z","shell.execute_reply":"2024-05-18T06:15:41.069177Z"},"trusted":true},"execution_count":29,"outputs":[{"execution_count":29,"output_type":"execute_result","data":{"text/plain":"torch.Size([3])"},"metadata":{}}]},{"cell_type":"code","source":"%%time\n# Matrix multiplication by hand \n# (avoid doing operations with for loops at all cost, they are computationally expensive)\nvalue = 0\nfor i in range(len(tensor)):\n value += tensor[i] * tensor[i]\nvalue","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:41.279204Z","iopub.execute_input":"2024-05-18T06:15:41.279521Z","iopub.status.idle":"2024-05-18T06:15:41.292623Z","shell.execute_reply.started":"2024-05-18T06:15:41.279496Z","shell.execute_reply":"2024-05-18T06:15:41.291682Z"},"trusted":true},"execution_count":30,"outputs":[{"name":"stdout","text":"CPU times: user 1.63 ms, sys: 917 µs, total: 2.55 ms\nWall time: 5.84 ms\n","output_type":"stream"},{"execution_count":30,"output_type":"execute_result","data":{"text/plain":"tensor(14)"},"metadata":{}}]},{"cell_type":"code","source":"%%time\ntorch.matmul(tensor, tensor)","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:41.491520Z","iopub.execute_input":"2024-05-18T06:15:41.491800Z","iopub.status.idle":"2024-05-18T06:15:41.499219Z","shell.execute_reply.started":"2024-05-18T06:15:41.491778Z","shell.execute_reply":"2024-05-18T06:15:41.498316Z"},"trusted":true},"execution_count":31,"outputs":[{"name":"stdout","text":"CPU times: user 336 µs, sys: 84 µs, total: 420 µs\nWall time: 395 µs\n","output_type":"stream"},{"execution_count":31,"output_type":"execute_result","data":{"text/plain":"tensor(14)"},"metadata":{}}]},{"cell_type":"markdown","source":"### Running tensors on GPU (and making faster computations)","metadata":{}},{"cell_type":"markdown","source":"Deep learning algorithms require a lot of numerical operations.\n\nAnd by default these operations are often done on a CPU (computer processing unit).\n\nHowever, there's another common piece of hardware called a GPU (graphics processing unit), which is often much faster at performing the specific types of operations neural networks need (matrix multiplications) than CPUs.\n\nYour computer might have one.\n\nIf so, you should look to use it whenever you can to train neural networks because chances are it'll speed up the training time dramatically.\n\nThere are a few ways to first get access to a GPU and secondly get PyTorch to use the GPU.\n\nNote: When I reference \"GPU\" throughout this course, I'm referencing a Nvidia GPU with CUDA enabled (CUDA is a computing platform and API that helps allow GPUs be used for general purpose computing & not just graphics) unless otherwise specified.","metadata":{}},{"cell_type":"markdown","source":"#### 1. Getting a GPU\nTo check if you've got access to a Nvidia GPU, you can run !nvidia-smi where the ! (also called bang) means \"run this on the command line\".","metadata":{}},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:46.740635Z","iopub.execute_input":"2024-05-18T06:15:46.740977Z","iopub.status.idle":"2024-05-18T06:15:47.790734Z","shell.execute_reply.started":"2024-05-18T06:15:46.740948Z","shell.execute_reply":"2024-05-18T06:15:47.789363Z"},"trusted":true},"execution_count":32,"outputs":[{"name":"stdout","text":"Sat May 18 06:15:47 2024 \n+---------------------------------------------------------------------------------------+\n| NVIDIA-SMI 535.129.03 Driver Version: 535.129.03 CUDA Version: 12.2 |\n|-----------------------------------------+----------------------+----------------------+\n| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |\n| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |\n| | | MIG M. |\n|=========================================+======================+======================|\n| 0 Tesla T4 Off | 00000000:00:04.0 Off | 0 |\n| N/A 39C P8 9W / 70W | 0MiB / 15360MiB | 0% Default |\n| | | N/A |\n+-----------------------------------------+----------------------+----------------------+\n| 1 Tesla T4 Off | 00000000:00:05.0 Off | 0 |\n| N/A 40C P8 10W / 70W | 0MiB / 15360MiB | 0% Default |\n| | | N/A |\n+-----------------------------------------+----------------------+----------------------+\n \n+---------------------------------------------------------------------------------------+\n| Processes: |\n| GPU GI CI PID Type Process name GPU Memory |\n| ID ID Usage |\n|=======================================================================================|\n| No running processes found |\n+---------------------------------------------------------------------------------------+\n","output_type":"stream"}]},{"cell_type":"markdown","source":"#### 2. Getting PyTorch to run on the GPU\n","metadata":{}},{"cell_type":"code","source":"# Check for GPU\nimport torch\ntorch.cuda.is_available()","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:18:16.718994Z","iopub.execute_input":"2024-05-18T06:18:16.719414Z","iopub.status.idle":"2024-05-18T06:18:16.782514Z","shell.execute_reply.started":"2024-05-18T06:18:16.719382Z","shell.execute_reply":"2024-05-18T06:18:16.781474Z"},"trusted":true},"execution_count":33,"outputs":[{"execution_count":33,"output_type":"execute_result","data":{"text/plain":"True"},"metadata":{}}]},{"cell_type":"markdown","source":"If the above outputs True, PyTorch can see and use the GPU, if it outputs False, it can't see the GPU and in that case, you'll have to go back through the installation steps.\n\nNow, let's say you wanted to setup your code so it ran on CPU or the GPU if it was available.\n\nThat way, if you or someone decides to run your code, it'll work regardless of the computing device they're using.\n\nLet's create a device variable to store what kind of device is available.","metadata":{}},{"cell_type":"code","source":"# Set device type\ndevice = \"cuda\" if torch.cuda.is_available() else \"cpu\"\ndevice","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:19:02.218683Z","iopub.execute_input":"2024-05-18T06:19:02.219039Z","iopub.status.idle":"2024-05-18T06:19:02.225312Z","shell.execute_reply.started":"2024-05-18T06:19:02.219012Z","shell.execute_reply":"2024-05-18T06:19:02.224460Z"},"trusted":true},"execution_count":34,"outputs":[{"execution_count":34,"output_type":"execute_result","data":{"text/plain":"'cuda'"},"metadata":{}}]},{"cell_type":"markdown","source":"If the above output \"cuda\" it means we can set all of our PyTorch code to use the available CUDA device (a GPU) and if it output \"cpu\", our PyTorch code will stick with the CPU.","metadata":{}},{"cell_type":"code","source":"# Count number of devices\ntorch.cuda.device_count()","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:19:46.087424Z","iopub.execute_input":"2024-05-18T06:19:46.088136Z","iopub.status.idle":"2024-05-18T06:19:46.117115Z","shell.execute_reply.started":"2024-05-18T06:19:46.088103Z","shell.execute_reply":"2024-05-18T06:19:46.116140Z"},"trusted":true},"execution_count":35,"outputs":[{"execution_count":35,"output_type":"execute_result","data":{"text/plain":"2"},"metadata":{}}]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]} -------------------------------------------------------------------------------- /Deep Learning/.ipynb_checkpoints/PyTorch 2-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 5 6 | } 7 | -------------------------------------------------------------------------------- /Deep Learning/.ipynb_checkpoints/PyTorch-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 5 6 | } 7 | -------------------------------------------------------------------------------- /Deep Learning/PyTorch 1.ipynb: -------------------------------------------------------------------------------- 1 | {"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[],"dockerImageVersionId":30699,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":5,"nbformat":4,"cells":[{"cell_type":"markdown","source":"#### What is PyTorch ? \nPyTorch is an open source machine learning and deep leaning framework. ","metadata":{}},{"cell_type":"markdown","source":"#### What can PyTorch be used for?\nPyTorch allows you to manipulate and process data and write machine learning algorithms using Python code.","metadata":{}},{"cell_type":"markdown","source":"#### Why use PyTorch?\nMachine learning researchers love using PyTorch. PyTorch is the most used deep learning framework on Papers With Code, a website for tracking machine learning research papers and the code repositories attached with them.\n\nPyTorch also helps take care of many things such as GPU acceleration (making your code run faster) behind the scenes.\n\nSo you can focus on manipulating data and writing algorithms and PyTorch will make sure it runs fast.\n\nAnd if companies such as Tesla and Meta (Facebook) use it to build models they deploy to power hundreds of applications, drive thousands of cars and deliver content to billions of people, it's clearly capable on the development front too.","metadata":{}},{"cell_type":"markdown","source":"#### Importing PyTorch ","metadata":{}},{"cell_type":"code","source":"import torch\n\n# check the version \ntorch.__version__","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:25.439679Z","iopub.execute_input":"2024-05-18T06:15:25.440019Z","iopub.status.idle":"2024-05-18T06:15:29.501840Z","shell.execute_reply.started":"2024-05-18T06:15:25.439990Z","shell.execute_reply":"2024-05-18T06:15:29.500850Z"},"trusted":true},"execution_count":1,"outputs":[{"execution_count":1,"output_type":"execute_result","data":{"text/plain":"'2.1.2'"},"metadata":{}}]},{"cell_type":"markdown","source":"#### Introduction to Tensor \nTensors are n-dimensional array. ","metadata":{}},{"cell_type":"markdown","source":"#### Creating Tensor ","metadata":{}},{"cell_type":"code","source":"# scalar \n# A scalar is a single number and in tensor-speak it's a zero dimension tensor.\nscalar = torch.tensor(7)\nprint(scalar)","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:32.673323Z","iopub.execute_input":"2024-05-18T06:15:32.674246Z","iopub.status.idle":"2024-05-18T06:15:32.718263Z","shell.execute_reply.started":"2024-05-18T06:15:32.674214Z","shell.execute_reply":"2024-05-18T06:15:32.717365Z"},"trusted":true},"execution_count":2,"outputs":[{"name":"stdout","text":"tensor(7)\n","output_type":"stream"}]},{"cell_type":"code","source":"scalar.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:33.093395Z","iopub.execute_input":"2024-05-18T06:15:33.093763Z","iopub.status.idle":"2024-05-18T06:15:33.099502Z","shell.execute_reply.started":"2024-05-18T06:15:33.093735Z","shell.execute_reply":"2024-05-18T06:15:33.098551Z"},"trusted":true},"execution_count":3,"outputs":[{"execution_count":3,"output_type":"execute_result","data":{"text/plain":"0"},"metadata":{}}]},{"cell_type":"code","source":"# now if I want to retrieve the number from tensor \n# Get the Python number within a tensor (only works with one-element tensors)\nscalar.item()","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:33.363545Z","iopub.execute_input":"2024-05-18T06:15:33.363837Z","iopub.status.idle":"2024-05-18T06:15:33.369688Z","shell.execute_reply.started":"2024-05-18T06:15:33.363813Z","shell.execute_reply":"2024-05-18T06:15:33.368638Z"},"trusted":true},"execution_count":4,"outputs":[{"execution_count":4,"output_type":"execute_result","data":{"text/plain":"7"},"metadata":{}}]},{"cell_type":"code","source":"# vector \n# A vector is a single dimension tensor but can contain many numbers.\nvector = torch.tensor([1,3,4])\nprint(vector)","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:33.650909Z","iopub.execute_input":"2024-05-18T06:15:33.651256Z","iopub.status.idle":"2024-05-18T06:15:33.660079Z","shell.execute_reply.started":"2024-05-18T06:15:33.651228Z","shell.execute_reply":"2024-05-18T06:15:33.658977Z"},"trusted":true},"execution_count":5,"outputs":[{"name":"stdout","text":"tensor([1, 3, 4])\n","output_type":"stream"}]},{"cell_type":"markdown","source":"**How does the shape affects the dimension of the tensor ?** \nA tensor can have more than two dimensions. The dimensionality (or rank) of a tensor is the number of indices required to uniquely specify an element of the tensor.\n\nWhat does this means ? \nLet's say we have an array of a= [1,2,3]. So now if we are trying to access the element then\na[0] = 1 \na[1] = 2\na[2] = 3 \nHere, we can access the element with single indices. ","metadata":{}},{"cell_type":"code","source":"vector.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:34.153788Z","iopub.execute_input":"2024-05-18T06:15:34.154132Z","iopub.status.idle":"2024-05-18T06:15:34.159832Z","shell.execute_reply.started":"2024-05-18T06:15:34.154105Z","shell.execute_reply":"2024-05-18T06:15:34.158912Z"},"trusted":true},"execution_count":6,"outputs":[{"execution_count":6,"output_type":"execute_result","data":{"text/plain":"1"},"metadata":{}}]},{"cell_type":"code","source":"# check the shape of the vector \nvector.shape ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:34.395982Z","iopub.execute_input":"2024-05-18T06:15:34.396501Z","iopub.status.idle":"2024-05-18T06:15:34.402242Z","shell.execute_reply.started":"2024-05-18T06:15:34.396471Z","shell.execute_reply":"2024-05-18T06:15:34.401329Z"},"trusted":true},"execution_count":7,"outputs":[{"execution_count":7,"output_type":"execute_result","data":{"text/plain":"torch.Size([3])"},"metadata":{}}]},{"cell_type":"markdown","source":"**Fun Fact: Shape of a Vector**\n\n- One-Dimensional Vector:\n\nWhen we talk about a vector such as [1,3,4], it is commonly considered a one-dimensional array.\nIn this context, its shape is simply (3,), indicating it has 3 elements in one dimension.\n\n- Matrix Interpretation:\n\nIf we interpret [1,3,4] as a row vector in the context of a matrix, then it can indeed be viewed as a matrix with 1 row and 3 columns.\nIn this case, the shape would be (1,3).\n\n> Detailed Examples\n- As a One-Dimensional Vector:\n\nConsider [1,3,4] as a 1D array.\nShape: (3,), indicating a single dimension with 3 elements.\n\n- As a Row Vector in a Matrix:\n\nInterpreting [1,3,4] as a row vector in matrix form:\nShape: (1,3), indicating 1 row and 3 columns.\n\n- As a Column Vector:\n\nIf [1,3,4] were instead considered a column vector.\nShape: (3,1), indicating 3 rows and 1 column.","metadata":{}},{"cell_type":"markdown","source":"vector has a shape of [3]. This is because of the two elements we placed inside the square brackets ([1,3,4]).","metadata":{}},{"cell_type":"code","source":"# Matrix \nmatrix = torch.tensor([[1,2],\n [4,5]])\nmatrix ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:35.045008Z","iopub.execute_input":"2024-05-18T06:15:35.045366Z","iopub.status.idle":"2024-05-18T06:15:35.052716Z","shell.execute_reply.started":"2024-05-18T06:15:35.045338Z","shell.execute_reply":"2024-05-18T06:15:35.051701Z"},"trusted":true},"execution_count":8,"outputs":[{"execution_count":8,"output_type":"execute_result","data":{"text/plain":"tensor([[1, 2],\n [4, 5]])"},"metadata":{}}]},{"cell_type":"code","source":"matrix.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:35.272881Z","iopub.execute_input":"2024-05-18T06:15:35.273449Z","iopub.status.idle":"2024-05-18T06:15:35.278910Z","shell.execute_reply.started":"2024-05-18T06:15:35.273419Z","shell.execute_reply":"2024-05-18T06:15:35.278040Z"},"trusted":true},"execution_count":9,"outputs":[{"execution_count":9,"output_type":"execute_result","data":{"text/plain":"2"},"metadata":{}}]},{"cell_type":"code","source":"print(matrix[0][0]) \nprint(matrix[1][0])","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:35.478700Z","iopub.execute_input":"2024-05-18T06:15:35.479005Z","iopub.status.idle":"2024-05-18T06:15:35.485098Z","shell.execute_reply.started":"2024-05-18T06:15:35.478981Z","shell.execute_reply":"2024-05-18T06:15:35.484050Z"},"trusted":true},"execution_count":10,"outputs":[{"name":"stdout","text":"tensor(1)\ntensor(4)\n","output_type":"stream"}]},{"cell_type":"markdown","source":"Here we need two indices to access the element. Thus the dimension of the tensor is 2. ","metadata":{}},{"cell_type":"markdown","source":"The matrix having the shape of (2,2) is considered as 2 dimensional as it has two directions x and y. ","metadata":{}},{"cell_type":"code","source":"matrix.shape","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.080224Z","iopub.execute_input":"2024-05-18T06:15:36.080574Z","iopub.status.idle":"2024-05-18T06:15:36.086334Z","shell.execute_reply.started":"2024-05-18T06:15:36.080547Z","shell.execute_reply":"2024-05-18T06:15:36.085482Z"},"trusted":true},"execution_count":11,"outputs":[{"execution_count":11,"output_type":"execute_result","data":{"text/plain":"torch.Size([2, 2])"},"metadata":{}}]},{"cell_type":"code","source":"# Tensor \ntensor = torch.tensor([[[1,2,3],\n [3,3,3],\n [6,6,8]]])\ntensor ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.282112Z","iopub.execute_input":"2024-05-18T06:15:36.282453Z","iopub.status.idle":"2024-05-18T06:15:36.289820Z","shell.execute_reply.started":"2024-05-18T06:15:36.282426Z","shell.execute_reply":"2024-05-18T06:15:36.288768Z"},"trusted":true},"execution_count":12,"outputs":[{"execution_count":12,"output_type":"execute_result","data":{"text/plain":"tensor([[[1, 2, 3],\n [3, 3, 3],\n [6, 6, 8]]])"},"metadata":{}}]},{"cell_type":"code","source":"tensor.shape ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.503955Z","iopub.execute_input":"2024-05-18T06:15:36.504237Z","iopub.status.idle":"2024-05-18T06:15:36.509848Z","shell.execute_reply.started":"2024-05-18T06:15:36.504212Z","shell.execute_reply":"2024-05-18T06:15:36.508941Z"},"trusted":true},"execution_count":13,"outputs":[{"execution_count":13,"output_type":"execute_result","data":{"text/plain":"torch.Size([1, 3, 3])"},"metadata":{}}]},{"cell_type":"code","source":"tensor[0][2][2]\n# [0]: Accesses the first (and only) matrix in the tensor.\n# [2]: Accesses the third row of the matrix.\n# [2]: Accesses the third element in that row, which is 8.","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.692975Z","iopub.execute_input":"2024-05-18T06:15:36.693332Z","iopub.status.idle":"2024-05-18T06:15:36.700571Z","shell.execute_reply.started":"2024-05-18T06:15:36.693294Z","shell.execute_reply":"2024-05-18T06:15:36.699463Z"},"trusted":true},"execution_count":14,"outputs":[{"execution_count":14,"output_type":"execute_result","data":{"text/plain":"tensor(8)"},"metadata":{}}]},{"cell_type":"code","source":"tensor.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:36.894775Z","iopub.execute_input":"2024-05-18T06:15:36.895146Z","iopub.status.idle":"2024-05-18T06:15:36.901369Z","shell.execute_reply.started":"2024-05-18T06:15:36.895115Z","shell.execute_reply":"2024-05-18T06:15:36.900337Z"},"trusted":true},"execution_count":15,"outputs":[{"execution_count":15,"output_type":"execute_result","data":{"text/plain":"3"},"metadata":{}}]},{"cell_type":"markdown","source":"The dimensions go outer to inner.\n\nThat means there's 1 dimension of 3 by 3.","metadata":{}},{"cell_type":"code","source":"# when to use [1][][]\ntensor_list = [\n torch.tensor([[1, 2, 3],\n [3, 3, 3],\n [6, 6, 8]]),\n torch.tensor([[9, 10, 11],\n [12, 13, 14],\n [15, 16, 17]])\n]\n\nelement = tensor_list[1][2][2]\nprint(element) ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:37.294778Z","iopub.execute_input":"2024-05-18T06:15:37.295114Z","iopub.status.idle":"2024-05-18T06:15:37.301984Z","shell.execute_reply.started":"2024-05-18T06:15:37.295085Z","shell.execute_reply":"2024-05-18T06:15:37.301058Z"},"trusted":true},"execution_count":16,"outputs":[{"name":"stdout","text":"tensor(17)\n","output_type":"stream"}]},{"cell_type":"code","source":"tensor = torch.tensor([[1,2],\n [3,4],\n [6,7]])\ntensor ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:37.502885Z","iopub.execute_input":"2024-05-18T06:15:37.503165Z","iopub.status.idle":"2024-05-18T06:15:37.510139Z","shell.execute_reply.started":"2024-05-18T06:15:37.503134Z","shell.execute_reply":"2024-05-18T06:15:37.509293Z"},"trusted":true},"execution_count":17,"outputs":[{"execution_count":17,"output_type":"execute_result","data":{"text/plain":"tensor([[1, 2],\n [3, 4],\n [6, 7]])"},"metadata":{}}]},{"cell_type":"code","source":"tensor.shape ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:37.699194Z","iopub.execute_input":"2024-05-18T06:15:37.699527Z","iopub.status.idle":"2024-05-18T06:15:37.705255Z","shell.execute_reply.started":"2024-05-18T06:15:37.699503Z","shell.execute_reply":"2024-05-18T06:15:37.704422Z"},"trusted":true},"execution_count":18,"outputs":[{"execution_count":18,"output_type":"execute_result","data":{"text/plain":"torch.Size([3, 2])"},"metadata":{}}]},{"cell_type":"code","source":"# random tensor \nrandom_tensor = torch.randn(3,4)\nrandom_tensor , random_tensor.dtype","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:37.907121Z","iopub.execute_input":"2024-05-18T06:15:37.907418Z","iopub.status.idle":"2024-05-18T06:15:37.992924Z","shell.execute_reply.started":"2024-05-18T06:15:37.907392Z","shell.execute_reply":"2024-05-18T06:15:37.992059Z"},"trusted":true},"execution_count":19,"outputs":[{"execution_count":19,"output_type":"execute_result","data":{"text/plain":"(tensor([[ 0.0079, -0.1512, -0.2071, -0.3022],\n [-0.0874, 0.7005, 0.7586, 1.3575],\n [-0.6072, 0.5573, 2.7717, -0.5877]]),\n torch.float32)"},"metadata":{}}]},{"cell_type":"code","source":"# Create a random tensor of size (224, 224, 3) = img size \nrandom_image_size_tensor = torch.rand(size=(224, 224, 3))\nrandom_image_size_tensor.shape, random_image_size_tensor.ndim","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:38.118772Z","iopub.execute_input":"2024-05-18T06:15:38.119393Z","iopub.status.idle":"2024-05-18T06:15:38.127532Z","shell.execute_reply.started":"2024-05-18T06:15:38.119365Z","shell.execute_reply":"2024-05-18T06:15:38.126639Z"},"trusted":true},"execution_count":20,"outputs":[{"execution_count":20,"output_type":"execute_result","data":{"text/plain":"(torch.Size([224, 224, 3]), 3)"},"metadata":{}}]},{"cell_type":"markdown","source":"#### Zeros and ones ","metadata":{}},{"cell_type":"code","source":"zeros_tensor = torch.zeros(3,4)\nzeros_tensor","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:38.532535Z","iopub.execute_input":"2024-05-18T06:15:38.533229Z","iopub.status.idle":"2024-05-18T06:15:38.540257Z","shell.execute_reply.started":"2024-05-18T06:15:38.533197Z","shell.execute_reply":"2024-05-18T06:15:38.539300Z"},"trusted":true},"execution_count":21,"outputs":[{"execution_count":21,"output_type":"execute_result","data":{"text/plain":"tensor([[0., 0., 0., 0.],\n [0., 0., 0., 0.],\n [0., 0., 0., 0.]])"},"metadata":{}}]},{"cell_type":"code","source":"ones_tensor = torch.ones(3,4)\nones_tensor","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:38.728571Z","iopub.execute_input":"2024-05-18T06:15:38.728848Z","iopub.status.idle":"2024-05-18T06:15:38.737154Z","shell.execute_reply.started":"2024-05-18T06:15:38.728825Z","shell.execute_reply":"2024-05-18T06:15:38.736195Z"},"trusted":true},"execution_count":22,"outputs":[{"execution_count":22,"output_type":"execute_result","data":{"text/plain":"tensor([[1., 1., 1., 1.],\n [1., 1., 1., 1.],\n [1., 1., 1., 1.]])"},"metadata":{}}]},{"cell_type":"markdown","source":"#### Tensor DataType \nThere are many different tensor datatypes available in PyTorch.\n\nSome are specific for CPU and some are better for GPU.\n\nGetting to know which is which can take some time.\n\nGenerally if you see torch.cuda anywhere, the tensor is being used for GPU (since Nvidia GPUs use a computing toolkit called CUDA).\n\nThe most common type (and generally the default) is torch.float32 or torch.float.\n\nThis is referred to as \"32-bit floating point\".\n\nBut there's also 16-bit floating point (torch.float16 or torch.half) and 64-bit floating point (torch.float64 or torch.double).\n\nAnd to confuse things even more there's also 8-bit, 16-bit, 32-bit and 64-bit integers.","metadata":{}},{"cell_type":"code","source":"float32_tensor = torch.tensor([3.0, 6.0 ,9.0],\n requires_grad = False,\n device = None,\n dtype = None)\n\nfloat32_tensor","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:39.166966Z","iopub.execute_input":"2024-05-18T06:15:39.167291Z","iopub.status.idle":"2024-05-18T06:15:39.174427Z","shell.execute_reply.started":"2024-05-18T06:15:39.167252Z","shell.execute_reply":"2024-05-18T06:15:39.173614Z"},"trusted":true},"execution_count":23,"outputs":[{"execution_count":23,"output_type":"execute_result","data":{"text/plain":"tensor([3., 6., 9.])"},"metadata":{}}]},{"cell_type":"code","source":"float32_tensor.shape, float32_tensor.dtype, float32_tensor.device","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:39.389336Z","iopub.execute_input":"2024-05-18T06:15:39.389639Z","iopub.status.idle":"2024-05-18T06:15:39.395246Z","shell.execute_reply.started":"2024-05-18T06:15:39.389613Z","shell.execute_reply":"2024-05-18T06:15:39.394400Z"},"trusted":true},"execution_count":24,"outputs":[{"execution_count":24,"output_type":"execute_result","data":{"text/plain":"(torch.Size([3]), torch.float32, device(type='cpu'))"},"metadata":{}}]},{"cell_type":"markdown","source":"Aside from shape issues (tensor shapes don't match up), two of the other most common issues you'll come across in PyTorch are datatype and device issues.\n\nFor example, one of tensors is torch.float32 and the other is torch.float16 (PyTorch often likes tensors to be the same format).\n\nOr one of your tensors is on the CPU and the other is on the GPU (PyTorch likes calculations between tensors to be on the same device).","metadata":{}},{"cell_type":"markdown","source":"#### Tensor Multiplication ","metadata":{}},{"cell_type":"code","source":"tensor = torch.tensor([1,2,3])\ntensor.shape ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:39.994315Z","iopub.execute_input":"2024-05-18T06:15:39.994626Z","iopub.status.idle":"2024-05-18T06:15:40.000884Z","shell.execute_reply.started":"2024-05-18T06:15:39.994602Z","shell.execute_reply":"2024-05-18T06:15:39.999982Z"},"trusted":true},"execution_count":25,"outputs":[{"execution_count":25,"output_type":"execute_result","data":{"text/plain":"torch.Size([3])"},"metadata":{}}]},{"cell_type":"code","source":"# Element-wise matrix multiplication\ntensor * tensor ","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:40.196112Z","iopub.execute_input":"2024-05-18T06:15:40.196863Z","iopub.status.idle":"2024-05-18T06:15:40.205169Z","shell.execute_reply.started":"2024-05-18T06:15:40.196830Z","shell.execute_reply":"2024-05-18T06:15:40.203830Z"},"trusted":true},"execution_count":26,"outputs":[{"execution_count":26,"output_type":"execute_result","data":{"text/plain":"tensor([1, 4, 9])"},"metadata":{}}]},{"cell_type":"code","source":"# Matrix multiplication\ntorch.matmul(tensor, tensor)","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:40.412301Z","iopub.execute_input":"2024-05-18T06:15:40.412578Z","iopub.status.idle":"2024-05-18T06:15:40.421135Z","shell.execute_reply.started":"2024-05-18T06:15:40.412553Z","shell.execute_reply":"2024-05-18T06:15:40.420327Z"},"trusted":true},"execution_count":27,"outputs":[{"execution_count":27,"output_type":"execute_result","data":{"text/plain":"tensor(14)"},"metadata":{}}]},{"cell_type":"code","source":"# Can also use the \"@\" symbol for matrix multiplication, though not recommended\ntensor @ tensor","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:40.628661Z","iopub.execute_input":"2024-05-18T06:15:40.629029Z","iopub.status.idle":"2024-05-18T06:15:40.636021Z","shell.execute_reply.started":"2024-05-18T06:15:40.628997Z","shell.execute_reply":"2024-05-18T06:15:40.634989Z"},"trusted":true},"execution_count":28,"outputs":[{"execution_count":28,"output_type":"execute_result","data":{"text/plain":"tensor(14)"},"metadata":{}}]},{"cell_type":"markdown","source":"The in-built torch.matmul() method is faster","metadata":{}},{"cell_type":"code","source":"tensor = torch.tensor([1, 2, 3])\ntensor.shape","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:41.063534Z","iopub.execute_input":"2024-05-18T06:15:41.063859Z","iopub.status.idle":"2024-05-18T06:15:41.070020Z","shell.execute_reply.started":"2024-05-18T06:15:41.063836Z","shell.execute_reply":"2024-05-18T06:15:41.069177Z"},"trusted":true},"execution_count":29,"outputs":[{"execution_count":29,"output_type":"execute_result","data":{"text/plain":"torch.Size([3])"},"metadata":{}}]},{"cell_type":"code","source":"%%time\n# Matrix multiplication by hand \n# (avoid doing operations with for loops at all cost, they are computationally expensive)\nvalue = 0\nfor i in range(len(tensor)):\n value += tensor[i] * tensor[i]\nvalue","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:41.279204Z","iopub.execute_input":"2024-05-18T06:15:41.279521Z","iopub.status.idle":"2024-05-18T06:15:41.292623Z","shell.execute_reply.started":"2024-05-18T06:15:41.279496Z","shell.execute_reply":"2024-05-18T06:15:41.291682Z"},"trusted":true},"execution_count":30,"outputs":[{"name":"stdout","text":"CPU times: user 1.63 ms, sys: 917 µs, total: 2.55 ms\nWall time: 5.84 ms\n","output_type":"stream"},{"execution_count":30,"output_type":"execute_result","data":{"text/plain":"tensor(14)"},"metadata":{}}]},{"cell_type":"code","source":"%%time\ntorch.matmul(tensor, tensor)","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:41.491520Z","iopub.execute_input":"2024-05-18T06:15:41.491800Z","iopub.status.idle":"2024-05-18T06:15:41.499219Z","shell.execute_reply.started":"2024-05-18T06:15:41.491778Z","shell.execute_reply":"2024-05-18T06:15:41.498316Z"},"trusted":true},"execution_count":31,"outputs":[{"name":"stdout","text":"CPU times: user 336 µs, sys: 84 µs, total: 420 µs\nWall time: 395 µs\n","output_type":"stream"},{"execution_count":31,"output_type":"execute_result","data":{"text/plain":"tensor(14)"},"metadata":{}}]},{"cell_type":"markdown","source":"### Running tensors on GPU (and making faster computations)","metadata":{}},{"cell_type":"markdown","source":"Deep learning algorithms require a lot of numerical operations.\n\nAnd by default these operations are often done on a CPU (computer processing unit).\n\nHowever, there's another common piece of hardware called a GPU (graphics processing unit), which is often much faster at performing the specific types of operations neural networks need (matrix multiplications) than CPUs.\n\nYour computer might have one.\n\nIf so, you should look to use it whenever you can to train neural networks because chances are it'll speed up the training time dramatically.\n\nThere are a few ways to first get access to a GPU and secondly get PyTorch to use the GPU.\n\nNote: When I reference \"GPU\" throughout this course, I'm referencing a Nvidia GPU with CUDA enabled (CUDA is a computing platform and API that helps allow GPUs be used for general purpose computing & not just graphics) unless otherwise specified.","metadata":{}},{"cell_type":"markdown","source":"#### 1. Getting a GPU\nTo check if you've got access to a Nvidia GPU, you can run !nvidia-smi where the ! (also called bang) means \"run this on the command line\".","metadata":{}},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:15:46.740635Z","iopub.execute_input":"2024-05-18T06:15:46.740977Z","iopub.status.idle":"2024-05-18T06:15:47.790734Z","shell.execute_reply.started":"2024-05-18T06:15:46.740948Z","shell.execute_reply":"2024-05-18T06:15:47.789363Z"},"trusted":true},"execution_count":32,"outputs":[{"name":"stdout","text":"Sat May 18 06:15:47 2024 \n+---------------------------------------------------------------------------------------+\n| NVIDIA-SMI 535.129.03 Driver Version: 535.129.03 CUDA Version: 12.2 |\n|-----------------------------------------+----------------------+----------------------+\n| GPU Name Persistence-M | Bus-Id Disp.A | Volatile Uncorr. ECC |\n| Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. |\n| | | MIG M. |\n|=========================================+======================+======================|\n| 0 Tesla T4 Off | 00000000:00:04.0 Off | 0 |\n| N/A 39C P8 9W / 70W | 0MiB / 15360MiB | 0% Default |\n| | | N/A |\n+-----------------------------------------+----------------------+----------------------+\n| 1 Tesla T4 Off | 00000000:00:05.0 Off | 0 |\n| N/A 40C P8 10W / 70W | 0MiB / 15360MiB | 0% Default |\n| | | N/A |\n+-----------------------------------------+----------------------+----------------------+\n \n+---------------------------------------------------------------------------------------+\n| Processes: |\n| GPU GI CI PID Type Process name GPU Memory |\n| ID ID Usage |\n|=======================================================================================|\n| No running processes found |\n+---------------------------------------------------------------------------------------+\n","output_type":"stream"}]},{"cell_type":"markdown","source":"#### 2. Getting PyTorch to run on the GPU\n","metadata":{}},{"cell_type":"code","source":"# Check for GPU\nimport torch\ntorch.cuda.is_available()","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:18:16.718994Z","iopub.execute_input":"2024-05-18T06:18:16.719414Z","iopub.status.idle":"2024-05-18T06:18:16.782514Z","shell.execute_reply.started":"2024-05-18T06:18:16.719382Z","shell.execute_reply":"2024-05-18T06:18:16.781474Z"},"trusted":true},"execution_count":33,"outputs":[{"execution_count":33,"output_type":"execute_result","data":{"text/plain":"True"},"metadata":{}}]},{"cell_type":"markdown","source":"If the above outputs True, PyTorch can see and use the GPU, if it outputs False, it can't see the GPU and in that case, you'll have to go back through the installation steps.\n\nNow, let's say you wanted to setup your code so it ran on CPU or the GPU if it was available.\n\nThat way, if you or someone decides to run your code, it'll work regardless of the computing device they're using.\n\nLet's create a device variable to store what kind of device is available.","metadata":{}},{"cell_type":"code","source":"# Set device type\ndevice = \"cuda\" if torch.cuda.is_available() else \"cpu\"\ndevice","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:19:02.218683Z","iopub.execute_input":"2024-05-18T06:19:02.219039Z","iopub.status.idle":"2024-05-18T06:19:02.225312Z","shell.execute_reply.started":"2024-05-18T06:19:02.219012Z","shell.execute_reply":"2024-05-18T06:19:02.224460Z"},"trusted":true},"execution_count":34,"outputs":[{"execution_count":34,"output_type":"execute_result","data":{"text/plain":"'cuda'"},"metadata":{}}]},{"cell_type":"markdown","source":"If the above output \"cuda\" it means we can set all of our PyTorch code to use the available CUDA device (a GPU) and if it output \"cpu\", our PyTorch code will stick with the CPU.","metadata":{}},{"cell_type":"code","source":"# Count number of devices\ntorch.cuda.device_count()","metadata":{"execution":{"iopub.status.busy":"2024-05-18T06:19:46.087424Z","iopub.execute_input":"2024-05-18T06:19:46.088136Z","iopub.status.idle":"2024-05-18T06:19:46.117115Z","shell.execute_reply.started":"2024-05-18T06:19:46.088103Z","shell.execute_reply":"2024-05-18T06:19:46.116140Z"},"trusted":true},"execution_count":35,"outputs":[{"execution_count":35,"output_type":"execute_result","data":{"text/plain":"2"},"metadata":{}}]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]} -------------------------------------------------------------------------------- /Deep Learning/PyTorch 2.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "059727dd-d937-43a3-a735-c8505386f32a", 7 | "metadata": {}, 8 | "outputs": [ 9 | { 10 | "data": { 11 | "text/plain": [ 12 | "'2.3.0+cu121'" 13 | ] 14 | }, 15 | "execution_count": 1, 16 | "metadata": {}, 17 | "output_type": "execute_result" 18 | } 19 | ], 20 | "source": [ 21 | "import torch\n", 22 | "from torch import nn # nn contains all of PyTorch's building blocks for neural networks\n", 23 | "import matplotlib.pyplot as plt\n", 24 | "\n", 25 | "# Check PyTorch version\n", 26 | "torch.__version__" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 2, 32 | "id": "d4168b8b-1da0-4935-abbe-0f398fbd31b1", 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "what_were_covering = {1: \"data preparation and loading\",\n", 37 | " 2: \"build model\",\n", 38 | " 3: \"fitting the model to data (training)\",\n", 39 | " 4: \"making predictions and evaluating a model (inference)\",\n", 40 | " 5: \"saving and loading a model\",\n", 41 | " 6: \"putting it all together\"\n", 42 | "}" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "id": "94360b6b-e193-49cc-9220-acae07ca1197", 48 | "metadata": {}, 49 | "source": [ 50 | "### 1. Data Preparation and Loading " 51 | ] 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "id": "8b8e01ca-a117-4947-b8ac-5ec676f66d2c", 56 | "metadata": {}, 57 | "source": [ 58 | "Data can be anything.... \n", 59 | "It could be images,videos,excel spreadsheets,audio,DNA,Text. \n", 60 | "\n", 61 | "Machine learning is game of two parts: \n", 62 | "1. Get the data into numerical representation.\n", 63 | "2. Build a model to learn pattern in numerical representation.\n", 64 | "\n", 65 | "We'll use a linear regression formula to make a straight line with known **paramaters**." 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 3, 71 | "id": "22068e31-632d-4012-b96d-f0aab634f442", 72 | "metadata": {}, 73 | "outputs": [ 74 | { 75 | "data": { 76 | "text/plain": [ 77 | "(tensor([[0.0000],\n", 78 | " [0.0200],\n", 79 | " [0.0400],\n", 80 | " [0.0600],\n", 81 | " [0.0800],\n", 82 | " [0.1000],\n", 83 | " [0.1200],\n", 84 | " [0.1400],\n", 85 | " [0.1600],\n", 86 | " [0.1800]]),\n", 87 | " tensor([[0.3000],\n", 88 | " [0.3140],\n", 89 | " [0.3280],\n", 90 | " [0.3420],\n", 91 | " [0.3560],\n", 92 | " [0.3700],\n", 93 | " [0.3840],\n", 94 | " [0.3980],\n", 95 | " [0.4120],\n", 96 | " [0.4260]]))" 97 | ] 98 | }, 99 | "execution_count": 3, 100 | "metadata": {}, 101 | "output_type": "execute_result" 102 | } 103 | ], 104 | "source": [ 105 | "# Create *known* parameters\n", 106 | "weight = 0.7\n", 107 | "bias = 0.3\n", 108 | "\n", 109 | "# Create data\n", 110 | "start = 0\n", 111 | "end = 1\n", 112 | "step = 0.02\n", 113 | "X = torch.arange(start, end, step).unsqueeze(dim=1) # unsqueeze adds extra dimension\n", 114 | "y = weight * X + bias\n", 115 | "\n", 116 | "X[:10], y[:10]" 117 | ] 118 | }, 119 | { 120 | "cell_type": "code", 121 | "execution_count": 4, 122 | "id": "5d133362-4da3-4327-9d04-b1f6ebff0029", 123 | "metadata": {}, 124 | "outputs": [ 125 | { 126 | "data": { 127 | "text/plain": [ 128 | "(50, 50)" 129 | ] 130 | }, 131 | "execution_count": 4, 132 | "metadata": {}, 133 | "output_type": "execute_result" 134 | } 135 | ], 136 | "source": [ 137 | "len(X), len(y)" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "id": "94368072-4a7a-49fa-970e-7ecdd4581868", 143 | "metadata": {}, 144 | "source": [ 145 | "### Splitting data into training and test sets" 146 | ] 147 | }, 148 | { 149 | "cell_type": "markdown", 150 | "id": "16f2b23a-852b-4b00-b932-c40b9e2d04ac", 151 | "metadata": {}, 152 | "source": [ 153 | "Training set - Course material \n", 154 | "Validation set - Practise set \n", 155 | "Test set - Final exam \n", 156 | "\n", 157 | "Generalization - The ability of Ml model to perform well on data it hasn't seen before. \n", 158 | "\n", 159 | "Validation set is often but not always used. \n", 160 | "\n", 161 | "Training set ~ 60 -80 % \n", 162 | "Validation set ~ 10 - 20 % \n", 163 | "Testing set ~ 10 - 20 %" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": 5, 169 | "id": "37137f51-572a-413b-97a8-d6ac0e65d483", 170 | "metadata": {}, 171 | "outputs": [ 172 | { 173 | "data": { 174 | "text/plain": [ 175 | "(40, 40, 40, 10)" 176 | ] 177 | }, 178 | "execution_count": 5, 179 | "metadata": {}, 180 | "output_type": "execute_result" 181 | } 182 | ], 183 | "source": [ 184 | "# create a train/test spllit \n", 185 | "train_split = int(0.8 * len(X))\n", 186 | "X_train, y_train = X[:train_split], y[:train_split]\n", 187 | "X_test, y_test = X[train_split:], y[train_split:]\n", 188 | "\n", 189 | "len(X_train), len(y_train), len(X_train), len(X_test)" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "execution_count": 6, 195 | "id": "e7994d31-9ca5-4e46-811e-debc15dcbd72", 196 | "metadata": {}, 197 | "outputs": [ 198 | { 199 | "data": { 200 | "text/plain": [ 201 | "(tensor([[0.0000],\n", 202 | " [0.0200],\n", 203 | " [0.0400],\n", 204 | " [0.0600],\n", 205 | " [0.0800],\n", 206 | " [0.1000],\n", 207 | " [0.1200],\n", 208 | " [0.1400],\n", 209 | " [0.1600],\n", 210 | " [0.1800],\n", 211 | " [0.2000],\n", 212 | " [0.2200],\n", 213 | " [0.2400],\n", 214 | " [0.2600],\n", 215 | " [0.2800],\n", 216 | " [0.3000],\n", 217 | " [0.3200],\n", 218 | " [0.3400],\n", 219 | " [0.3600],\n", 220 | " [0.3800],\n", 221 | " [0.4000],\n", 222 | " [0.4200],\n", 223 | " [0.4400],\n", 224 | " [0.4600],\n", 225 | " [0.4800],\n", 226 | " [0.5000],\n", 227 | " [0.5200],\n", 228 | " [0.5400],\n", 229 | " [0.5600],\n", 230 | " [0.5800],\n", 231 | " [0.6000],\n", 232 | " [0.6200],\n", 233 | " [0.6400],\n", 234 | " [0.6600],\n", 235 | " [0.6800],\n", 236 | " [0.7000],\n", 237 | " [0.7200],\n", 238 | " [0.7400],\n", 239 | " [0.7600],\n", 240 | " [0.7800]]),\n", 241 | " tensor([[0.3000],\n", 242 | " [0.3140],\n", 243 | " [0.3280],\n", 244 | " [0.3420],\n", 245 | " [0.3560],\n", 246 | " [0.3700],\n", 247 | " [0.3840],\n", 248 | " [0.3980],\n", 249 | " [0.4120],\n", 250 | " [0.4260],\n", 251 | " [0.4400],\n", 252 | " [0.4540],\n", 253 | " [0.4680],\n", 254 | " [0.4820],\n", 255 | " [0.4960],\n", 256 | " [0.5100],\n", 257 | " [0.5240],\n", 258 | " [0.5380],\n", 259 | " [0.5520],\n", 260 | " [0.5660],\n", 261 | " [0.5800],\n", 262 | " [0.5940],\n", 263 | " [0.6080],\n", 264 | " [0.6220],\n", 265 | " [0.6360],\n", 266 | " [0.6500],\n", 267 | " [0.6640],\n", 268 | " [0.6780],\n", 269 | " [0.6920],\n", 270 | " [0.7060],\n", 271 | " [0.7200],\n", 272 | " [0.7340],\n", 273 | " [0.7480],\n", 274 | " [0.7620],\n", 275 | " [0.7760],\n", 276 | " [0.7900],\n", 277 | " [0.8040],\n", 278 | " [0.8180],\n", 279 | " [0.8320],\n", 280 | " [0.8460]]))" 281 | ] 282 | }, 283 | "execution_count": 6, 284 | "metadata": {}, 285 | "output_type": "execute_result" 286 | } 287 | ], 288 | "source": [ 289 | "X_train, y_train" 290 | ] 291 | }, 292 | { 293 | "cell_type": "code", 294 | "execution_count": 7, 295 | "id": "31d726d0-bb45-43f5-bc06-9d467ad35e76", 296 | "metadata": {}, 297 | "outputs": [], 298 | "source": [ 299 | "# Build a function to visualize the data \n", 300 | "def plot_prediction(train_data = X_train,\n", 301 | " train_labels = y_train, \n", 302 | " test_data = X_test,\n", 303 | " test_labels = y_test,\n", 304 | " prediction=None):\n", 305 | " plt.figure(figsize = (5,5))\n", 306 | "\n", 307 | " # plot training the data in blue \n", 308 | " plt.scatter(train_data, train_labels, c = \"b\", s = 4, label = \"Training Data\")\n", 309 | "\n", 310 | " # plot the testing data in green\n", 311 | " plt.scatter(test_data, test_labels, c = \"g\", s= 4, label =\"Testing Data\")\n", 312 | "\n", 313 | " # Are there prediction? \n", 314 | " if prediction is not None:\n", 315 | " # plot the prediction if they exit \n", 316 | " plt.scatter(test_data, prediction, c =\"r\", s= 4, label=\"Prediction\")\n", 317 | " \n", 318 | " # show the legend\n", 319 | " plt.legend(prop = {\"size\": 14});" 320 | ] 321 | }, 322 | { 323 | "cell_type": "code", 324 | "execution_count": 8, 325 | "id": "24501c28-01bb-4376-9a31-7cd95ac8e133", 326 | "metadata": {}, 327 | "outputs": [ 328 | { 329 | "data": { 330 | "image/png": "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", 331 | "text/plain": [ 332 | "
" 333 | ] 334 | }, 335 | "metadata": {}, 336 | "output_type": "display_data" 337 | } 338 | ], 339 | "source": [ 340 | "plot_prediction()" 341 | ] 342 | }, 343 | { 344 | "cell_type": "markdown", 345 | "id": "535fb21f-3ce6-4934-8015-ee80a4eb8f8d", 346 | "metadata": {}, 347 | "source": [ 348 | "### Build model \n", 349 | "What our model does:\n", 350 | "* Start with random value (weight & bias)\n", 351 | "* Look at training data and adjust the random values to better represent (or get closer to) the ideal value (the weight & bias values we used to create the data)\n", 352 | "\n", 353 | "How does it do so? \n", 354 | "Through two main algorithms: \n", 355 | "* Gradient descent\n", 356 | "* Backpropagation" 357 | ] 358 | }, 359 | { 360 | "cell_type": "code", 361 | "execution_count": 9, 362 | "id": "baf93a0f-62cc-427c-82f2-d81b68ad1f52", 363 | "metadata": {}, 364 | "outputs": [], 365 | "source": [ 366 | "# Create linear regression model class \n", 367 | "class LinearRegressionModel(nn.Module):# <- almost everything in pytorch inherits from nn.Module\n", 368 | " def __init__(self):\n", 369 | " super().__init__()\n", 370 | " self.weight = nn.Parameter(torch.randn(1,\n", 371 | " requires_grad = True,\n", 372 | " dtype = torch.float))\n", 373 | " \n", 374 | " self.bias = nn.Parameter(torch.randn(1,\n", 375 | " requires_grad=True,\n", 376 | " dtype=torch.float))\n", 377 | "\n", 378 | " # Forward method to define the computation in the model \n", 379 | " def forward(self, x: torch.Tensor) -> torch.Tensor: \n", 380 | " \"\"\"\n", 381 | " x: torch.Tensor: This indicates that the input x is expected to be a PyTorch tensor.\n", 382 | " -> torch.Tensor: This specifies that the output of the forward method is also a PyTorch tensor.\n", 383 | " \"\"\"\n", 384 | " return self.weight * x + self.bias # this is linear regression formula " 385 | ] 386 | }, 387 | { 388 | "cell_type": "markdown", 389 | "id": "ca49aa62-5b0d-4beb-93c2-a032e19061bb", 390 | "metadata": {}, 391 | "source": [ 392 | "#### PyTorch model building essentials \n", 393 | "\n", 394 | "* torch.nn - contains all of the building blocks for computational graphs(a the neural networks).\n", 395 | "* torch.nn.Parameter - what parameters should our model try and learn, often a PyTorch layer from torch.nn will set these for us.\n", 396 | "* torch.nn.Module - the base class for all neural network module, if you subclass it, you should overwrite forward()\n", 397 | "* torch.optim - this is where the optimizers in PyTorch live, they will help with gradient descent. # optimizers e.g. gradient descent, ADAM, etc.\n", 398 | "* def forward() - All nn.Module subclasses require you to overwrite forward(), this method define what happen in forward computation.\n", 399 | "* torch.utils.data.Dataset - Represent a map between key(label) and sample(feature) pairs of your data. Such a images and their associated labels.\n", 400 | "* torch.utils.data.DataLoader - Creates a python iterable over a torch Dataset (allows you to iterate over your data).\n", 401 | "* torch.nn.functional - layers, activations and more\n", 402 | " > Read more - www.pytorch.org/tutorials/beginner/ptcheat.html" 403 | ] 404 | }, 405 | { 406 | "cell_type": "code", 407 | "execution_count": 10, 408 | "id": "9cdc2b07-f839-421c-8e87-27117672a067", 409 | "metadata": {}, 410 | "outputs": [], 411 | "source": [ 412 | "# checking the content of our pytorch model \n", 413 | "# create a random seed \n", 414 | "torch.manual_seed(42)\n", 415 | "\n", 416 | "# create an instance of the model( this is a subclass of the nn.Module) \n", 417 | "model = LinearRegressionModel()" 418 | ] 419 | }, 420 | { 421 | "cell_type": "code", 422 | "execution_count": 11, 423 | "id": "a2c76553-5e75-44f8-91b3-7976e837e238", 424 | "metadata": {}, 425 | "outputs": [ 426 | { 427 | "data": { 428 | "text/plain": [ 429 | "LinearRegressionModel()" 430 | ] 431 | }, 432 | "execution_count": 11, 433 | "metadata": {}, 434 | "output_type": "execute_result" 435 | } 436 | ], 437 | "source": [ 438 | "model" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "execution_count": 12, 444 | "id": "83b74c4f-cf6a-4ae1-8548-f482417cc036", 445 | "metadata": {}, 446 | "outputs": [ 447 | { 448 | "data": { 449 | "text/plain": [ 450 | "" 451 | ] 452 | }, 453 | "execution_count": 12, 454 | "metadata": {}, 455 | "output_type": "execute_result" 456 | } 457 | ], 458 | "source": [ 459 | "model.parameters()" 460 | ] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": 13, 465 | "id": "2327f2c6-9d1f-4574-b5dd-93fc2e733f37", 466 | "metadata": {}, 467 | "outputs": [ 468 | { 469 | "data": { 470 | "text/plain": [ 471 | "[Parameter containing:\n", 472 | " tensor([0.3367], requires_grad=True),\n", 473 | " Parameter containing:\n", 474 | " tensor([0.1288], requires_grad=True)]" 475 | ] 476 | }, 477 | "execution_count": 13, 478 | "metadata": {}, 479 | "output_type": "execute_result" 480 | } 481 | ], 482 | "source": [ 483 | "list(model.parameters())" 484 | ] 485 | }, 486 | { 487 | "cell_type": "code", 488 | "execution_count": 14, 489 | "id": "0a72dd3a-7079-4c81-b05b-f8417ef85803", 490 | "metadata": {}, 491 | "outputs": [ 492 | { 493 | "data": { 494 | "text/plain": [ 495 | "OrderedDict([('weight', tensor([0.3367])), ('bias', tensor([0.1288]))])" 496 | ] 497 | }, 498 | "execution_count": 14, 499 | "metadata": {}, 500 | "output_type": "execute_result" 501 | } 502 | ], 503 | "source": [ 504 | "# list named parameters \n", 505 | "model.state_dict()" 506 | ] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": 15, 511 | "id": "90bcb3cf-997e-4f4e-80f0-13a7479a0d91", 512 | "metadata": {}, 513 | "outputs": [ 514 | { 515 | "data": { 516 | "text/plain": [ 517 | "(0.7, 0.3)" 518 | ] 519 | }, 520 | "execution_count": 15, 521 | "metadata": {}, 522 | "output_type": "execute_result" 523 | } 524 | ], 525 | "source": [ 526 | "weight, bias" 527 | ] 528 | }, 529 | { 530 | "cell_type": "markdown", 531 | "id": "4b158543-79dc-4576-9229-80be4a547f05", 532 | "metadata": {}, 533 | "source": [ 534 | "The better we get ([('weight', tensor([0.3367])), ('bias', tensor([0.1288]))]) value closer to (0.7, 0.3) the better we are able to predict and model. " 535 | ] 536 | }, 537 | { 538 | "cell_type": "code", 539 | "execution_count": 16, 540 | "id": "75e67eb1-66f8-483f-8cfc-46a73b3eda76", 541 | "metadata": {}, 542 | "outputs": [ 543 | { 544 | "data": { 545 | "text/plain": [ 546 | "tensor([[0.3982],\n", 547 | " [0.4049],\n", 548 | " [0.4116],\n", 549 | " [0.4184],\n", 550 | " [0.4251],\n", 551 | " [0.4318],\n", 552 | " [0.4386],\n", 553 | " [0.4453],\n", 554 | " [0.4520],\n", 555 | " [0.4588]])" 556 | ] 557 | }, 558 | "execution_count": 16, 559 | "metadata": {}, 560 | "output_type": "execute_result" 561 | } 562 | ], 563 | "source": [ 564 | "# making prediction using `torch.inference_mode()`\n", 565 | "# To check our model's predictive power, let's see how well it predicts `y_test` based on `x_test`.\n", 566 | "\n", 567 | "with torch.inference_mode():\n", 568 | " y_preds = model(X_test)\n", 569 | "\n", 570 | "y_preds" 571 | ] 572 | }, 573 | { 574 | "cell_type": "code", 575 | "execution_count": 17, 576 | "id": "4974afd9-4717-4bcb-bde8-080c6e0615ac", 577 | "metadata": {}, 578 | "outputs": [ 579 | { 580 | "data": { 581 | "text/plain": [ 582 | "tensor([[0.8600],\n", 583 | " [0.8740],\n", 584 | " [0.8880],\n", 585 | " [0.9020],\n", 586 | " [0.9160],\n", 587 | " [0.9300],\n", 588 | " [0.9440],\n", 589 | " [0.9580],\n", 590 | " [0.9720],\n", 591 | " [0.9860]])" 592 | ] 593 | }, 594 | "execution_count": 17, 595 | "metadata": {}, 596 | "output_type": "execute_result" 597 | } 598 | ], 599 | "source": [ 600 | "y_test" 601 | ] 602 | }, 603 | { 604 | "cell_type": "code", 605 | "execution_count": 18, 606 | "id": "aed727de-f7a4-41e5-a1e9-2b9f2e45eee4", 607 | "metadata": {}, 608 | "outputs": [ 609 | { 610 | "data": { 611 | "image/png": "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", 612 | "text/plain": [ 613 | "
" 614 | ] 615 | }, 616 | "metadata": {}, 617 | "output_type": "display_data" 618 | } 619 | ], 620 | "source": [ 621 | "plot_prediction(prediction = y_preds)" 622 | ] 623 | }, 624 | { 625 | "cell_type": "markdown", 626 | "id": "b9220464-c593-4197-a437-e13a376f40af", 627 | "metadata": {}, 628 | "source": [ 629 | "#### Train model \n", 630 | "The whole idea of training is for a model from some *unknown* parameters (these may be random) to some *known* parameters. \n", 631 | "Or in other words from a poor representation of the data to a better representation of the data. \n", 632 | "\n", 633 | "One way to measure how poor or how wrong your models prediction are is to use loss function. \n", 634 | "\n", 635 | "* NOTE: Loss function may also be called cost function or criterion in different areas. For our case, we're going to refer to it as a loss function.\n", 636 | "\n", 637 | "Things we need to train:\n", 638 | "* **Loss function**: A function to measure how wrong your model's predictiosns are to the ideal outputs, lower is better.\n", 639 | "* **Optimizer**: Take into account the loss of a model and adjusts the model's parameters (e.g. weight & bias in our case) to improve the loss function.\n", 640 | "\n", 641 | "And specifically in pytorch, we need: \n", 642 | "* A training loop\n", 643 | "* A testing loop " 644 | ] 645 | }, 646 | { 647 | "cell_type": "code", 648 | "execution_count": 21, 649 | "id": "bca66d3f-d341-4b97-9064-d163bd765fec", 650 | "metadata": {}, 651 | "outputs": [ 652 | { 653 | "data": { 654 | "text/plain": [ 655 | "[Parameter containing:\n", 656 | " tensor([0.3367], requires_grad=True),\n", 657 | " Parameter containing:\n", 658 | " tensor([0.1288], requires_grad=True)]" 659 | ] 660 | }, 661 | "execution_count": 21, 662 | "metadata": {}, 663 | "output_type": "execute_result" 664 | } 665 | ], 666 | "source": [ 667 | "list(model.parameters())" 668 | ] 669 | }, 670 | { 671 | "cell_type": "code", 672 | "execution_count": 29, 673 | "id": "436210f7-d416-4afa-b05d-2fc132bf971f", 674 | "metadata": {}, 675 | "outputs": [ 676 | { 677 | "data": { 678 | "text/plain": [ 679 | "OrderedDict([('weight', tensor([0.3367])), ('bias', tensor([0.1288]))])" 680 | ] 681 | }, 682 | "execution_count": 29, 683 | "metadata": {}, 684 | "output_type": "execute_result" 685 | } 686 | ], 687 | "source": [ 688 | "# Check out the model's parameter (a parameter is a value that the model sets itself) \n", 689 | "model.state_dict()" 690 | ] 691 | }, 692 | { 693 | "cell_type": "code", 694 | "execution_count": 32, 695 | "id": "430a29d9-af1d-4808-9302-5946950fbe66", 696 | "metadata": {}, 697 | "outputs": [], 698 | "source": [ 699 | "# Setup a loss function \n", 700 | "loss_fn = nn.L1Loss()\n", 701 | "\n", 702 | "# Setup an optimizer \n", 703 | "optimizer = torch.optim.SGD(params = model.parameters(), \n", 704 | " lr=0.01) # lr = learning rate = possibly the most important hyperparameter you can set " 705 | ] 706 | }, 707 | { 708 | "cell_type": "markdown", 709 | "id": "a22b97f4-bafe-4bc5-9822-489109633724", 710 | "metadata": {}, 711 | "source": [ 712 | "#### Building a training loop (and a testing loop) in pytorch\n", 713 | "A couple of things we need in a training loop : \n", 714 | "* Loop through the data\n", 715 | "* Forward pass ( this involves data moving through our model's `forward()` function) to make prediction on data - also called forward propagation.\n", 716 | "* Calculate the loss (compare forward pass predictions to ground truth labels)\n", 717 | "* Optimizer zero grad\n", 718 | "* Loss Backward - move backward through the network to calculate the gradient of each of the parameters of our model with respect to the loss ( **backpropagation**)\n", 719 | "* Optimizer step - use the optimizer to adjust our model's parameters to try and improve the loss (**gradient descent**)" 720 | ] 721 | }, 722 | { 723 | "cell_type": "code", 724 | "execution_count": null, 725 | "id": "bdf46ad7-6c8e-4bc5-ad63-177ab6cb0c1e", 726 | "metadata": {}, 727 | "outputs": [], 728 | "source": [] 729 | }, 730 | { 731 | "cell_type": "code", 732 | "execution_count": null, 733 | "id": "ccc64dbd-fb83-4841-a8e6-04e2391042e5", 734 | "metadata": {}, 735 | "outputs": [], 736 | "source": [] 737 | }, 738 | { 739 | "cell_type": "code", 740 | "execution_count": null, 741 | "id": "55987287-b6ee-48e0-96dc-2d9072dbf781", 742 | "metadata": {}, 743 | "outputs": [], 744 | "source": [] 745 | }, 746 | { 747 | "cell_type": "code", 748 | "execution_count": null, 749 | "id": "e8b7a342-4b72-4c88-8832-342949868e71", 750 | "metadata": {}, 751 | "outputs": [], 752 | "source": [] 753 | } 754 | ], 755 | "metadata": { 756 | "kernelspec": { 757 | "display_name": "Python 3 (ipykernel)", 758 | "language": "python", 759 | "name": "python3" 760 | }, 761 | "language_info": { 762 | "codemirror_mode": { 763 | "name": "ipython", 764 | "version": 3 765 | }, 766 | "file_extension": ".py", 767 | "mimetype": "text/x-python", 768 | "name": "python", 769 | "nbconvert_exporter": "python", 770 | "pygments_lexer": "ipython3", 771 | "version": "3.11.4" 772 | } 773 | }, 774 | "nbformat": 4, 775 | "nbformat_minor": 5 776 | } 777 | -------------------------------------------------------------------------------- /Deep Learning/PyTorch.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "55e67195-be41-448c-ae6a-64946f9a5399", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import torch \n", 11 | "import torchvision \n", 12 | "import torch.nn as nn \n", 13 | "import torchvision.transforms as transforms\n", 14 | "import numpy as np " 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "id": "121d8d3c-b545-4b1c-bd72-ba2611581305", 20 | "metadata": {}, 21 | "source": [ 22 | "### Tensors \n", 23 | "Tensors are a specialized data structure that are very similar to arrays and matrices. In PyTorch, we use tensors to encode the inputs and outputs of a model, as well as the model’s parameters.\n", 24 | "\n", 25 | "Tensors are similar to NumPy’s ndarrays, except that tensors can run on GPUs or other specialized hardware to accelerate computing" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "id": "6f6201cb-53b9-43aa-bd0c-e2ee8082e217", 32 | "metadata": {}, 33 | "outputs": [], 34 | "source": [ 35 | "# Tensor Initialization " 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 3, 41 | "id": "dd81d25d-28d4-4563-9477-0a7b67d00e6a", 42 | "metadata": {}, 43 | "outputs": [ 44 | { 45 | "name": "stdout", 46 | "output_type": "stream", 47 | "text": [ 48 | "tensor([[1, 2],\n", 49 | " [3, 4]])\n" 50 | ] 51 | } 52 | ], 53 | "source": [ 54 | "# Directly from data\n", 55 | "x = [[1,2],[3,4]]\n", 56 | "x_tensor = torch.tensor(x)\n", 57 | "print(x_tensor)" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 4, 63 | "id": "8181bccd-82a1-43e7-8fdb-a07b4fe74d4f", 64 | "metadata": {}, 65 | "outputs": [ 66 | { 67 | "name": "stdout", 68 | "output_type": "stream", 69 | "text": [ 70 | "tensor([[1, 2],\n", 71 | " [3, 4]])\n" 72 | ] 73 | } 74 | ], 75 | "source": [ 76 | "# From np array \n", 77 | "x_array = np.array(x) \n", 78 | "x_array_tensor = torch.tensor(x_array)\n", 79 | "print(x_array_tensor)" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": 5, 85 | "id": "01a39b51-8b23-4dfa-ad71-90219b8ab017", 86 | "metadata": {}, 87 | "outputs": [ 88 | { 89 | "name": "stdout", 90 | "output_type": "stream", 91 | "text": [ 92 | "tensor([[1, 1],\n", 93 | " [1, 1]])\n", 94 | "tensor([[0.7202, 0.9920],\n", 95 | " [0.0935, 0.5687]])\n", 96 | "tensor([[0, 0],\n", 97 | " [0, 0]])\n" 98 | ] 99 | } 100 | ], 101 | "source": [ 102 | "# from another tensor \n", 103 | "x_ones = torch.ones_like(x_tensor) \n", 104 | "print(x_ones)\n", 105 | "\n", 106 | "x_rand = torch.rand_like(x_tensor, dtype=torch.float) # overrides the datatype of x\n", 107 | "print(x_rand)\n", 108 | "\n", 109 | "x_zeroes = torch.zeros_like(x_tensor)\n", 110 | "print(x_zeroes)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 6, 116 | "id": "a0f60e7a-c823-4b1d-830a-1c09de362b23", 117 | "metadata": {}, 118 | "outputs": [ 119 | { 120 | "name": "stdout", 121 | "output_type": "stream", 122 | "text": [ 123 | "Random Tensor: \n", 124 | " tensor([[0.3847, 0.3175, 0.9163],\n", 125 | " [0.8538, 0.9047, 0.5371]]) \n", 126 | "\n", 127 | "Ones Tensor: \n", 128 | " tensor([[1., 1., 1.],\n", 129 | " [1., 1., 1.]]) \n", 130 | "\n", 131 | "Zeros Tensor: \n", 132 | " tensor([[0., 0., 0.],\n", 133 | " [0., 0., 0.]])\n" 134 | ] 135 | } 136 | ], 137 | "source": [ 138 | "# with random or constant value \n", 139 | "shape = (2, 3,)\n", 140 | "rand_tensor = torch.rand(shape)\n", 141 | "ones_tensor = torch.ones(shape)\n", 142 | "zeros_tensor = torch.zeros(shape)\n", 143 | "\n", 144 | "print(f\"Random Tensor: \\n {rand_tensor} \\n\")\n", 145 | "print(f\"Ones Tensor: \\n {ones_tensor} \\n\")\n", 146 | "print(f\"Zeros Tensor: \\n {zeros_tensor}\")" 147 | ] 148 | }, 149 | { 150 | "cell_type": "markdown", 151 | "id": "ad4aeb43-8dd5-4a84-a2df-edc7058db04a", 152 | "metadata": {}, 153 | "source": [ 154 | "In Python, adding a trailing comma after the last item in a tuple is a matter of style and doesn't affect the functionality. However, in certain contexts, it can improve code readability and make it easier to maintain, especially when modifying the tuple by adding or removing elements.\n", 155 | "\n", 156 | "The version with the trailing comma `(2, 3,)` can be considered a good practice in some coding styles or guidelines because it makes it clear that the tuple has more than one element, even if there's only one element present. This can prevent errors when adding more elements to the tuple in the future, as you won't need to remember to add a comma after the last element.\n", 157 | "\n", 158 | "In summary, while it's not strictly necessary, adding a trailing comma after the last item in a tuple can be considered a good practice for consistency and readability in Python code. However, whether or not to use it ultimately depends on the coding style guide you or your team follows." 159 | ] 160 | }, 161 | { 162 | "cell_type": "markdown", 163 | "id": "c6b5ef57-6510-4312-83fd-756d74bf4a04", 164 | "metadata": {}, 165 | "source": [ 166 | "## Tensor Attributes " 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "execution_count": 7, 172 | "id": "66cc7653-0edb-4a7a-911d-caded5380b3b", 173 | "metadata": {}, 174 | "outputs": [ 175 | { 176 | "name": "stdout", 177 | "output_type": "stream", 178 | "text": [ 179 | "Shape of tensor: torch.Size([3, 4])\n", 180 | "Datatype of tensor: torch.float32\n", 181 | "Device tensor is stored on: cpu\n" 182 | ] 183 | } 184 | ], 185 | "source": [ 186 | "tensor = torch.rand(3, 4)\n", 187 | "\n", 188 | "print(f\"Shape of tensor: {tensor.shape}\")\n", 189 | "print(f\"Datatype of tensor: {tensor.dtype}\")\n", 190 | "print(f\"Device tensor is stored on: {tensor.device}\")" 191 | ] 192 | }, 193 | { 194 | "cell_type": "markdown", 195 | "id": "a5bf89c1-bdb9-445b-aefe-12ce2e10750f", 196 | "metadata": {}, 197 | "source": [ 198 | "### Basic autograds " 199 | ] 200 | }, 201 | { 202 | "cell_type": "markdown", 203 | "id": "e89c1ea1-f1e7-4dfc-8e82-86766481a635", 204 | "metadata": {}, 205 | "source": [ 206 | "Gradients are quite important for the optimization purpose. PyTorch provides package which can do all the computation task." 207 | ] 208 | }, 209 | { 210 | "cell_type": "code", 211 | "execution_count": 8, 212 | "id": "bf79ba9c-db0c-4bf8-b16a-3c7d77753db1", 213 | "metadata": {}, 214 | "outputs": [ 215 | { 216 | "name": "stdout", 217 | "output_type": "stream", 218 | "text": [ 219 | "tensor([ 1.5194, -1.1760, 0.1726])\n" 220 | ] 221 | } 222 | ], 223 | "source": [ 224 | "x = torch.randn(3)\n", 225 | "print(x)" 226 | ] 227 | }, 228 | { 229 | "cell_type": "code", 230 | "execution_count": 9, 231 | "id": "068321a3-7414-4690-b26e-c97af961f5f4", 232 | "metadata": {}, 233 | "outputs": [ 234 | { 235 | "name": "stdout", 236 | "output_type": "stream", 237 | "text": [ 238 | "tensor([ 0.8898, -0.9223, -2.1185], requires_grad=True)\n" 239 | ] 240 | } 241 | ], 242 | "source": [ 243 | "x = torch.randn(3, requires_grad = True) # by default requires_grad = false \n", 244 | "print(x)" 245 | ] 246 | }, 247 | { 248 | "cell_type": "code", 249 | "execution_count": 10, 250 | "id": "a1038999-4d25-4182-a2bd-83672d5ba762", 251 | "metadata": {}, 252 | "outputs": [ 253 | { 254 | "name": "stdout", 255 | "output_type": "stream", 256 | "text": [ 257 | "tensor([ 2.8898, 1.0777, -0.1185], grad_fn=)\n" 258 | ] 259 | } 260 | ], 261 | "source": [ 262 | "y = x + 2 # will create the computational graph for us \n", 263 | "print(y)" 264 | ] 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "id": "2dd66dde-d223-4adf-a4c0-416f3676f204", 269 | "metadata": {}, 270 | "source": [ 271 | "Here, AddBackward can be seen as we have done the backpropagation. " 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": 11, 277 | "id": "52b82340-360c-49d9-8294-29d62a691c37", 278 | "metadata": {}, 279 | "outputs": [ 280 | { 281 | "name": "stdout", 282 | "output_type": "stream", 283 | "text": [ 284 | "tensor([16.7020, 2.3231, 0.0281], grad_fn=)\n" 285 | ] 286 | } 287 | ], 288 | "source": [ 289 | "z = y*y*2 \n", 290 | "print(z)" 291 | ] 292 | }, 293 | { 294 | "cell_type": "markdown", 295 | "id": "05656eef-e31f-4eda-b255-881b0f41c71c", 296 | "metadata": {}, 297 | "source": [ 298 | "Here, MulBackward can be seen as we are doing multiplication operation. " 299 | ] 300 | }, 301 | { 302 | "cell_type": "code", 303 | "execution_count": 12, 304 | "id": "260539a8-af1f-42d4-b2bb-7ff5380dc823", 305 | "metadata": {}, 306 | "outputs": [ 307 | { 308 | "name": "stdout", 309 | "output_type": "stream", 310 | "text": [ 311 | "tensor(6.3510, grad_fn=)\n" 312 | ] 313 | } 314 | ], 315 | "source": [ 316 | "z = z.mean()\n", 317 | "print(z) " 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": 13, 323 | "id": "9fd10f75-158d-4d5a-8a6f-bfb7636572c0", 324 | "metadata": {}, 325 | "outputs": [ 326 | { 327 | "name": "stdout", 328 | "output_type": "stream", 329 | "text": [ 330 | "tensor([ 3.8531, 1.4370, -0.1579])\n" 331 | ] 332 | } 333 | ], 334 | "source": [ 335 | "# to calculate the gradient \n", 336 | "z.backward() # dz/dx\n", 337 | "print(x.grad) # x will store the gradient value " 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 14, 343 | "id": "9d54cce5-11b5-4dd0-a9ef-384a914e9eed", 344 | "metadata": {}, 345 | "outputs": [ 346 | { 347 | "name": "stdout", 348 | "output_type": "stream", 349 | "text": [ 350 | "tensor([ 4.8862, 23.5957, 10.5685], grad_fn=)\n" 351 | ] 352 | } 353 | ], 354 | "source": [ 355 | "# grad can only be implicitly created only for scalar outputs\n", 356 | "x = torch.randn(3, requires_grad = True ) \n", 357 | "y = x + 2 \n", 358 | "\n", 359 | "z = y*y*2 \n", 360 | "# z.mean()\n", 361 | "print(z) # z is not a scalar value " 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "execution_count": 15, 367 | "id": "cc1e19a2-3789-41f1-9ffc-8e5910970a22", 368 | "metadata": {}, 369 | "outputs": [ 370 | { 371 | "ename": "RuntimeError", 372 | "evalue": "grad can be implicitly created only for scalar outputs", 373 | "output_type": "error", 374 | "traceback": [ 375 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 376 | "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", 377 | "Cell \u001b[0;32mIn[15], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# to calculate gradient \u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[43mz\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbackward\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[38;5;28mprint\u001b[39m(x\u001b[38;5;241m.\u001b[39mgrad)\n", 378 | "File \u001b[0;32m~/myenv/lib/python3.11/site-packages/torch/_tensor.py:525\u001b[0m, in \u001b[0;36mTensor.backward\u001b[0;34m(self, gradient, retain_graph, create_graph, inputs)\u001b[0m\n\u001b[1;32m 515\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m has_torch_function_unary(\u001b[38;5;28mself\u001b[39m):\n\u001b[1;32m 516\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m handle_torch_function(\n\u001b[1;32m 517\u001b[0m Tensor\u001b[38;5;241m.\u001b[39mbackward,\n\u001b[1;32m 518\u001b[0m (\u001b[38;5;28mself\u001b[39m,),\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 523\u001b[0m inputs\u001b[38;5;241m=\u001b[39minputs,\n\u001b[1;32m 524\u001b[0m )\n\u001b[0;32m--> 525\u001b[0m \u001b[43mtorch\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mautograd\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbackward\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 526\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgradient\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mretain_graph\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcreate_graph\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minputs\u001b[49m\n\u001b[1;32m 527\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", 379 | "File \u001b[0;32m~/myenv/lib/python3.11/site-packages/torch/autograd/__init__.py:260\u001b[0m, in \u001b[0;36mbackward\u001b[0;34m(tensors, grad_tensors, retain_graph, create_graph, grad_variables, inputs)\u001b[0m\n\u001b[1;32m 251\u001b[0m inputs \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 252\u001b[0m (inputs,)\n\u001b[1;32m 253\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(inputs, (torch\u001b[38;5;241m.\u001b[39mTensor, graph\u001b[38;5;241m.\u001b[39mGradientEdge))\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 256\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mtuple\u001b[39m()\n\u001b[1;32m 257\u001b[0m )\n\u001b[1;32m 259\u001b[0m grad_tensors_ \u001b[38;5;241m=\u001b[39m _tensor_or_tensors_to_tuple(grad_tensors, \u001b[38;5;28mlen\u001b[39m(tensors))\n\u001b[0;32m--> 260\u001b[0m grad_tensors_ \u001b[38;5;241m=\u001b[39m \u001b[43m_make_grads\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtensors\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mgrad_tensors_\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mis_grads_batched\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[1;32m 261\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m retain_graph \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 262\u001b[0m retain_graph \u001b[38;5;241m=\u001b[39m create_graph\n", 380 | "File \u001b[0;32m~/myenv/lib/python3.11/site-packages/torch/autograd/__init__.py:133\u001b[0m, in \u001b[0;36m_make_grads\u001b[0;34m(outputs, grads, is_grads_batched)\u001b[0m\n\u001b[1;32m 131\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m out\u001b[38;5;241m.\u001b[39mrequires_grad:\n\u001b[1;32m 132\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m out\u001b[38;5;241m.\u001b[39mnumel() \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[0;32m--> 133\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\n\u001b[1;32m 134\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgrad can be implicitly created only for scalar outputs\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 135\u001b[0m )\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m out\u001b[38;5;241m.\u001b[39mdtype\u001b[38;5;241m.\u001b[39mis_floating_point:\n\u001b[1;32m 137\u001b[0m msg \u001b[38;5;241m=\u001b[39m (\n\u001b[1;32m 138\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mgrad can be implicitly created only for real scalar outputs\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 139\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m but got \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mout\u001b[38;5;241m.\u001b[39mdtype\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 140\u001b[0m )\n", 381 | "\u001b[0;31mRuntimeError\u001b[0m: grad can be implicitly created only for scalar outputs" 382 | ] 383 | } 384 | ], 385 | "source": [ 386 | "# to calculate gradient \n", 387 | "z.backward()\n", 388 | "print(x.grad)" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": 16, 394 | "id": "1ed0062b-c569-4a40-ae08-a803558b3ccf", 395 | "metadata": {}, 396 | "outputs": [ 397 | { 398 | "name": "stdout", 399 | "output_type": "stream", 400 | "text": [ 401 | "tensor([6.2522e-01, 1.3739e+01, 9.1950e-03])\n" 402 | ] 403 | } 404 | ], 405 | "source": [ 406 | "# solution is multipying it with an vector \n", 407 | "v = torch.tensor([0.1, 1.0, 0.001], dtype = torch.float32)\n", 408 | "z.backward(v)\n", 409 | "print(x.grad)" 410 | ] 411 | }, 412 | { 413 | "cell_type": "markdown", 414 | "id": "f0fbc9ef-c35a-41d7-b2ea-81f3232bfea3", 415 | "metadata": {}, 416 | "source": [ 417 | "##### Preventing Gradient History\n", 418 | "There are three ways to do prevent gradient history and tracking the computational history. They are: \n", 419 | "1. x_requires_grad_(False)\n", 420 | "2. x.detach()\n", 421 | "3. with torch.no_grad():" 422 | ] 423 | }, 424 | { 425 | "cell_type": "markdown", 426 | "id": "48b09451-2516-4f28-b031-2d4d58b23fc8", 427 | "metadata": {}, 428 | "source": [ 429 | "##### 1. x_requires_grad_(False)" 430 | ] 431 | }, 432 | { 433 | "cell_type": "code", 434 | "execution_count": 17, 435 | "id": "0da6d673-df33-41f1-947d-b6650da6837f", 436 | "metadata": {}, 437 | "outputs": [ 438 | { 439 | "name": "stdout", 440 | "output_type": "stream", 441 | "text": [ 442 | "tensor([-0.0869, -1.6616, -0.6585], requires_grad=True)\n" 443 | ] 444 | } 445 | ], 446 | "source": [ 447 | "x = torch.randn(3, requires_grad = True ) \n", 448 | "print(x)" 449 | ] 450 | }, 451 | { 452 | "cell_type": "code", 453 | "execution_count": 18, 454 | "id": "da4a1244-ef6e-4492-8698-f0fd5884a56b", 455 | "metadata": {}, 456 | "outputs": [ 457 | { 458 | "data": { 459 | "text/plain": [ 460 | "'\\nWhenever a function has a trailing _, this means that it will modify our variable in place. \\n'" 461 | ] 462 | }, 463 | "execution_count": 18, 464 | "metadata": {}, 465 | "output_type": "execute_result" 466 | } 467 | ], 468 | "source": [ 469 | "x.requires_grad_(False) \n", 470 | "\"\"\"\n", 471 | "Whenever a function has a trailing _, this means that it will modify our variable in place. \n", 472 | "\"\"\"" 473 | ] 474 | }, 475 | { 476 | "cell_type": "code", 477 | "execution_count": 19, 478 | "id": "d1f6e3e6-3595-4f5a-af79-a420d73ebeb6", 479 | "metadata": {}, 480 | "outputs": [ 481 | { 482 | "name": "stdout", 483 | "output_type": "stream", 484 | "text": [ 485 | "tensor([-0.0869, -1.6616, -0.6585])\n" 486 | ] 487 | } 488 | ], 489 | "source": [ 490 | "print(x)" 491 | ] 492 | }, 493 | { 494 | "cell_type": "markdown", 495 | "id": "64c2e7cc-f2f4-4525-a991-fe569602d078", 496 | "metadata": {}, 497 | "source": [ 498 | "##### 2. x.detach()" 499 | ] 500 | }, 501 | { 502 | "cell_type": "code", 503 | "execution_count": 20, 504 | "id": "344dcec0-c61d-4b05-be3e-e2adbbf4ce00", 505 | "metadata": {}, 506 | "outputs": [ 507 | { 508 | "name": "stdout", 509 | "output_type": "stream", 510 | "text": [ 511 | "tensor([-0.0869, -1.6616, -0.6585])\n" 512 | ] 513 | } 514 | ], 515 | "source": [ 516 | "y = x.detach()\n", 517 | "print(y) " 518 | ] 519 | }, 520 | { 521 | "cell_type": "markdown", 522 | "id": "ed40f314-22bc-4dfd-9b36-14a0582ee937", 523 | "metadata": {}, 524 | "source": [ 525 | "This will create new tensor which also does not have requires_grad> " 526 | ] 527 | }, 528 | { 529 | "cell_type": "markdown", 530 | "id": "348dfe78-46b6-43ca-ac27-aae504c8cca6", 531 | "metadata": {}, 532 | "source": [ 533 | "##### 3. with toch.no_grad()" 534 | ] 535 | }, 536 | { 537 | "cell_type": "code", 538 | "execution_count": 21, 539 | "id": "c2994bf0-405f-43c7-b10a-aa427066dc7f", 540 | "metadata": {}, 541 | "outputs": [ 542 | { 543 | "name": "stdout", 544 | "output_type": "stream", 545 | "text": [ 546 | "tensor([1.9131, 0.3384, 1.3415])\n" 547 | ] 548 | } 549 | ], 550 | "source": [ 551 | "with torch.no_grad():\n", 552 | " y = x + 2\n", 553 | " print(y)" 554 | ] 555 | }, 556 | { 557 | "cell_type": "markdown", 558 | "id": "8bb416ea-0a71-4c52-823b-a8a615947297", 559 | "metadata": {}, 560 | "source": [ 561 | "This also does not have the gradient attribute. \n" 562 | ] 563 | }, 564 | { 565 | "cell_type": "markdown", 566 | "id": "fc6fdf53-6cf8-4500-b07d-75590bc6ccff", 567 | "metadata": {}, 568 | "source": [ 569 | "Now,\n", 570 | "In PyTorch, when you call the backward() function on a tensor that is part of a computation graph, it computes the gradients of some scalar value (usually a loss) with respect to that tensor, using automatic differentiation techniques like backpropagation.\n", 571 | "\n", 572 | "When you perform backpropagation, PyTorch accumulates the gradients of the parameters (usually weights) of your model in their respective .grad attributes. These gradients are not overwritten on subsequent calls to backward(), but rather accumulated. This behavior is useful, for example, when you have multiple losses in your model and you want to accumulate gradients from each loss before updating the model parameters." 573 | ] 574 | }, 575 | { 576 | "cell_type": "code", 577 | "execution_count": 22, 578 | "id": "cdadf808-5876-4cbb-9ba6-a274baa41e28", 579 | "metadata": {}, 580 | "outputs": [ 581 | { 582 | "name": "stdout", 583 | "output_type": "stream", 584 | "text": [ 585 | "tensor([3., 3., 3., 3.])\n" 586 | ] 587 | } 588 | ], 589 | "source": [ 590 | "# example \n", 591 | "weight = torch.ones(4, requires_grad = True) \n", 592 | "\n", 593 | "for epoch in range(1):\n", 594 | " model_output = (weight*3).sum()\n", 595 | "\n", 596 | " model_output.backward()\n", 597 | " print(weight.grad)" 598 | ] 599 | }, 600 | { 601 | "cell_type": "code", 602 | "execution_count": 23, 603 | "id": "8e894b25-ac1a-47ea-88c8-cb3c6e04f07b", 604 | "metadata": {}, 605 | "outputs": [ 606 | { 607 | "name": "stdout", 608 | "output_type": "stream", 609 | "text": [ 610 | "tensor([3., 3., 3., 3.])\n", 611 | "tensor([6., 6., 6., 6.])\n" 612 | ] 613 | } 614 | ], 615 | "source": [ 616 | "weight = torch.ones(4, requires_grad = True) \n", 617 | "\n", 618 | "for epoch in range(2):\n", 619 | " model_output = (weight*3).sum()\n", 620 | "\n", 621 | " model_output.backward()\n", 622 | " print(weight.grad)" 623 | ] 624 | }, 625 | { 626 | "cell_type": "code", 627 | "execution_count": 24, 628 | "id": "f801eb03-cff0-4df8-9f0b-99c2d75d9886", 629 | "metadata": {}, 630 | "outputs": [ 631 | { 632 | "name": "stdout", 633 | "output_type": "stream", 634 | "text": [ 635 | "tensor([3., 3., 3., 3.])\n", 636 | "tensor([6., 6., 6., 6.])\n", 637 | "tensor([9., 9., 9., 9.])\n" 638 | ] 639 | } 640 | ], 641 | "source": [ 642 | "weight = torch.ones(4, requires_grad = True) \n", 643 | "\n", 644 | "for epoch in range(3):\n", 645 | " model_output = (weight*3).sum()\n", 646 | "\n", 647 | " model_output.backward()\n", 648 | " print(weight.grad)" 649 | ] 650 | }, 651 | { 652 | "cell_type": "markdown", 653 | "id": "74d7d19c-d030-4ee4-8d82-1a8ea7f892e6", 654 | "metadata": {}, 655 | "source": [ 656 | "All the values are summed up and our weights are clearly incorrect. " 657 | ] 658 | }, 659 | { 660 | "cell_type": "code", 661 | "execution_count": 25, 662 | "id": "93341023-8a93-498b-9d6a-cc44cf781ac2", 663 | "metadata": {}, 664 | "outputs": [ 665 | { 666 | "name": "stdout", 667 | "output_type": "stream", 668 | "text": [ 669 | "tensor([3., 3., 3., 3.])\n", 670 | "tensor([3., 3., 3., 3.])\n", 671 | "tensor([3., 3., 3., 3.])\n" 672 | ] 673 | } 674 | ], 675 | "source": [ 676 | "# Before we do next iteration and optimization step , we must empty the gradient. \n", 677 | "weight = torch.ones(4, requires_grad = True) \n", 678 | "\n", 679 | "for epoch in range(3):\n", 680 | " model_output = (weight*3).sum()\n", 681 | "\n", 682 | " model_output.backward()\n", 683 | " print(weight.grad)\n", 684 | " weight.grad.zero_()" 685 | ] 686 | }, 687 | { 688 | "cell_type": "markdown", 689 | "id": "af0bfe09-2594-4ecf-a1d0-fe8ecef7b45d", 690 | "metadata": {}, 691 | "source": [ 692 | "### Backpropagation" 693 | ] 694 | }, 695 | { 696 | "cell_type": "code", 697 | "execution_count": 33, 698 | "id": "61a98bdb-524b-4d71-8f1f-7314dcd3d586", 699 | "metadata": {}, 700 | "outputs": [], 701 | "source": [ 702 | "x = torch.tensor(1.0)\n", 703 | "y = torch.tensor(2.0)\n", 704 | "\n", 705 | "w = torch.tensor(1.0, requires_grad = True)" 706 | ] 707 | }, 708 | { 709 | "cell_type": "code", 710 | "execution_count": 34, 711 | "id": "c221013a-6658-444e-8619-74d4c61e9a1a", 712 | "metadata": {}, 713 | "outputs": [ 714 | { 715 | "name": "stdout", 716 | "output_type": "stream", 717 | "text": [ 718 | "tensor(1., grad_fn=)\n" 719 | ] 720 | } 721 | ], 722 | "source": [ 723 | "# forward pass and compute the loss\n", 724 | "y_hat = w*x \n", 725 | "loss = (y_hat - y )**2\n", 726 | "\n", 727 | "print(loss)" 728 | ] 729 | }, 730 | { 731 | "cell_type": "code", 732 | "execution_count": 35, 733 | "id": "add893d4-e6c2-4cfc-b943-9457ebb5c7b8", 734 | "metadata": {}, 735 | "outputs": [ 736 | { 737 | "name": "stdout", 738 | "output_type": "stream", 739 | "text": [ 740 | "tensor(-2.)\n" 741 | ] 742 | } 743 | ], 744 | "source": [ 745 | "# backward pass\n", 746 | "loss.backward()\n", 747 | "print(w.grad)" 748 | ] 749 | }, 750 | { 751 | "cell_type": "code", 752 | "execution_count": 36, 753 | "id": "739abd85-eb27-45a8-b29b-d28215a5f9e3", 754 | "metadata": {}, 755 | "outputs": [], 756 | "source": [ 757 | "# update weights \n", 758 | "### next forward and backward " 759 | ] 760 | }, 761 | { 762 | "cell_type": "code", 763 | "execution_count": null, 764 | "id": "76f82d0f-00ac-4ddf-8b53-0ad685b8ce08", 765 | "metadata": {}, 766 | "outputs": [], 767 | "source": [] 768 | } 769 | ], 770 | "metadata": { 771 | "kernelspec": { 772 | "display_name": "Python 3 (ipykernel)", 773 | "language": "python", 774 | "name": "python3" 775 | }, 776 | "language_info": { 777 | "codemirror_mode": { 778 | "name": "ipython", 779 | "version": 3 780 | }, 781 | "file_extension": ".py", 782 | "mimetype": "text/x-python", 783 | "name": "python", 784 | "nbconvert_exporter": "python", 785 | "pygments_lexer": "ipython3", 786 | "version": "3.11.4" 787 | } 788 | }, 789 | "nbformat": 4, 790 | "nbformat_minor": 5 791 | } 792 | -------------------------------------------------------------------------------- /ML/.ipynb_checkpoints/Linear Regression-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [], 3 | "metadata": {}, 4 | "nbformat": 4, 5 | "nbformat_minor": 5 6 | } 7 | -------------------------------------------------------------------------------- /ML/Linear Regression.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "id": "d78b7b22-0753-4303-9b42-e5e9bc87d158", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "# importing all neccessary libraries \n", 11 | "import numpy as np \n", 12 | "import pandas as pd \n", 13 | "import matplotlib.pyplot as plt \n", 14 | "from sklearn.model_selection import train_test_split\n", 15 | "from sklearn.linear_model import LinearRegression\n", 16 | "from sklearn.metrics import mean_squared_error, r2_score" 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 2, 22 | "id": "5970f265-d94d-41ce-9863-1a2020aa4dae", 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# creating synthetic data \n", 27 | "np.random.seed(0)\n", 28 | "X = 2 * np.random.rand(100, 1)\n", 29 | "y = 4 + 3 * X + np.random.randn(100, 1)" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": 3, 35 | "id": "00e8a607-ce3b-4dc2-b262-461a14904050", 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "# splitting the data\n", 40 | "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": 4, 46 | "id": "4f4e2a00-d207-41f2-8cb0-b1caf6f86aa9", 47 | "metadata": {}, 48 | "outputs": [ 49 | { 50 | "data": { 51 | "text/html": [ 52 | "
LinearRegression()
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
" 457 | ], 458 | "text/plain": [ 459 | "LinearRegression()" 460 | ] 461 | }, 462 | "execution_count": 4, 463 | "metadata": {}, 464 | "output_type": "execute_result" 465 | } 466 | ], 467 | "source": [ 468 | "# Create and train the model\n", 469 | "model = LinearRegression()\n", 470 | "model.fit(X_train, y_train)" 471 | ] 472 | }, 473 | { 474 | "cell_type": "code", 475 | "execution_count": 5, 476 | "id": "334528f2-bd96-4888-bbee-0a3b0d29e0a7", 477 | "metadata": {}, 478 | "outputs": [], 479 | "source": [ 480 | "# Make predictions\n", 481 | "y_pred = model.predict(X_test)" 482 | ] 483 | }, 484 | { 485 | "cell_type": "code", 486 | "execution_count": 6, 487 | "id": "95886da1-7dd6-406a-a107-a0071c6e57f9", 488 | "metadata": {}, 489 | "outputs": [ 490 | { 491 | "name": "stdout", 492 | "output_type": "stream", 493 | "text": [ 494 | "Mean Squared Error: 0.9177532469714291\n", 495 | "R-squared Score: 0.6521157503858556\n" 496 | ] 497 | } 498 | ], 499 | "source": [ 500 | "# Evaluate the model\n", 501 | "mse = mean_squared_error(y_test, y_pred)\n", 502 | "r2 = r2_score(y_test, y_pred)\n", 503 | "\n", 504 | "print(\"Mean Squared Error:\", mse)\n", 505 | "print(\"R-squared Score:\", r2)" 506 | ] 507 | }, 508 | { 509 | "cell_type": "code", 510 | "execution_count": 7, 511 | "id": "630ed0d0-534f-43ec-b908-6bd5bf587629", 512 | "metadata": {}, 513 | "outputs": [ 514 | { 515 | "data": { 516 | "image/png": "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06bhuuuuAwCMHz8ehw8fxtdff43CwkLMmTMH119/vcP3VVpairvuugudO3fG/v37MWfOHCxYsACvv/663Xm5ublo0KABtm/fjjfffBP//Oc/7UKdN9555x106tQJe/fuxTPPPIPhw4fj6NGjAICrV6+ib9++CA8Px+bNm7FlyxZcd9116NevH/7880+fXpeIiDzDoaWaOnUCzp3z/+tGRwO7dok+/csvv8R1112Ha9euobKyEkFBQfjggw8AAJWVlXjjjTewfv16dOvWDQDQokULfPfdd/jwww/Rs2dPfPjhh0hOTsZbb70FAEhOTsbBgwcxefJku9e5evUqZs+ejQ4dOgAATp8+jYULF+L06dOIjY0FAIwZMwZr1qzBwoUL8cYbb+D06dO499570a5dO9trW50+fRo333wzOnXqBMDS++HM7NmzkZCQgA8++AAGgwGtW7fGTz/9hLFjx+LVV1+1DXG1b98eEyZMAAC0bNkSH3zwATZs2IA+ffqI/n7WdNddd+GZZ54BAIwdOxbTp09HQUEBkpOT8dlnn6Gqqgr/+te/YDAYAAALFy5EVFQUTCYT7rzzTq9fl4iIPMMgU9O5c0BpqdKtcCstLQ1z5szBpUuXMH36dNSpUwf33nsvAODEiRO4fPlyrRv5n3/+iZtvvhkAcPToUXTu3NnueJcuXWq9TkhICNq3b2/7+sCBAzCbzWjVqpXdeZWVlWjcuDEA4LnnnsPw4cOxdu1a9O7dG/fee6/tGsOHD8e9996LPXv24M4778TAgQPRvXt3h++xsLAQ3bp1s4UFALjttttQUVGBM2fOIDExEQDs2gcAMTExOH/+vJPvnDjVr2kwGBAdHW275v79+3HixAmEh4fbPefKlSs4efKkT69LRESeYZCpSYFiU29et0GDBrjxxhsBAB999BE6dOiABQsW4LHHHkNFRQUA4KuvvkJcXJzd80JDQz16nbCwMLsgUVFRgeDgYOzevRvBwcF251qHjx5//HH07dsXX331FdauXYspU6bgnXfewbPPPov+/fvj1KlTWL16NdatW4devXphxIgRePvttz1qV3V169a1+9pgMKCqqsrr67m7ZkVFBW699VZ8+umntZ7XpEkTn16XiIg8wyBTkwfDO2oRFBSE//f//h9Gjx6NoUOH2hXm9uzZ0+FzkpOTbQW4Vjt37nT7WjfffDPM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", 517 | "text/plain": [ 518 | "
" 519 | ] 520 | }, 521 | "metadata": {}, 522 | "output_type": "display_data" 523 | } 524 | ], 525 | "source": [ 526 | "# Plotting the results\n", 527 | "plt.scatter(X, y, color='green', label='Original data')\n", 528 | "plt.plot(X_test, y_pred, color='red', linewidth=2, label='Regression line')\n", 529 | "plt.xlabel('X')\n", 530 | "plt.ylabel('y')\n", 531 | "plt.legend()\n", 532 | "plt.show()" 533 | ] 534 | }, 535 | { 536 | "cell_type": "code", 537 | "execution_count": null, 538 | "id": "a618abc1-7e62-42b0-b104-89be5e817a7e", 539 | "metadata": {}, 540 | "outputs": [], 541 | "source": [] 542 | } 543 | ], 544 | "metadata": { 545 | "kernelspec": { 546 | "display_name": "Python 3 (ipykernel)", 547 | "language": "python", 548 | "name": "python3" 549 | }, 550 | "language_info": { 551 | "codemirror_mode": { 552 | "name": "ipython", 553 | "version": 3 554 | }, 555 | "file_extension": ".py", 556 | "mimetype": "text/x-python", 557 | "name": "python", 558 | "nbconvert_exporter": "python", 559 | "pygments_lexer": "ipython3", 560 | "version": "3.11.4" 561 | } 562 | }, 563 | "nbformat": 4, 564 | "nbformat_minor": 5 565 | } 566 | -------------------------------------------------------------------------------- /Python/Python Day3.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "e886a608-cdda-4b1d-aad8-906517e1644a", 6 | "metadata": {}, 7 | "source": [ 8 | "### Hiding some variables " 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": 1, 14 | "id": "2a48bb97-29d4-4b4f-a743-63ae6d76ecdb", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "# private variables in python" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 2, 24 | "id": "3497a592-8544-496c-8579-53e085f66149", 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "class A: \n", 29 | " def __init__(self, value):\n", 30 | " self.__value = value\n", 31 | " # add double _ to hide the value\n", 32 | " # python changes __ value to _A__value" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": 3, 38 | "id": "573b81d2-d02c-4238-bc03-c7fc81e53964", 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "object = A(89)" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 4, 48 | "id": "57e29bb0-f2a7-4e36-ada0-8e3d5a5f3ee4", 49 | "metadata": {}, 50 | "outputs": [ 51 | { 52 | "ename": "AttributeError", 53 | "evalue": "'A' object has no attribute '__value'", 54 | "output_type": "error", 55 | "traceback": [ 56 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 57 | "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", 58 | "Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mobject\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__value\u001b[49m\n", 59 | "\u001b[0;31mAttributeError\u001b[0m: 'A' object has no attribute '__value'" 60 | ] 61 | } 62 | ], 63 | "source": [ 64 | "object.__value" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "id": "a8821e48-8052-45b6-96ae-51ffae2a83ed", 71 | "metadata": {}, 72 | "outputs": [], 73 | "source": [ 74 | "object._A__value" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "id": "2e641718-9874-491d-aff2-0256e57d66f0", 80 | "metadata": {}, 81 | "source": [ 82 | "This is not really an private method. " 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "id": "742363d1-7c21-4af5-a15f-20f6af8add28", 88 | "metadata": {}, 89 | "source": [ 90 | "There are three types of variable in python i.e. public, private (accessed on the same class ) and protected ( accessed only on the parent and child class ). These are known as access modifier which totally depends on the person writing the code. Access modifier are not good in \n", 91 | "python as c++/Java as private data is not even private in python we are able to access those data anyway. " 92 | ] 93 | }, 94 | { 95 | "cell_type": "markdown", 96 | "id": "31ec47c5-12cc-44c7-bd18-c5c674a9f4d8", 97 | "metadata": {}, 98 | "source": [ 99 | "### Scoping " 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": 3, 105 | "id": "8e56f3e2-11c8-4c1e-a2bf-7d0d67173fce", 106 | "metadata": {}, 107 | "outputs": [], 108 | "source": [ 109 | "def fun(): \n", 110 | " a = 10" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 4, 116 | "id": "1ef52d67-3530-45a4-b782-e3d05370af87", 117 | "metadata": {}, 118 | "outputs": [], 119 | "source": [ 120 | "fun()" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "execution_count": 7, 126 | "id": "84d20548-854d-4a4f-9371-8a489e879423", 127 | "metadata": {}, 128 | "outputs": [ 129 | { 130 | "ename": "NameError", 131 | "evalue": "name 'a' is not defined", 132 | "output_type": "error", 133 | "traceback": [ 134 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 135 | "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", 136 | "Cell \u001b[0;32mIn[7], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43ma\u001b[49m) \u001b[38;5;66;03m# cannot access the value outside the function\u001b[39;00m\n", 137 | "\u001b[0;31mNameError\u001b[0m: name 'a' is not defined" 138 | ] 139 | } 140 | ], 141 | "source": [ 142 | "print(a) # cannot access the value outside the function" 143 | ] 144 | }, 145 | { 146 | "cell_type": "code", 147 | "execution_count": 8, 148 | "id": "b6a1725c-0ea6-4ff1-a7e3-e5a3b4259061", 149 | "metadata": {}, 150 | "outputs": [ 151 | { 152 | "ename": "UnboundLocalError", 153 | "evalue": "cannot access local variable 'a' where it is not associated with a value", 154 | "output_type": "error", 155 | "traceback": [ 156 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 157 | "\u001b[0;31mUnboundLocalError\u001b[0m Traceback (most recent call last)", 158 | "Cell \u001b[0;32mIn[8], line 5\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfun\u001b[39m():\n\u001b[1;32m 3\u001b[0m a \u001b[38;5;241m=\u001b[39m a \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m20\u001b[39m \u001b[38;5;66;03m# local variable \u001b[39;00m\n\u001b[0;32m----> 5\u001b[0m \u001b[43mfun\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", 159 | "Cell \u001b[0;32mIn[8], line 3\u001b[0m, in \u001b[0;36mfun\u001b[0;34m()\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mfun\u001b[39m():\n\u001b[0;32m----> 3\u001b[0m a \u001b[38;5;241m=\u001b[39m \u001b[43ma\u001b[49m \u001b[38;5;241m+\u001b[39m \u001b[38;5;241m20\u001b[39m\n", 160 | "\u001b[0;31mUnboundLocalError\u001b[0m: cannot access local variable 'a' where it is not associated with a value" 161 | ] 162 | } 163 | ], 164 | "source": [ 165 | "a = 20 # global variable \n", 166 | "def fun():\n", 167 | " a = a + 20 # local variable \n", 168 | "\n", 169 | "fun()" 170 | ] 171 | }, 172 | { 173 | "cell_type": "markdown", 174 | "id": "ce52ddcf-1be5-465f-817e-00da4aac882b", 175 | "metadata": {}, 176 | "source": [ 177 | "In python, we can not change the value of the global scope should not come inside the local scope and should not change the value as global scope could be used in another local scopes( functions or any other) " 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 9, 183 | "id": "c5b7ad51-3428-4bc3-bfbf-9b11fc866cf6", 184 | "metadata": {}, 185 | "outputs": [], 186 | "source": [ 187 | "a = 30 \n", 188 | "def fun(): \n", 189 | " a = 60 # local variable of function fun()\n", 190 | " a = a + 34\n", 191 | " print(a)" 192 | ] 193 | }, 194 | { 195 | "cell_type": "code", 196 | "execution_count": 10, 197 | "id": "8aba472e-4b10-404f-9c12-2bb2b29df22a", 198 | "metadata": {}, 199 | "outputs": [ 200 | { 201 | "name": "stdout", 202 | "output_type": "stream", 203 | "text": [ 204 | "94\n" 205 | ] 206 | } 207 | ], 208 | "source": [ 209 | "fun()" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": 11, 215 | "id": "cf1f1f34-5437-4c04-a330-d25c8464b0a5", 216 | "metadata": {}, 217 | "outputs": [ 218 | { 219 | "data": { 220 | "text/plain": [ 221 | "30" 222 | ] 223 | }, 224 | "execution_count": 11, 225 | "metadata": {}, 226 | "output_type": "execute_result" 227 | } 228 | ], 229 | "source": [ 230 | "a # Global variable # you can access the global variable but can not change directly" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "execution_count": 12, 236 | "id": "d2e76072-487c-4e4b-9a48-d0ad2f6a5dfe", 237 | "metadata": {}, 238 | "outputs": [ 239 | { 240 | "name": "stdout", 241 | "output_type": "stream", 242 | "text": [ 243 | "\n" 244 | ] 245 | } 246 | ], 247 | "source": [ 248 | "# more examples \n", 249 | "a = 45 # Global variable 'a' assigned the value 45\n", 250 | "\n", 251 | "def a(): # Function definition named 'a'\n", 252 | " print(a) # Inside the function, 'a' refers to the function itself\n", 253 | "\n", 254 | "a() # Call the function named 'a'" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": 13, 260 | "id": "f7a0b1f3-0221-407d-9e9e-d1765859c042", 261 | "metadata": {}, 262 | "outputs": [ 263 | { 264 | "name": "stdout", 265 | "output_type": "stream", 266 | "text": [ 267 | "345\n" 268 | ] 269 | } 270 | ], 271 | "source": [ 272 | "# more examples \n", 273 | "a = 345\n", 274 | "\n", 275 | "def abc():\n", 276 | " print(a) # global value accessed\n", 277 | "\n", 278 | "abc()" 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "id": "caff99b9-cf83-4515-8592-2615c4e27213", 284 | "metadata": {}, 285 | "source": [ 286 | "**LGEB Rule**: Local Enclosed Global Builtin Rule \n", 287 | "- At first it will check the variable values in local and then enclosed ie function inside the function then global and last in built-in" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "execution_count": 14, 293 | "id": "56614f5c-541e-4a3c-951a-d2e5da109908", 294 | "metadata": {}, 295 | "outputs": [], 296 | "source": [ 297 | "a = 67 \n", 298 | "\n", 299 | "def x():\n", 300 | " a = 10 # this is local to x \n", 301 | " # this a = 10, this is enclosed for y()\n", 302 | " \n", 303 | " def y():\n", 304 | " a = 660 # this is local to y \n", 305 | " print(\"a in y() is\", a)\n", 306 | "\n", 307 | " print(\"a in x() is\",a)\n", 308 | " return y()" 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": 15, 314 | "id": "7c76193d-ed12-4c6c-9d6e-4b6ddc1b0a91", 315 | "metadata": {}, 316 | "outputs": [ 317 | { 318 | "name": "stdout", 319 | "output_type": "stream", 320 | "text": [ 321 | "a in x() is 10\n", 322 | "a in y() is 660\n" 323 | ] 324 | } 325 | ], 326 | "source": [ 327 | "x()" 328 | ] 329 | }, 330 | { 331 | "cell_type": "code", 332 | "execution_count": 16, 333 | "id": "4b909ec1-29e3-4728-ab7e-6918baf902a5", 334 | "metadata": {}, 335 | "outputs": [], 336 | "source": [ 337 | "# let's check the locals \n", 338 | "a = 67 \n", 339 | "\n", 340 | "def x():\n", 341 | " a = 10 # this is local to x \n", 342 | " # this a = 10, this is enclosed for y()\n", 343 | " \n", 344 | " def y():\n", 345 | " a = 660 # this is local to y \n", 346 | " print(\"a in y() is\", a)\n", 347 | " print(\"locals for y are:\", locals())\n", 348 | "\n", 349 | " print(\"a in x() is\",a)\n", 350 | " print(\"locals for x are\",locals())\n", 351 | " return y()" 352 | ] 353 | }, 354 | { 355 | "cell_type": "code", 356 | "execution_count": 17, 357 | "id": "91854ec9-70c5-41b1-8e62-75135c182e0c", 358 | "metadata": {}, 359 | "outputs": [ 360 | { 361 | "name": "stdout", 362 | "output_type": "stream", 363 | "text": [ 364 | "a in x() is 10\n", 365 | "locals for x are {'a': 10, 'y': .y at 0x7fc66d5dd760>}\n", 366 | "a in y() is 660\n", 367 | "locals for y are: {'a': 660}\n" 368 | ] 369 | } 370 | ], 371 | "source": [ 372 | "x()" 373 | ] 374 | }, 375 | { 376 | "cell_type": "code", 377 | "execution_count": 18, 378 | "id": "c4d83c67-7af4-4660-8dba-015d53db0265", 379 | "metadata": {}, 380 | "outputs": [], 381 | "source": [ 382 | "a = 67 \n", 383 | "\n", 384 | "def x():\n", 385 | " a = 10 # this is local to x \n", 386 | " # this a = 10, this is enclosed for y()\n", 387 | " \n", 388 | " def y():\n", 389 | " a += 660 # this is local to y \n", 390 | " print(\"a in y() is\", a)\n", 391 | " print(\"locals for y are:\", locals())\n", 392 | "\n", 393 | " print(\"a in x() is\",a)\n", 394 | " print(\"locals for x are\",locals())\n", 395 | " return y()" 396 | ] 397 | }, 398 | { 399 | "cell_type": "code", 400 | "execution_count": 19, 401 | "id": "e4a6e060-fe1b-4ee0-8378-2d104047127d", 402 | "metadata": {}, 403 | "outputs": [ 404 | { 405 | "name": "stdout", 406 | "output_type": "stream", 407 | "text": [ 408 | "a in x() is 10\n", 409 | "locals for x are {'a': 10, 'y': .y at 0x7fc66d5dca40>}\n" 410 | ] 411 | }, 412 | { 413 | "ename": "UnboundLocalError", 414 | "evalue": "cannot access local variable 'a' where it is not associated with a value", 415 | "output_type": "error", 416 | "traceback": [ 417 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 418 | "\u001b[0;31mUnboundLocalError\u001b[0m Traceback (most recent call last)", 419 | "Cell \u001b[0;32mIn[19], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mx\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", 420 | "Cell \u001b[0;32mIn[18], line 14\u001b[0m, in \u001b[0;36mx\u001b[0;34m()\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124ma in x() is\u001b[39m\u001b[38;5;124m\"\u001b[39m,a)\n\u001b[1;32m 13\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlocals for x are\u001b[39m\u001b[38;5;124m\"\u001b[39m,\u001b[38;5;28mlocals\u001b[39m())\n\u001b[0;32m---> 14\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43my\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", 421 | "Cell \u001b[0;32mIn[18], line 8\u001b[0m, in \u001b[0;36mx..y\u001b[0;34m()\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21my\u001b[39m():\n\u001b[0;32m----> 8\u001b[0m \u001b[43ma\u001b[49m \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m660\u001b[39m \u001b[38;5;66;03m# this is local to y \u001b[39;00m\n\u001b[1;32m 9\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124ma in y() is\u001b[39m\u001b[38;5;124m\"\u001b[39m, a)\n\u001b[1;32m 10\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlocals for y are:\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28mlocals\u001b[39m())\n", 422 | "\u001b[0;31mUnboundLocalError\u001b[0m: cannot access local variable 'a' where it is not associated with a value" 423 | ] 424 | } 425 | ], 426 | "source": [ 427 | "x()" 428 | ] 429 | }, 430 | { 431 | "cell_type": "markdown", 432 | "id": "698c86e3-e062-4f6c-8912-7104e629312f", 433 | "metadata": {}, 434 | "source": [ 435 | "Here, the python is not letting us to change the value of x = 10 ( local variable to x) " 436 | ] 437 | }, 438 | { 439 | "cell_type": "code", 440 | "execution_count": 20, 441 | "id": "cb697f00-7437-4064-a609-fb421d9c6485", 442 | "metadata": {}, 443 | "outputs": [], 444 | "source": [ 445 | "a = 67 \n", 446 | "\n", 447 | "def x():\n", 448 | " a = 10 # this is local to x \n", 449 | " # this a = 10, this is enclosed for y()\n", 450 | " \n", 451 | " def y():\n", 452 | " nonlocal a\n", 453 | " a += 660 # this is local to y \n", 454 | " print(\"a in y() is\", a)\n", 455 | " print(\"locals for y are:\", locals())\n", 456 | "\n", 457 | " print(\"a in x() is\",a)\n", 458 | " print(\"locals for x are\",locals())\n", 459 | " return y()" 460 | ] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": 21, 465 | "id": "d9bc9615-f609-47f3-a98e-f2234e2c9efd", 466 | "metadata": {}, 467 | "outputs": [ 468 | { 469 | "name": "stdout", 470 | "output_type": "stream", 471 | "text": [ 472 | "a in x() is 10\n", 473 | "locals for x are {'y': .y at 0x7fc66d5ddf80>, 'a': 10}\n", 474 | "a in y() is 670\n", 475 | "locals for y are: {'a': 670}\n" 476 | ] 477 | } 478 | ], 479 | "source": [ 480 | "x()" 481 | ] 482 | }, 483 | { 484 | "cell_type": "code", 485 | "execution_count": 22, 486 | "id": "65db5bdf-d726-427b-9a70-4cb608f2a16f", 487 | "metadata": {}, 488 | "outputs": [ 489 | { 490 | "name": "stdout", 491 | "output_type": "stream", 492 | "text": [ 493 | "10\n", 494 | "20\n", 495 | "60\n", 496 | "160\n", 497 | "160\n" 498 | ] 499 | } 500 | ], 501 | "source": [ 502 | "x = 10 \n", 503 | "\n", 504 | "def a():\n", 505 | " x = 20\n", 506 | "\n", 507 | " def b():\n", 508 | " x = 60\n", 509 | "\n", 510 | " def c(): \n", 511 | " nonlocal x\n", 512 | " x += 100\n", 513 | " print(x)\n", 514 | "\n", 515 | " print(x)\n", 516 | " c()\n", 517 | " print(x) # after running the function c # 160\n", 518 | " \n", 519 | " print(x)\n", 520 | " b()\n", 521 | "\n", 522 | "print(x)\n", 523 | "a()" 524 | ] 525 | }, 526 | { 527 | "cell_type": "code", 528 | "execution_count": 23, 529 | "id": "74a4ade3-097f-4feb-ae7e-10398b08e2ca", 530 | "metadata": {}, 531 | "outputs": [ 532 | { 533 | "name": "stdout", 534 | "output_type": "stream", 535 | "text": [ 536 | "10\n", 537 | "20\n", 538 | "60\n", 539 | "110\n", 540 | "60\n" 541 | ] 542 | } 543 | ], 544 | "source": [ 545 | "x = 10 \n", 546 | "\n", 547 | "def a():\n", 548 | " x = 20\n", 549 | "\n", 550 | " def b():\n", 551 | " x = 60\n", 552 | "\n", 553 | " def c(): \n", 554 | " global x\n", 555 | " x += 100\n", 556 | " print(x)\n", 557 | "\n", 558 | " print(x)\n", 559 | " c()\n", 560 | " print(x) # after running the function c \n", 561 | " \n", 562 | " print(x)\n", 563 | " b()\n", 564 | "\n", 565 | "print(x)\n", 566 | "a()" 567 | ] 568 | }, 569 | { 570 | "cell_type": "markdown", 571 | "id": "97fea6b8-9216-4103-9e0f-8510cdc3c099", 572 | "metadata": {}, 573 | "source": [ 574 | "### Closure \n", 575 | "Python closure is a nested function that allows us to access variables of the outer function even after the outer function is closed." 576 | ] 577 | }, 578 | { 579 | "cell_type": "code", 580 | "execution_count": 24, 581 | "id": "82986ca6-d6ac-41b3-a687-96f4769d391e", 582 | "metadata": {}, 583 | "outputs": [], 584 | "source": [ 585 | "def outer_fun():\n", 586 | " name = \"Prabhash\"\n", 587 | "\n", 588 | " def inner_fun():\n", 589 | " print(name)\n", 590 | "\n", 591 | " return inner_fun" 592 | ] 593 | }, 594 | { 595 | "cell_type": "code", 596 | "execution_count": 25, 597 | "id": "ea4360c0-05fc-46b6-9002-f3b747eaba5f", 598 | "metadata": {}, 599 | "outputs": [], 600 | "source": [ 601 | "my_fun = outer_fun() # my_fun = inner_fun() # I am basically doing this " 602 | ] 603 | }, 604 | { 605 | "cell_type": "code", 606 | "execution_count": 26, 607 | "id": "97be14a7-4de7-4106-96ec-ba3af57f86af", 608 | "metadata": {}, 609 | "outputs": [ 610 | { 611 | "name": "stdout", 612 | "output_type": "stream", 613 | "text": [ 614 | "Prabhash\n" 615 | ] 616 | } 617 | ], 618 | "source": [ 619 | "my_fun()" 620 | ] 621 | }, 622 | { 623 | "cell_type": "code", 624 | "execution_count": 27, 625 | "id": "9ff9cdcc-1725-4e83-b390-094620695481", 626 | "metadata": {}, 627 | "outputs": [], 628 | "source": [ 629 | "def outer_fun():\n", 630 | " name = \"Prabhash\"\n", 631 | "\n", 632 | " def inner_fun():\n", 633 | " print(\"locals of inner fun are:\", locals())\n", 634 | " print(name) # free variable\n", 635 | "\n", 636 | " return inner_fun" 637 | ] 638 | }, 639 | { 640 | "cell_type": "code", 641 | "execution_count": 28, 642 | "id": "88acdfc9-79cd-47e4-97fe-a393e9bba789", 643 | "metadata": {}, 644 | "outputs": [], 645 | "source": [ 646 | "my_fun = outer_fun()" 647 | ] 648 | }, 649 | { 650 | "cell_type": "code", 651 | "execution_count": 29, 652 | "id": "1ed6f377-1c42-4820-bf9a-25e5100d0600", 653 | "metadata": {}, 654 | "outputs": [ 655 | { 656 | "name": "stdout", 657 | "output_type": "stream", 658 | "text": [ 659 | "locals of inner fun are: {'name': 'Prabhash'}\n", 660 | "Prabhash\n" 661 | ] 662 | } 663 | ], 664 | "source": [ 665 | "my_fun()" 666 | ] 667 | }, 668 | { 669 | "cell_type": "code", 670 | "execution_count": 30, 671 | "id": "cfc46598-ce7e-464a-81b0-12a96618febb", 672 | "metadata": {}, 673 | "outputs": [], 674 | "source": [ 675 | "def add(a):\n", 676 | " def addition(b):\n", 677 | " return a + b\n", 678 | " return addition" 679 | ] 680 | }, 681 | { 682 | "cell_type": "code", 683 | "execution_count": 31, 684 | "id": "918cd02d-2568-45b9-ac72-978c598462fa", 685 | "metadata": {}, 686 | "outputs": [], 687 | "source": [ 688 | "a = add(2) " 689 | ] 690 | }, 691 | { 692 | "cell_type": "code", 693 | "execution_count": 32, 694 | "id": "ae0ff133-7370-4bac-a35e-bb150eeee208", 695 | "metadata": {}, 696 | "outputs": [ 697 | { 698 | "data": { 699 | "text/plain": [ 700 | "5" 701 | ] 702 | }, 703 | "execution_count": 32, 704 | "metadata": {}, 705 | "output_type": "execute_result" 706 | } 707 | ], 708 | "source": [ 709 | "a(3)" 710 | ] 711 | }, 712 | { 713 | "cell_type": "code", 714 | "execution_count": 33, 715 | "id": "ef57c3cf-6516-4514-b812-4a51dac26114", 716 | "metadata": {}, 717 | "outputs": [ 718 | { 719 | "data": { 720 | "text/plain": [ 721 | "356567880" 722 | ] 723 | }, 724 | "execution_count": 33, 725 | "metadata": {}, 726 | "output_type": "execute_result" 727 | } 728 | ], 729 | "source": [ 730 | "a(356567878)" 731 | ] 732 | }, 733 | { 734 | "cell_type": "code", 735 | "execution_count": 34, 736 | "id": "0a4e6dab-d95b-48f0-8fbd-f88cc5ad9557", 737 | "metadata": {}, 738 | "outputs": [ 739 | { 740 | "data": { 741 | "text/plain": [ 742 | "356567883" 743 | ] 744 | }, 745 | "execution_count": 34, 746 | "metadata": {}, 747 | "output_type": "execute_result" 748 | } 749 | ], 750 | "source": [ 751 | "5 + 356567878" 752 | ] 753 | }, 754 | { 755 | "cell_type": "code", 756 | "execution_count": 35, 757 | "id": "ab105370-2075-432c-80d1-47e293313cbc", 758 | "metadata": {}, 759 | "outputs": [ 760 | { 761 | "data": { 762 | "text/plain": [ 763 | "356567880" 764 | ] 765 | }, 766 | "execution_count": 35, 767 | "metadata": {}, 768 | "output_type": "execute_result" 769 | } 770 | ], 771 | "source": [ 772 | "2 + 356567878 # this is the calculation happening here" 773 | ] 774 | }, 775 | { 776 | "cell_type": "markdown", 777 | "id": "87985b17-2698-470b-967a-29e29cbb1763", 778 | "metadata": {}, 779 | "source": [ 780 | "Usage of Closure: Data Hiding and Decorators" 781 | ] 782 | }, 783 | { 784 | "cell_type": "markdown", 785 | "id": "404cf5e9-7c9c-4718-9924-1b7f7bb85c07", 786 | "metadata": {}, 787 | "source": [ 788 | "They stores values in their locals. " 789 | ] 790 | }, 791 | { 792 | "cell_type": "code", 793 | "execution_count": 36, 794 | "id": "22872e93-6eed-403c-b39e-38f71c30a9fa", 795 | "metadata": {}, 796 | "outputs": [], 797 | "source": [ 798 | "def add(a):\n", 799 | " def addition(b):\n", 800 | " print(locals())\n", 801 | " return a + b\n", 802 | " return addition" 803 | ] 804 | }, 805 | { 806 | "cell_type": "code", 807 | "execution_count": 37, 808 | "id": "d4b67d27-39e0-45e9-8408-39df97660dfc", 809 | "metadata": {}, 810 | "outputs": [], 811 | "source": [ 812 | "a = add(3)" 813 | ] 814 | }, 815 | { 816 | "cell_type": "code", 817 | "execution_count": 38, 818 | "id": "466f5892-3d51-4deb-9b25-61cc97b0d5c6", 819 | "metadata": {}, 820 | "outputs": [ 821 | { 822 | "name": "stdout", 823 | "output_type": "stream", 824 | "text": [ 825 | "{'b': 5, 'a': 3}\n" 826 | ] 827 | }, 828 | { 829 | "data": { 830 | "text/plain": [ 831 | "8" 832 | ] 833 | }, 834 | "execution_count": 38, 835 | "metadata": {}, 836 | "output_type": "execute_result" 837 | } 838 | ], 839 | "source": [ 840 | "a(5)" 841 | ] 842 | }, 843 | { 844 | "cell_type": "code", 845 | "execution_count": null, 846 | "id": "dcda6d6e-8097-4cf7-8177-7bc694223e65", 847 | "metadata": {}, 848 | "outputs": [], 849 | "source": [] 850 | }, 851 | { 852 | "cell_type": "code", 853 | "execution_count": null, 854 | "id": "e5fbd08e-81f7-46b2-a69b-bc08a0cfb94b", 855 | "metadata": {}, 856 | "outputs": [], 857 | "source": [] 858 | } 859 | ], 860 | "metadata": { 861 | "kernelspec": { 862 | "display_name": "Python 3 (ipykernel)", 863 | "language": "python", 864 | "name": "python3" 865 | }, 866 | "language_info": { 867 | "codemirror_mode": { 868 | "name": "ipython", 869 | "version": 3 870 | }, 871 | "file_extension": ".py", 872 | "mimetype": "text/x-python", 873 | "name": "python", 874 | "nbconvert_exporter": "python", 875 | "pygments_lexer": "ipython3", 876 | "version": "3.11.4" 877 | } 878 | }, 879 | "nbformat": 4, 880 | "nbformat_minor": 5 881 | } 882 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Generative AI Full Course README 2 | 3 | ## Overview 4 | This repository contains materials for the Generative AI Full Course organized by the TensorFlow User Group Kathmandu. The course is designed to provide participants with a comprehensive understanding of generative artificial intelligence techniques and applications. 5 | 6 | ## Lead Organizer / Speaker 7 | - **Prabhash Kumar Jha** 8 | 9 | ## Organizer 10 | - **Ashish Aryal** - [LinkedIn](https://www.linkedin.com/in/ashish-aryal-030875201/) 11 | 12 | ## Course Content 13 | The course is organized into modules covering various aspects of generative AI. Each module includes lecture slides, code examples, and additional resources. 14 | 15 | ### Modules 16 | 1. 17 | 18 | ## Requirements 19 | - Python 3.11.4 20 | - Pytorch 21 | - TensorFlow 22 | - Jupyter Notebooks 23 | 24 | ## Getting Started 25 | 1. Clone this repository: 26 | 2. Navigate to the desired module directory and exercises. 27 | 3. Follow the instructions provided in the README file of each module to run the code examples and access the lecture materials. 28 | 29 | ## Contributions 30 | Contributions to this course material are welcome! If you find any issues or have suggestions for improvements, please feel free to open an issue or submit a pull request. 31 | 32 | ## Contact 33 | For any inquiries or feedback regarding the course, you can reach out to the organizers via the following channels: 34 | - Prabhash Kumar Jha: prabhashj07@gmail.com 35 | - Aashish Aryal : ashisharyal580@gmail.com 36 | 37 | ## License 38 | This course material is provided under the [MIT License](LICENSE). Feel free to use and modify it for educational purposes. 39 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | jupyter 2 | torch 3 | torchvision 4 | nbformat 5 | nbconvert 6 | --------------------------------------------------------------------------------