985 lines
78 KiB
Plaintext
985 lines
78 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "opposite-dream",
|
||
"metadata": {},
|
||
"source": [
|
||
"# A.I. Assignment 1\n",
|
||
"\n",
|
||
"Set up and familiarize with some Python packages. A simple application with random numbers.\n",
|
||
"\n",
|
||
"For this assignment you have these tasks:\n",
|
||
"1. Prepare the working environment\n",
|
||
"1. Get familiarized with Numpy (create and manipulate arrays)\n",
|
||
"1. Get familiarized with Matplotlib (display various graphics)\n",
|
||
"1. Get familiarized with Pytorch tensors (creation and manipulation)\n",
|
||
"1. Get familiarized with PIL/PILLOW (python image library)\n",
|
||
"1. Two applications: Simulate an unfair probability spinner and performe a Monte Carlo Simulation \n",
|
||
"\n",
|
||
"## Task 1 - Prepare the working environment\n",
|
||
"\n",
|
||
"In order to present the solved tasks from the laboratories a Jupyter notebook is preferred. For this prepare the working environment as follows: \n",
|
||
"\n",
|
||
"Install Anaconda distribution and navigator. Create a new environment aiclasses and inside this environment install: numpy, matplotlib, pytorch, pillow.\n",
|
||
"\n",
|
||
"Environments in Python are like sandboxes that have different versions of Python and/or packages installed in them. You can create, export, list, remove, and update environments. Anaconda allows easy management for these. \n",
|
||
"Here are the links for the packages’ documentations if you need further references: \n",
|
||
"\n",
|
||
"[Pytorch](https://pytorch.org/)\n",
|
||
"[Pillow](https://pillow.readthedocs.io/en/stable/)\n",
|
||
"[Numpy](https://numpy.org/)\n",
|
||
"[Matplotlib](https://matplotlib.org/)\n",
|
||
"\n",
|
||
"After these setups install jupyter notebook and launch it. Create a new notebook related to python 3. \n",
|
||
"\t\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "injured-telephone",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Task 2 -- Get familiarized with Numpy (create and manipulate arrays)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"id": "protecting-status",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy as np"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "pharmaceutical-disaster",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"my_array = np.array([1, 2, 3, 4])\n",
|
||
"# works as it would with a standard list\n",
|
||
"len(my_array)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "precise-safety",
|
||
"metadata": {},
|
||
"source": [
|
||
"The shape array of an array is very useful (we'll see more of it later when we talk about 2D arrays -- matrices -- and higher-dimensional arrays)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "south-smell",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"my_array.shape"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "tender-football",
|
||
"metadata": {},
|
||
"source": [
|
||
"Numpy arrays are typed. This means that by default, all the elements will be assumed to be of the same type (e.g., integer, float, String)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "terminal-loading",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"my_array.dtype"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "announced-passenger",
|
||
"metadata": {},
|
||
"source": [
|
||
"Numpy arrays have similar functionality as lists! Below, we compute the length, slice the array, and iterate through it (one could identically perform the same with a list)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "brave-buyer",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(len(my_array))\n",
|
||
"print(my_array[2:4])\n",
|
||
"for element in my_array:\n",
|
||
" print(element)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "breathing-premises",
|
||
"metadata": {},
|
||
"source": [
|
||
"There are two ways to manipulate numpy arrays: \n",
|
||
"\n",
|
||
"1. by using the numpy module's methods (e.g., `np.mean()`)\n",
|
||
"1. by applying the function `np.mean()` with the numpy array as an argument."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "proud-adobe",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"print(my_array.mean())\n",
|
||
"print(np.mean(my_array))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "deadly-divorce",
|
||
"metadata": {},
|
||
"source": [
|
||
"There are many other efficient ways to construct numpy arrays. Here are some commonly used numpy array constructors. Read more details in the numpy documentation."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "looking-voluntary",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"np.ones(10) # generates 10 floating point ones"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "considerable-adaptation",
|
||
"metadata": {},
|
||
"source": [
|
||
"Numpy gains a lot of its efficiency from being typed. That is, all elements in the array have the same type, such as integer or floating point. The default type, as can be seen above, is a float. (Each float uses either 32 or 64 bits of memory, depending on if the code is running a 32-bit or 64-bit machine, respectively)."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "cultural-memphis",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"np.dtype(float).itemsize # in bytes (remember, 1 byte = 8 bits)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "monetary-reset",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"np.ones(10, dtype='int') # generates 10 integer ones"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "illegal-stable",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"np.zeros(10)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "addressed-shadow",
|
||
"metadata": {},
|
||
"source": [
|
||
"Often, you will want random numbers. Use the random constructor!"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "applicable-gross",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"np.random.random(10) # uniform from [0,1]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "victorian-sitting",
|
||
"metadata": {},
|
||
"source": [
|
||
"You can generate random numbers from a normal distribution with mean 0 and variance 1:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "amended-handy",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"normal_array = np.random.randn(1000)\n",
|
||
"print(\"The sample mean and standard devation are %f and %f, respectively.\" %(np.mean(normal_array), np.std(normal_array)))"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "miniature-thumb",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"len(normal_array)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "immune-clinic",
|
||
"metadata": {},
|
||
"source": [
|
||
"You can sample with and without replacement from an array. Let's first construct a list with evenly-spaced values:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "soviet-excerpt",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"grid = np.arange(0., 1.01, 0.1)\n",
|
||
"grid"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "silver-vertical",
|
||
"metadata": {},
|
||
"source": [
|
||
"Without replacement"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "tropical-hypothetical",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"np.random.choice(grid, 5, replace=False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "vulnerable-regular",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"np.random.choice(grid, 20, replace=False)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "devoted-president",
|
||
"metadata": {},
|
||
"source": [
|
||
"With replacement:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "convertible-rider",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"np.random.choice(grid, 20, replace=True)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "equipped-embassy",
|
||
"metadata": {},
|
||
"source": [
|
||
"Let's create 1,000 points between -10 and 10"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "descending-motivation",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"x = np.linspace(-10, 10, 1000) # linspace() returns evenly-spaced numbers over a specified interval\n",
|
||
"x[-5:], x[:5]"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "intensive-ceremony",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Task 3 -- Get familiarized with Matplotlib (display various graphics)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "union-collins",
|
||
"metadata": {},
|
||
"source": [
|
||
"The plot() function is used to draw points (markers) in a diagram. By default, the plot() function draws a line from point to point. The function takes parameters for specifying points in the diagram. Parameter 1 is an array containing the points on the x-axis. Parameter 2 is an array containing the points on the y-axis."
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "interracial-prince",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import matplotlib.pyplot as plt\n",
|
||
"x = [1, 2]\n",
|
||
"y = [1, 5]\n",
|
||
"plt.plot(x, y)\n",
|
||
"plt.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "hawaiian-danish",
|
||
"metadata": {},
|
||
"source": [
|
||
"*Other example where we modify the line style and the color:*"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "central-maine",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import matplotlib.pyplot as plt\n",
|
||
"import numpy as np\n",
|
||
"x = np.random.randint(low=1, high=20, size=30)\n",
|
||
"plt.plot(x, color = 'blue', linewidth=3, linestyle='dashed')\n",
|
||
"plt.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "norman-speech",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Task 4 -- Get familiarized with Pytorch tensors (creation and manipulation)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 2,
|
||
"id": "colored-civilization",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import torch"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "mineral-assembly",
|
||
"metadata": {},
|
||
"source": [
|
||
" ***Creation Examples:***"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "adolescent-adelaide",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"x = torch.empty(3, 4)\n",
|
||
"print(type(x))\n",
|
||
"print(x)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "surface-harvest",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"zeros = torch.zeros(2, 3)\n",
|
||
"print(zeros)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "forty-aviation",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"ones = torch.ones(2, 3)\n",
|
||
"print(ones)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "consecutive-programming",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"torch.manual_seed(1729)\n",
|
||
"random = torch.rand(2, 3)\n",
|
||
"print(random)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "vocational-tuition",
|
||
"metadata": {},
|
||
"source": [
|
||
"Observe the last example with the seed specified. Run the following example and observe the “random” values generated:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "billion-sunday",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"torch.manual_seed(1)\n",
|
||
"random1 = torch.rand(2, 3)\n",
|
||
"print(random1)\n",
|
||
"\n",
|
||
"random2 = torch.rand(2, 3)\n",
|
||
"print(random2)\n",
|
||
"\n",
|
||
"torch.manual_seed(1)\n",
|
||
"random3 = torch.rand(2, 3)\n",
|
||
"print(random3)\n",
|
||
"\n",
|
||
"random4 = torch.rand(2, 3)\n",
|
||
"print(random4)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "whole-immigration",
|
||
"metadata": {},
|
||
"source": [
|
||
"***Tensor Shapes***\n",
|
||
"\n",
|
||
"On performing operations on two or more tensors, they will need to be of the same shape - that is, having the same number of dimensions and the same number of cells in each dimension. For that, we have the `torch.*_like()` methods:\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 3,
|
||
"id": "nonprofit-fleece",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"torch.Size([2, 2, 3])\n",
|
||
"tensor([[[-8.5047e+37, 4.2793e-41, -8.5047e+37],\n",
|
||
" [ 4.2793e-41, 0.0000e+00, 0.0000e+00]],\n",
|
||
"\n",
|
||
" [[ 0.0000e+00, 6.2841e-38, 0.0000e+00],\n",
|
||
" [ 9.1835e-41, 4.3714e-38, 4.7396e-35]]])\n",
|
||
"torch.Size([2, 2, 3])\n",
|
||
"tensor([[[5.9935e-34, 0.0000e+00, 0.0000e+00],\n",
|
||
" [0.0000e+00, nan, 0.0000e+00]],\n",
|
||
"\n",
|
||
" [[3.0601e+32, 1.8179e+31, 2.7947e+20],\n",
|
||
" [2.2855e+20, 9.3168e-39, 3.8016e-39]]])\n",
|
||
"torch.Size([2, 2, 3])\n",
|
||
"tensor([[[0., 0., 0.],\n",
|
||
" [0., 0., 0.]],\n",
|
||
"\n",
|
||
" [[0., 0., 0.],\n",
|
||
" [0., 0., 0.]]])\n",
|
||
"torch.Size([2, 2, 3])\n",
|
||
"tensor([[[1., 1., 1.],\n",
|
||
" [1., 1., 1.]],\n",
|
||
"\n",
|
||
" [[1., 1., 1.],\n",
|
||
" [1., 1., 1.]]])\n",
|
||
"torch.Size([2, 2, 3])\n",
|
||
"tensor([[[0.9067, 0.8428, 0.2423],\n",
|
||
" [0.5723, 0.8805, 0.9745]],\n",
|
||
"\n",
|
||
" [[0.3893, 0.6402, 0.8499],\n",
|
||
" [0.7114, 0.9586, 0.4303]]])\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"x = torch.empty(2, 2, 3)\n",
|
||
"print(x.shape)\n",
|
||
"print(x)\n",
|
||
"\n",
|
||
"empty_like_x = torch.empty_like(x)\n",
|
||
"print(empty_like_x.shape)\n",
|
||
"print(empty_like_x)\n",
|
||
"\n",
|
||
"zeros_like_x = torch.zeros_like(x)\n",
|
||
"print(zeros_like_x.shape)\n",
|
||
"print(zeros_like_x)\n",
|
||
"\n",
|
||
"ones_like_x = torch.ones_like(x)\n",
|
||
"print(ones_like_x.shape)\n",
|
||
"print(ones_like_x)\n",
|
||
"\n",
|
||
"rand_like_x = torch.rand_like(x)\n",
|
||
"print(rand_like_x.shape)\n",
|
||
"print(rand_like_x)\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "detected-committee",
|
||
"metadata": {},
|
||
"source": [
|
||
"***Moving to GPU***\n",
|
||
"\n",
|
||
" First, we should check whether a GPU is available, with the is_available() method.\n",
|
||
"\n",
|
||
" **If you do not have a CUDA-compatible GPU and CUDA drivers installed, the executable cells in this section will not execute any GPU-related code.**\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "armed-opposition",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"if torch.cuda.is_available():\n",
|
||
" print('We have a GPU!')\n",
|
||
"else:\n",
|
||
" print('Sorry, CPU only.')"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "expressed-minority",
|
||
"metadata": {},
|
||
"source": [
|
||
"A common way to handle this situation is this: "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "healthy-assembly",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"if torch.cuda.is_available():\n",
|
||
" my_device = torch.device('cuda')\n",
|
||
"else:\n",
|
||
" my_device = torch.device('cpu')\n",
|
||
"print('Device: {}'.format(my_device))\n",
|
||
"\n",
|
||
"x = torch.rand(2, 2, device=my_device)\n",
|
||
"print(x)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "blessed-processing",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Task 5 -- Get familiarized with PIL/PILLOW (python image library)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "unauthorized-institution",
|
||
"metadata": {},
|
||
"source": [
|
||
"A. Display an image with pillow (the image must be in the same folder for these examples to run, and we considered the name of the image file `opera.jpg`):"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "hearing-ecuador",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# load and show an image with Pillow\n",
|
||
"from PIL import Image\n",
|
||
"# load the image\n",
|
||
"image = Image.open('opera.jpg')\n",
|
||
"# summarize some details about the image\n",
|
||
"print(image.format)\n",
|
||
"print(image.mode)\n",
|
||
"print(image.size)\n",
|
||
"# show the image\n",
|
||
"image.show()\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "broken-package",
|
||
"metadata": {},
|
||
"source": [
|
||
"B. Convert the image to a numpy array:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "abstract-proportion",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# load and display an image with Matplotlib\n",
|
||
"from matplotlib import image\n",
|
||
"from matplotlib import pyplot\n",
|
||
"# load image as pixel array\n",
|
||
"data = image.imread('opera.jpg')\n",
|
||
"# summarize shape of the pixel array\n",
|
||
"print(data.dtype)\n",
|
||
"print(data.shape)\n",
|
||
"# display the array of pixels as an image\n",
|
||
"pyplot.imshow(data)\n",
|
||
"pyplot.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "respective-relief",
|
||
"metadata": {},
|
||
"source": [
|
||
"C. Resize an image to a specific dimension:"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"id": "floral-cooler",
|
||
"metadata": {
|
||
"scrolled": true
|
||
},
|
||
"outputs": [],
|
||
"source": [
|
||
"# create a thumbnail of an image\n",
|
||
"from PIL import Image\n",
|
||
"# load the image\n",
|
||
"image = Image.open('opera.jpg')\n",
|
||
"# report the size of the image\n",
|
||
"print(image.size)\n",
|
||
"# create a thumbnail and preserve aspect ratio\n",
|
||
"image.thumbnail((100,100))\n",
|
||
"# report the size of the thumbnail\n",
|
||
"print(image.size)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "insured-organic",
|
||
"metadata": {},
|
||
"source": [
|
||
"D. Other operations can be found at the address [How to Load and Manipulate Images for Deep Learning in Python With PIL/Pillow](https://machinelearningmastery.com/how-to-load-and-manipulate-images-for-deep-learning-in-python-with-pil-pillow/) \n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "armed-biotechnology",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Task 6 -- An application: Simulate an unfair probability spinner"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "quick-christian",
|
||
"metadata": {},
|
||
"source": [
|
||
"Conside an unfair probability spinner with $n$ slots. Each slot has a probabilty $P_n \\in [0,1]$ and $\\sum_{i=0}^{n-1}P_i = 1$. \n",
|
||
"\n",
|
||
"Write a function that random generate an index $i$ with the probability $P_i$ from the set $\\{0, 1, ..., n\\}$. "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 4,
|
||
"id": "together-ownership",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"\n",
|
||
"def spinner(probabilityDistribution):\n",
|
||
" return np.random.choice(np.arange(0, len(probabilityDistribution)), p=probabilityDistribution)\n",
|
||
" "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 31,
|
||
"id": "77ffb8f2",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import random\n",
|
||
"\n",
|
||
"def spinner_cumulative(probabilityDistribution):\n",
|
||
" cumulativeDistribution = []\n",
|
||
" cumulative_sum = 0\n",
|
||
" for probability in probabilityDistribution:\n",
|
||
" cumulative_sum += probability\n",
|
||
" cumulativeDistribution.append(cumulative_sum)\n",
|
||
" \n",
|
||
" random_number = random.uniform(0, 1)\n",
|
||
" index = 0\n",
|
||
" for i, cumulative_prob in enumerate(cumulativeDistribution):\n",
|
||
" if random_number <= cumulative_prob:\n",
|
||
" index = i\n",
|
||
" break\n",
|
||
" \n",
|
||
" return index\n"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 40,
|
||
"id": "26c6ab2f",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"2\n",
|
||
"[0.29782, 0.19897, 0.50321]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print(spinner_cumulative([0.3,0.2,0.5]))\n",
|
||
"\n",
|
||
"val = [0, 0, 0]\n",
|
||
"for i in range(100000):\n",
|
||
" val[spinner_cumulative([0.3,0.2,0.5])] += 1\n",
|
||
"print([v/100000 for v in val])"
|
||
]
|
||
},
|
||
{
|
||
"attachments": {
|
||
"chart.png": {
|
||
"image/png": "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"
|
||
}
|
||
},
|
||
"cell_type": "markdown",
|
||
"id": "3be14413",
|
||
"metadata": {},
|
||
"source": [
|
||
"The same problem but instead of a distribution of probability the input is a list of natural numbers that holds how many degrees has the center angle $\\theta_i$ corespondent to index $i$.\n",
|
||
"\n",
|
||
"### Example:\n",
|
||
"\n",
|
||
"Consider we have a wheel with 4 slots as in Figure \n",
|
||
"\n",
|
||
"\n",
|
||
"\n",
|
||
"When we spin the wheel we get for example blue index with $12.86\\%$ chances. "
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 12,
|
||
"id": "e38ae234",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"\n",
|
||
"def spinner_360(probabilityDistribution):\n",
|
||
" return np.random.choice(np.arange(0, len(probabilityDistribution)), p=[i/360 for i in probabilityDistribution])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 34,
|
||
"id": "ae5de145",
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import random\n",
|
||
"\n",
|
||
"def spinner_360(probabilityDistribution):\n",
|
||
" probabilityDistribution = [i/360 for i in probabilityDistribution]\n",
|
||
" cumulativeDistribution = []\n",
|
||
" cumulative_sum = 0\n",
|
||
" for probability in probabilityDistribution:\n",
|
||
" cumulative_sum += probability\n",
|
||
" cumulativeDistribution.append(cumulative_sum)\n",
|
||
" \n",
|
||
" random_number = random.uniform(0, 1)\n",
|
||
" index = 0\n",
|
||
" for i, cumulative_prob in enumerate(cumulativeDistribution):\n",
|
||
" if random_number <= cumulative_prob:\n",
|
||
" index = i\n",
|
||
" break\n",
|
||
" \n",
|
||
" return index"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 41,
|
||
"id": "e2ae60c3",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0\n",
|
||
"[0.24911, 0.25038, 0.25217, 0.24834]\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"print(spinner_360([90,90,90,90]))\n",
|
||
"\n",
|
||
"val = [0, 0, 0, 0]\n",
|
||
"for i in range(100000):\n",
|
||
" val[spinner_360([90,90,90,90])] += 1\n",
|
||
"print([v/100000 for v in val])"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"id": "c0da82ad",
|
||
"metadata": {},
|
||
"source": [
|
||
"## Task 7 -- Determine some outcomes using Monte Carlo Simulations"
|
||
]
|
||
},
|
||
{
|
||
"attachments": {
|
||
"MCSIM.jpg": {
|
||
"image/jpeg": "/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAIBAlsDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3+iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqnqmqWej2D3t9L5cKYHALMzHgKqjlmJ4AHJq5XDxSf8JDrkury/NZ2kjwadGemVJWSb6sQVB7KMj7xqoxu7Ck7K5JJca9rvzzXEmjWLfdtrcqbhh/00k5Cf7qcj+8arnwjoMvN1psV63d74m5Y/UyFjW3RW6ikYOTZir4U0eA7rG3fTn7Pp8rW5H4IQD9CCKsR6vrPh/nUGfV9MH3p0jAuoB6sqgCVR32gMPRq0qKHBMFJo3LW6gvbWK6tZkmt5VDxyRtlWU9CDUtcXpkn/CO+Io7VONK1WRtidoLrBY49FkAY4/vD1eu0rnas7G6d1cKKKKQwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAKeqapZ6NYPe30vlwpgcAszMeAqqOWYngAcmuWkuNe13557iTRrFvu21uVNyw/6aSchP91OR/eNMik/4SHXJdXl+aytJHt9OjPTKkrJN9SQVB7KMj7xrXraEOrMpz6IxD4R0GU5utNivX7vfE3LH6mQsaVfCuk2/wA2nwyaZIOj6fK0GP8AgKkKfoQRW1RWlkZ3ZnQeINR8PsE16QXmmk4GpogV4f8Arug42/7agAd1A5rsVZXUMpBUjIIPBFc8yhlKsAVIwQehql4ambRdWbw67E2UsbXGmk/8s1BHmQ/Rchl/2SR0WsZwtqjW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AUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/2Q=="
|
||
}
|
||
},
|
||
"cell_type": "markdown",
|
||
"id": "5d27f3f8",
|
||
"metadata": {},
|
||
"source": [
|
||
"Consider a large pipe with a radius $R = 30 cm$ that has the opening pointing straight up, as in the figure. Around this pipe is a rectangular wall with an edge $l = 1m$. Balls of radius $r = 1 cm$ fall down uniformly from above inside the square yard. Compute, using a Monte Carlo simulation, the probability that a ball falls inside the pipe. Compare the results with the mathematically deduced probability.\n",
|
||
"\n",
|
||
""
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": 42,
|
||
"id": "6ddea90c",
|
||
"metadata": {},
|
||
"outputs": [
|
||
{
|
||
"name": "stdout",
|
||
"output_type": "stream",
|
||
"text": [
|
||
"0.264139\n",
|
||
"0.2642079421669016\n"
|
||
]
|
||
}
|
||
],
|
||
"source": [
|
||
"import numpy as np\n",
|
||
"import math\n",
|
||
"\n",
|
||
"\n",
|
||
"l=100\n",
|
||
"r=1\n",
|
||
"R=30 - r\n",
|
||
"inside = 0\n",
|
||
"outsite = 0\n",
|
||
"\n",
|
||
"number_of_trials = 1000000\n",
|
||
"for i in range(number_of_trials):\n",
|
||
" x = np.random.uniform(-l/2, +l/2)\n",
|
||
" y = np.random.uniform(-l/2, +l/2)\n",
|
||
" if x**2 + y**2 < R**2:\n",
|
||
" inside += 1\n",
|
||
" else:\n",
|
||
" outsite += 1\n",
|
||
"\n",
|
||
"print(inside/number_of_trials)\n",
|
||
"theoretical_probability = (math.pi * R**2) / (l**2)\n",
|
||
"print(theoretical_probability)"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernel_info": {
|
||
"name": "python"
|
||
},
|
||
"kernelspec": {
|
||
"display_name": "Python 3",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.12.2"
|
||
},
|
||
"nteract": {
|
||
"version": "nteract-front-end@1.0.0"
|
||
},
|
||
"polyglot_notebook": {
|
||
"kernelInfo": {
|
||
"defaultKernelName": "csharp",
|
||
"items": [
|
||
{
|
||
"aliases": [],
|
||
"name": "csharp"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 5
|
||
}
|