Thanks to visit codestin.com
Credit goes to pyofpython.wordpress.com

BEFORE STARTING ANYTHING A BIG THANK YOU TO ALL

Simplifying Regular Expression Using Python made it to the Best New Regular Expressions eBooks.

I’m happy to announce that my book, “Simplifying Regular Expression Using Python: Learn RegEx Like Never Before”, made it to BookAuthority’s Best New Regular Expressions eBooks:
https://bookauthority.org/books/new-regular-expressions-ebooks?t=q95spu&s=award&book=1094777978
BookAuthority collects and ranks the best books in the world, and it is a great honour to get this kind of recognition. Thank you for all your support!

To learn python from basics, subscribe the YouTube channel.

The book is available for purchase on Amazon.

Machine Learning Numerical Practice

Q.1 Based on the given data below which depicts the Bayesian Belief Network respond to the following questions:

(i) Draw the probability table for each node in the network. 

(ii) Use the Bayesian Network to predict the car value for the following:

P (Mileage = Low, Engine = Bad, Air Condition = Broken)

MileageEngineACNo. of records with car value = HighNo. of records with car value = Low
HighGoodWorking34
HighGoodBroken12
HighBadWorking15
HighBadBroken04
LowGoodWorking90
LowGoodBroken51
LowBadWorking12
LowBadBroken02

Solution- We’ll first draw the probability table for each node in the Bayesian Belief Network (BBN), then we’ll use the network to predict the car value for the given scenario.

(i) Probability Table for Each Node:

(ii) Predict Car Value:

Let’s calculate the probabilities and perform the prediction.

Probability Table for Each Node:

Predict Car Value:

Q.2 Explain how KNN method is implemented. Below is information regarding players speed and agility that will be used to determine whether he’ll be drafted into the team? Predict the likelihood that the player with speed = 6.75 and agility = 3 will make the team using KNN model assuming K = 3? 

IDSpeedAgilityDrift
112.002.00NO
125.002.50NO
138.258.50YES
145.758.75YES
154.756.25YES
165.506.75YES
175.259.50YES
187.004.25YES
197.508.00YES
207.255.75YES

Solution- The K-Nearest Neighbors (KNN) algorithm is a simple, instance-based learning algorithm used for classification and regression tasks. Here’s how it’s implemented and how you can use it to predict whether a player will be drafted into the team:

Data Preparation:

Prepare your dataset with features and labels. In this case, features are “Speed” and “Agility”, and the label is “Draft” (whether the player is drafted or not).

Calculate Distance:

For a given new data point (player with speed = 6.75 and agility = 3), calculate the distance to all other data points in the dataset. Typically, Euclidean distance is used for this calculation. Euclidean distance between two points (x1, y1) and (x2, y2) is calculated as:

Find K Nearest Neighbors:

Sort the calculated distances and select the K nearest neighbors to the new data point.

Majority Vote:

For classification, count the occurrences of each class among the K nearest neighbors.

Assign the new data point to the class that appears most frequently among its K nearest neighbors.

Predict Outcome:

Once you have the majority class among the K nearest neighbors, assign that class as the predicted outcome for the new data point.

Let’s calculate the Euclidean distances for the given data point (speed = 6.75, agility = 3) and find the K nearest neighbors. Then, we’ll predict the likelihood of being drafted into the team.

Given data point:

  • Speed = 6.75
  • Agility = 3

We’ll calculate the distance from this point to all other points in the dataset and find the 3 nearest neighbors. Then, we’ll determine the majority class among these neighbors and predict the outcome for the given data point.

Let’s calculate the distances:

Now, let’s find the 3 nearest neighbors:

  1. Nearest Neighbor: ID 18 (Distance ≈ 1.275)
  2. Second Nearest Neighbor: ID 12 (Distance ≈ 1.82)
  3. Third Nearest Neighbor: ID 16 (Distance ≈ 3.251)

Among these 3 neighbors:

  • ID 18: Draft = YES
  • ID 12: Draft = NO
  • ID 16: Draft = YES

So, the majority class is “YES” (drafted). Therefore, according to the KNN model with K=3, the likelihood that the player with speed = 6.75 and agility = 3 will make the team is “YES”.

Q.3 Replace the old weights (not the bias) in the network depicted in the following figure using a back propagation algorithm. A [0, 1] input pattern is given to the network, and the desired output is 1. Use the sigmoid activation function and a learning rate of 0.3.

Solution- To solve this problem, we need to perform a single iteration of the back-propagation algorithm on the given neural network with a specified learning rate of 0.3. The input pattern is [0,1] and the desired output is 1. We will use the Sigmoid activation function.

Let’s follow these steps:

  1. Forward Pass:
    • Calculate the net input and output for each neuron.
    • Use the Sigmoid function for activation.
  2. Backward Pass:
    • Calculate the error at the output.
    • Propagate the error backward through the network.
    • Update the weights using the learning rate.

Given:

Given this framework, let’s start with the initial weights and biases directly from the network diagram, and compute each step accordingly.

These are the new weights and biases after performing one iteration of the back-propagation algorithm with the provided values.

Q.4 Use K-means clustering to cluster the following data into 2 groups. Assume cluster centroids are m1 = 2 and m2 = 4. The distance function used is Euclidean distance. {2, 4, 10, 12, 3, 20, 30, 11, 25}

Solution- To perform K-means clustering with 2 clusters using the given data and initial centroids m1=2 and m2=4, we’ll follow these steps:

  1. Initialize the centroids: Set m1=2 and m2=4.
  2. Assign data points to clusters: Calculate the Euclidean distance between each data point and the centroids. Assign each data point to the cluster with the nearest centroid.
  3. Update centroids: Recalculate the centroids based on the mean of the data points assigned to each cluster.
  4. Repeat steps 2 and 3 until convergence or a predefined number of iterations.

Given data: {2, 4, 10, 12, 3, 20, 30, 11, 25}

Step 1: Initialize the centroids:

  • m1=2
  • m2=4

Step 2: Assign data points to clusters:

Assign each data point to the cluster with the nearest centroid.

Calculate the distance of each data point from the centroids.

Step 3: Update centroids:

  • Calculate the mean of the data points assigned to each cluster and update the centroids.

Reading image using OpenCV in NVIDIA Jetson Nano

To start with, we’ll take a very easy project, that is, to read any image file and display it. So, we’ll be using OpenCV, Python, Numpy, everything in NVIDIA Jetson Nano. So, I have created one folder on my desktop on which I’ll saving all my work. Let’s do the coding part first. First, i’ll get inside the folder where I want my work to be stored.

Now type gedit. This will open the editor to code. You can also use nano editor. But gedit is basic and more flexible to do editing then nano editor. Of course you can use other Linux supported editors as well.

Now it’s time to write the code in your editor.

import cv2
import numpy as np

im = cv2.imread(‘lenna.jpg’)

cv2.imshow(‘im’, im)
cv2.waitKey(0)
cv2.destroyAllWindows()

The code is very easy. It’s traditional OpenCV code. But since this is our first code we’ll dissect it:

  1. We are importing numpy and opencv libraries first. In this specific code, numpy is not doing anything so we can ignore it. But I am habitual to call it so, no problem.
  2. Then using imread (image read) we are reading the image file. Here, the file name is Lenna and it’s extension is .jpg. Now do remember that the file is stored in the same folder which is ocv in my case. So, I don’t need to specify the complete path. In the later posts, we’ll see how to give complete path also.
  3. Using imshow (image show), the image will be displayed. Pass in the variable name which is used to read the image file.
  4. After displaying the image the question is till how much time you want to display it. For this, waitkey is used. As the name suggest, it will wait for a specific time in milliseconds until you press any key on the keyboard. If you want that the image should be displayed for indefinite time period, then write waitkey (0).
  5. Finally, we will close all windows using destroyAllWindows ().  If you have multiple windows open and you do not need those to be open, you can use cv2.destroyAllWindows() to close those all.

Waitkey can also destroy the windows but in many cases, it cannot. Especially in python scripts running from terminals. So, it’s good practice to use destroyAllWindows ()

After writing it, save the file with any non-python keyword. Save it using .py extension. I am saving it with the name f1.py. Time to execute the code now. On the terminal, write python fi.py and press enter

And the image will be displayed as shown above. As you can see, there is no provision in the code to terminate the program other than the keyboard interrupt but you can add few lines also to terminate the program by pressing any specific key. We’ll see this also in the coming posts. i am trying to go step by step without a rush and with minimum python knowledge.

That’s it. This was our first project using OpenCV. Now you can do this on any OS and on any python editor. But our purpose here is to see what NVIDIA Jetson Nano is capable of. That’s why we are using this.

In the next article we’ll explore more of OpenCV and Python in NVIDIA Jetson Nano 2 GB Kit.

Installing the Operating System and required Dependencies

The first thing to do is to install the operating system for our NVIDIA Jetson Nano 2 GB Kit. For this, you need to download image to the SD Card. Now this is going to be a time testing process, because this is 6.1 GB image file. To down load follow this link,

https://developer.nvidia.com/embedded/learn/get-started-jetson-nano-2gb-devkit#write

The screen after clicking the above link looks something like this-

Let’s zoom a bit-

When we click on this green colour statement in first point. Our download starts. So, its going to be time taking process so in the mean time download 2 more software which we will need immediately after downloading the image file. They are Card Formatter and Etcher to format your SD Card and then write the downloaded file on the formatted card respectively.

If you scroll down a bit in the above link, you will see that, there are 3 options:

I’ll be using Linux so I’ll click on INSTRUCTIONS FOR LINUX and then the link for downloading Etcher software will be seen as shown above. And further scrolling down will guide you step by step to prepare your SD Card with the required Operating System. So I’ll not dive deep into this thing.

After performing the above, your SD card is ready. So, inserting it into the NVIDIA kit and providing the power supply will turn it on. Now the process is similar to that of installing any windows or Linux OS in some mainframe computer. The desktop looks like this:

Cool!! So, we are all set to start with our NVIDIA Jetson Nano 2 GB Kit.

We need few software to install first. The kit is working on Python 3.6. This kit is compatible with Numpy version 1.16. So, I strongly suggest you to don’t upgrade it. You’ll need to install TensorFlow to perform Deep Learning projects. For this you can blindly follow the official documentation via the following link:

https://docs.nvidia.com/deeplearning/frameworks/install-tf-jetson-platform/index.html

Just follow the steps given here in this link. After everything is done, open your terminal and check the versions of numpy, tensorflow and opencv before starting anything.

You can see that python version is 3.6.9, numpy is 1.16.1, opencv version is 4.5.3 and tensorflow version is 2.3.1.

So, here I want to give my opinion that company like NVIDIA must know the latest versions of python, numpy, opencv and tensorflow. Still they opted for some old versions (ARM processor limitation may be). My suggestion will be that don’t upgrade to latest versions. (I go for Numpy 1.19 and believe me, just after some time I came back to 1.16).

That’s it. Our mini PC is all set to start AI and ML/ DL projects.

About this Kit

NVIDIA Jetson Nano 2GB Developer Kit is one of the most pocket friendly trainer kit on which AI computational models and projects can be deployed. So, in this section, I’ll be demonstrating small projects which can be made by using this kit. Although you don’t need this kit to build these projects (you can use any editor also), but if you want to deploy your project using some hardware, then this kit is going to be your 1st choice (it’s very pocket friendly with great features, trust me).

Talking about technical specifications of this kit, the kit offers:

  • 128-core NVIDIA Maxwell GPU
  • Quad-core Arm Cortex- A57 MPCore processor
  • 2GB LPDDR4 Memory
  • MicroSD Card Slot
  • 1 USB 3.0 Type A port
  • 2 USB 2.0 Type A ports
  • USB 2.0 Micro B (Device Mode Only)
  • HDMI Port
  • Gigabit Ethernet Port
  • 1 MIPI CSI-2 Camera Connector
  • 40 Pin Expansion Header (UART, SPI, I2S, I2C, GPIO)
2GB NVIDIA Jetson Nano Developer Kits with connections done

As you can see in above figure this is how you have to connect your kit with your monitor. Looking from the top connector, 1st is LAN or Ethernet cable. Then there are two ports one above the other. I have connected USB keyboard and USB mouse in them respectively. Next USB port has webcam connected. I am using Logitech Webcam. Then, there is HDMI Port. I am using an old Dell Monitor so I have used HDMI to VGA converter as well. The white cable at last is Power Supply through USB C (5V 3A).

There is a card slot underneath the big black heat sink. I am using 128 GB micro SD card. You can use any size starting from 32 GB.

With these hardware requirements, we are all set to start with the NVIDIA Jetson Nano 2GB Developer Kit.

Generators

A generator function is a function which returns the generator- iterator with the help of yield function. It means that a generator generates iterators. In simple words, a generator produces the result when needed, while an iterator produces the entire result.  In the previous article we learned about iterators. To make a generator, yield () function is used. Let’s take the same example of squaring the list elements. But now we don’t need to append and return anything. We just need to write a yield followed by the operation to be performed. It’s more readable also. For each value present in the list, yield the square of the value. No append, no return and no need to store it in an empty list.

If we see this, the output generated is not a list of squared numbers. Generators don’t hold the entire result in the memory. It hasn’t done anything yet. It’s waiting for us to ask to give the next result. And for this next function is used. So, I’ll write my function and argument inside the next function and print it.

So, it’ll print the next result. That’s the squared value of the first element of the given list. It’s again waiting for us to ask what to do next. Let’s print the next values.

OK. All values are printed. Oh yes, we don’t need the empty list as well. What will happen if we still ask to print the next step?

Stop Iteration error occurs. It means that the generator has exhausted as there are no further values in the list to generate the next value. There is a much better approach to write so many next statements by using a for loop.

This will check for all values of elements in the given list and print the result. Basically, what we were getting with iterators in the last chapter, we are getting with generators as well. But here we have more control on executing our output. 

We can also write a generator comprehension just like a list comprehension. Two things we have to remember. First, use normal parentheses instead of square brackets. Second, we know that a generator will give only one value at a time, so to get the next result we’ll write the for loop again.

These outputs are not holded up all at once in memory. What if you want to print out all the values from the generator? We can convert this into a list. If you want to convert it into a list, use the list function and pass the generator into it.

Let me take another example. Now I am making the program of the Fibonacci series as a generator function. 

Everything is like what we have done before. The only difference is now we are using the yield keyword with our output. When the program executes the yield statement, it stops. When we ask it to fetch the next value, then only it’s iterating.

So what is the advantage of this generator over the iterators? The main advantage is that you can save huge heaps of memory at the cost of having extra execution time for generating the next iterable object. But the limitation of a generator function is that they are slow because they execute once. You can also convert your generator output to become a list using the list function. If you need to save memory and don’t care about execution time use a generator, and if you don’t care about high memory usage and need a little bit faster execution time use a list. 

Iterators and Iterables

So we have learned about lists, and we also have seen the concept of functions. Let’s make a function which will print the squares of all elements of the given list. What we have done earlier is take an empty list, check for each element present in my given list, square each element and append the squared value in the empty list. Finally, print the empty list. In function, we have to put the above logic inside def function and instead of printing the result of an empty string, we will return this result back to the def function and will print the function. Let’s code it now.

So we got a list of squared values of the given list. Let’s deep dive into this small already done program. What is this for loop doing? It’s checking for the first value, then the second, then the third value and so on till all values are fetched. In the language of mathematics, it’s performing iterations, and thus it’s an iterator.

So,  iterators are used to fetch one value at a time.  Other than using this for loop, there are two more ways to fetch one value at one time. The first method is using index position. We can write a[0] and it will give the first value, a[1] will give a second value and so on. But this indexing method won’t work on unordered data structures, such as sets and dictionaries.

Another method is to use a function called iter (). It’s written as the double underscore iter followed by double underscore. These double underscore methods are also called the magic methods. This double underscore iter method helps us to find out if something is iterable or not. We know that lists are iterable. Anything on which the loop can run are iterables. When we write for I in list, it means that for loop is trying to loop over our list. String, dictionaries, sets, tuples all are iterables because we can use loops to fetch data from them. Let’s make a list and by using dir () we will check if it has __iter__ method or not. If this method exists then that thing becomes iterable.

As you can see the marked red circle, it has the iter method.

It means that lists are iterable because it has this method. But is it an iterator? Can we use a list to do the function of a for loop? Iterator has a state through which it knows where it is during an iteration and by using double underscore next method they get their next value. If we see here in the output then there is no next method. Hence, a list has no state to check the next value and that’s why a list is not an iterator. 

So the list has no attribute next. This can be verified from the previous output as well. There you can see the iter () method but not the next() method. That’s why lists are not iterators although they are iterables. There is another way to write these magic methods. Usually they are written as functions. Let’s pass my list name into this iter function.

Similarly, we can use the next () function.

OOPS!! An error occurred. If the list has become an iterator then it should have the next() attribute also so that it can iterate the next value. Let me first pass this into another variable and then print it. 

Now it’s working correctly. You can see that both __iter__ and __next__ method are present.

This next () method preserves the state of the last value. So what the for loop does is that it calls iter on our object and returns an iterator that we can loop over. At the back end it calls for the next function again and again and generates all the values. The iterators use both the iter and the next methods continuously at its back end to fetch next values and then print the complete result. Conceptually, now you know why for loops or any other loops are iterators, how they iterate and why everything cannot be an iterator? This knowledge is also helpful in making our own iterator functions using the iter function. But there is another method through which you can make iterators without using the iter.

Which method is used to pass arguments in functions in python?

We usually do not come across this question but it’s a great interview question in C programming language. By default C uses pass by value method or pass by reference method to pass functions argument?

Now this question does not come in python programming. Because… Python do not need these? Or it uses both? Let’s see the concept and try to understand.

Pass by Value

In this the function creates a copy of the variable passed as an argument. The actual object is not affected. In this case, the variable is of immutable type and cannot be modified.

You can see that the variable is an immutable type object. The actual value is not changed and the memory address is also different.

Pass by Reference

In this the actual variable is passed as an argument. All the changes made to the object inside the function affects the original value. In this case, the variable is of mutable type and can be modified.

You can see that the variable is a mutable type object (list here). The actual value is also changed and the memory addresses are same.

It means that python uses both methods to pass arguments and that’s why we usually don’t come across this topic in books.

Recursive Functions

When a function calls itself, this process is called Recursion. Let’s understand this concept using the most used example of finding the factorial of a given number. Mathematically, the factorial of a number is given by multiplying the number with its decreasing value, one at a time, till 1. For example, the factorial of 5 is written as 5 ! = 5 x 4 x 3 x 2 x 1. If we observe this, we can say that it’s 5 x 4 !  Because 4 ! = 4 x 3 x 2 x 1. Again, it can be written as 4 x 3 !,  because 3 ! = 3 x 2 x 1. Again, it can be written as 3 x 2 !,  because 2 ! = 2 x 1. Again, it can be written as 2 x 1 !,  because 1 ! = 1 x 1. In generalized form we can write it as, n x (n-1) !. Starting with n = 5, it will first call (n-1) !, that is 4 !. Now the new value of n will be 5 x 4 x (n-1) !., then it will again be 3 !. Now the new value of n will be 5 x 4 x 3 x (n-1) !, then, it will again call 2 !, and finally, it will again call 1 !. This is how a function calls itself. Let’s code this.

So, we can define recursion as a process in which a function breaks down into smaller problems, and it keeps calling itself for each of the smaller problems until a base case is reached. Like here, the base case is 1 !. What does a non- recursive or general iterative factorial function look like? 

It’s a general function. There are some differences between iteration and recursion.

  • Recursion requires more memory.
  • In many languages Iteration is a much faster approach.
  • Recursion sometimes can be a more abstract and harder approach to understand.
  • Recursion is practically a faster method for applications like traversing trees and binary search.

Is there a limit to which a function can call itself? What’s the difference between a function which can call itself for infinite times and a recursive function? Let’s call a function recursively without having a base or terminal case and see if it’s an infinite function or has some limit.

The function endgame () is calling itself again and again and we are not providing a limit. When I executed this code, the output I got was a lot of Avengers Assemble printing continuously and then after sometime an error occurred.

Recursion Error, and it says that OK there is some maximum recursion depth. Is there a default value? For this recursion provides a method called .getrecursionlimit (). We have to import a module called sys. Let’s see how to use it and what value is generated, if any default value is there.

Look at the first line of the output. It’s displaying a value of 3000. This may be our default value. We can also set this limit by using another method called  .setrecursionlimit (). We can pass the value up to which we want that the function calls itself.

The value is now 2000 as set. I am also using a global variable i, to keep a count of my output numbers generated. So, basically Recursion is a desired condition and accidently if it enters an infinite loop condition, a default value has been set to avoid our program from being crashed or the system being hanged.

A new argument introduced in Python 3.8

We saw earlier keywords arguments. Python 3.8 has introduced a new feature in functions known as positional only arguments. For this, / sign is added after the desired arguments, separated by comma. All arguments written before / sign can be passed only positionally and written after this sign can be passed positionally or by using the keyword. The following example illustrates this example.

The error says that we have passed positional only arguments as keyword arguments.

Here, one can observe that variables x and y can be written as positional only, but z can be passed with and without keyword z. Let’s also check what will be the output without using this argument?

We can see that without positional only argument, /, arguments can be passed with or without keywords.

Anonymous Functions in Python

Anonymous functions are also called lambda functions in Python because instead of declaring them with the standard def keyword, lambda keyword is used.

Anonymous functions are used when there is a requirement of a nameless function for a short period of time. These functions are created at runtime. Depending upon the program you need, lambda function works in conjunction with filter(), map() and reduce():

The filter() function filters, as the name suggests, the original input on the basis of the conditions given. With map(), you apply a function to all items of the list. The reduce() function is part of the functools library. You use this function cumulatively to the items of the list, from left to right and reduce the sequence to a single value. Let’s see how to use them.

The function sq(n) is having a parameter n which will return a value of n multiplied with 3. For example, when n = 3, the output is 6. The same can be written using the lambda function.

We will use the lambda keyword. The parameter is written first. Then a colon sign is placed. Then the operation is written. Let’s see one more example.

The program is simple. It’s checking that in between two numbers, which number is bigger. There are two parameters, m and n. While writing with lambda we will write lambda m,n. Then, we have the body part. It will return the result m if m>n, else it will return the value n. Let’s write it now using the lambda function.

I have a list of numbers, and the task is to generate another list which will contain the squared value of the previous list. There will be a list. Then, an empty list will be generated. We will check every value of our list. We will square every element and then will append every value in the empty list. Then we will return the empty list. Let’s code it down first using a function. 

With lambda we can write it like this. We have x and this variable has to be squared, that is, x**2. But from where it will take these values of x. From the list l. Now we will need to map our squared result with our list l. For this, the  map function is used. This function is then passed through the list function.

Let’s take the above list and do another operation. We have to make a list of elements which are greater than two. We only have to check that if x>2, then we will append this value of x, in an empty list. Then finally, return this empty list.

Technically, we are filtering our data. We are filtering those values of x, which are greater than 2. 

We will write a filter command instead of map command. We can also use the map command. It will print the result in Boolean.

3 and 4 are greater than 2, hence, a True Boolean value is displayed. For 1 and 2, False Boolean value is printed. Let’s do one more task. I need to multiply each value of my list and print the result. In the above case, my list has values 1,2,3,4. The result will be 1x2x3x4 = 24.  

In this case, we will need to reduce our list to a single value. Here we can use the reduce function. As stated earlier, reduce function comes in the functools package. For multiplication, we need two values, x and y. Let’s see how to write it.

That’s all for Anonymous Function.

Design a site like this with WordPress.com
Get started