Post by mtriplett on Dec 16, 2020 18:18:47 GMT
This installment is focused on how you, a bot builder, can actually implement a "Supervised Learning" neural net on a robot. To do this, you need a plan and some data. Most of your work will go there. Once you have a plan and some data, implementing the NN will be the easy part.
Step #1: Pick a good simple use case to learn from, something not too complicated. Something with a limited number of inputs and outputs. Once you understand how to do this, it will be easy to take on bigger problems.
Some options are:
The theme is obviously...making decisions. I will use the first example of using a neural net to decide on drive commands while avoiding obstacles. For my example:
Whatever you decide, I would choose something with less than 6 inputs and less than 6 possible outputs in the beginning. This will reduce the amount of time you need to plan, gather data, the train the models. Once you learn the basics, you can easily move on to more complex models.
A Note on Outputs - "One Hot" vs. Alternatives
Most simple NNs return what is called "One Hot" outputs, where one output is "Hot" and the others are "Cold". Hot=1, Cold=0. This represents mutually exclusive outcomes. This is a great way to start, but NNs will also work where outputs represent any value between 0 and 1 and are not mutually exclusive. While my example will focus on a "One-Hot" design, I could just as easily trained a NN to output 2 throttle values between 0 and 1 for the left and right motors and had the robot performing fluid turns.
Step #2: Decide on the Relevant Inputs & Mapping
What sensors have data that is relevant to what you are trying to do? In my example, we'll use 3 sonars. We could have used all kinds of things, light, temperature, presence of people, encoder data, anything. Typically, you will want or need to map each of these inputs to a range between 0 and 1. On an Arduino or in most any programming language, this mapping can be done with a simple one-line function call.
Step #3: Decide on the Relevant Outputs & Mapping
What are the possible outcomes for your neural net? In my example, I will use a set of 5 basic drive actions...stop, forward, reverse. turn left, turn right. We could have used many more, or we could have used just 2...left and right throttle. I chose the first "one-hot" type with 5 outputs, as this is the most common approach when creating a neural net.
Once you decide on your outcomes, you then need to imagine how you will map your outputs back to your bots behavior. It could just be a "switch" statement to call a function for each output. That is up to you.
Step #4: Build a File that will be used to train your model
For now, I would start by simply creating this in a spreadsheet or CSV file if you don't have a spreadsheet program. You could also use a database table.
I would put column headers at the top with English labels for each input..."Sonar1", "Sonar2", "Sonar3".
After that, I would add more column headers for each possible output..."Stop", "Forward", "Reverse", etc.
I like to add a number to identify each row, and I like to add an "In_" and "Out_" prefix to each input and output heading. These are just conventions I use, as the code I use will automatically map data to and from the neural net as needed.
Step #5: Create your Training Data
Each row will represent a different scenario. You simply need to fill in a 0 or 1 for each input and output.
Note, typically there will only be a single "1" in the outputs for each row, but the neural net itself and the math will work either way. This means in a larger model you could have many outputs that represent multiple choices being made, some mutually exclusive, some not, some with values between 0 and 1.
The result in text could look something like this...
That's it. If you have performed these steps with your use case, congratulations, you are already most of the way to implementing a neural net on your bot!
What would be a reason to do this rather than just write code to do it? Here are a few reasons:
In the next installment, I will talk about how you can write your own code to build the neural net, train the model, and use it to make predictions, or use a third party library to do it for you. I will show to do this with a simple (3 or 4 layer) "fully-connected" network.
Step #1: Pick a good simple use case to learn from, something not too complicated. Something with a limited number of inputs and outputs. Once you understand how to do this, it will be easy to take on bigger problems.
Some options are:
- Deciding How to Move Around a Room
- Deciding on an Emotion
- Deciding on a Motivation
- Deciding When to Talk, Ask a Question, or Shut Up...something my own bots need improvement on!
- Deciding on what Gesture to exhibit
- Deciding Throttle Settings
- Deciding What to Look At
- Deciding on Whether to Be Passive or Autonomous
The theme is obviously...making decisions. I will use the first example of using a neural net to decide on drive commands while avoiding obstacles. For my example:
- Imagine a robot with 3 sonars facing in different directions...facing left of center, center, and right of center.
- Imagine a robot with a drive system that can go forward, stop, and make turns.
Whatever you decide, I would choose something with less than 6 inputs and less than 6 possible outputs in the beginning. This will reduce the amount of time you need to plan, gather data, the train the models. Once you learn the basics, you can easily move on to more complex models.
A Note on Outputs - "One Hot" vs. Alternatives
Most simple NNs return what is called "One Hot" outputs, where one output is "Hot" and the others are "Cold". Hot=1, Cold=0. This represents mutually exclusive outcomes. This is a great way to start, but NNs will also work where outputs represent any value between 0 and 1 and are not mutually exclusive. While my example will focus on a "One-Hot" design, I could just as easily trained a NN to output 2 throttle values between 0 and 1 for the left and right motors and had the robot performing fluid turns.
Step #2: Decide on the Relevant Inputs & Mapping
What sensors have data that is relevant to what you are trying to do? In my example, we'll use 3 sonars. We could have used all kinds of things, light, temperature, presence of people, encoder data, anything. Typically, you will want or need to map each of these inputs to a range between 0 and 1. On an Arduino or in most any programming language, this mapping can be done with a simple one-line function call.
Step #3: Decide on the Relevant Outputs & Mapping
What are the possible outcomes for your neural net? In my example, I will use a set of 5 basic drive actions...stop, forward, reverse. turn left, turn right. We could have used many more, or we could have used just 2...left and right throttle. I chose the first "one-hot" type with 5 outputs, as this is the most common approach when creating a neural net.
Once you decide on your outcomes, you then need to imagine how you will map your outputs back to your bots behavior. It could just be a "switch" statement to call a function for each output. That is up to you.
Step #4: Build a File that will be used to train your model
For now, I would start by simply creating this in a spreadsheet or CSV file if you don't have a spreadsheet program. You could also use a database table.
I would put column headers at the top with English labels for each input..."Sonar1", "Sonar2", "Sonar3".
After that, I would add more column headers for each possible output..."Stop", "Forward", "Reverse", etc.
I like to add a number to identify each row, and I like to add an "In_" and "Out_" prefix to each input and output heading. These are just conventions I use, as the code I use will automatically map data to and from the neural net as needed.
Step #5: Create your Training Data
Each row will represent a different scenario. You simply need to fill in a 0 or 1 for each input and output.
Note, typically there will only be a single "1" in the outputs for each row, but the neural net itself and the math will work either way. This means in a larger model you could have many outputs that represent multiple choices being made, some mutually exclusive, some not, some with values between 0 and 1.
The result in text could look something like this...
Num | In_Sonar1 | In_Sonar2 | In_Sonar3 | Out_Stop | Out_Forward | Out_Left | Out_Right |
1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
2 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
3 | 0 | 1 | 1 | 0 | 0 | 0 | 1 |
4 | 1 | 1 | 0 | 0 | 0 | 1 | 0 |
5 | 0 | 1 | 0 | 0 | 1 | 0 | 0 |
6 | 0 | 0 | 1 | 0 | 0 | 0 | 1 |
7 | 1 | 0 | 0 | 0 | 0 | 1 | 0 |
8 | 1 | 0 | 1 | 0 | 0 | 0 | 1 |
That's it. If you have performed these steps with your use case, congratulations, you are already most of the way to implementing a neural net on your bot!
What would be a reason to do this rather than just write code to do it? Here are a few reasons:
- My example is a very simple one meant to teach some core concepts for getting you started.
Real bots are a lot more complicated than this. If you try to code everything procedurally or otherwise, you can end up writing lots of conditional logic and introducing lots of bugs that take time to fix. With a neural net, you just add additional data when you want to handle new and more specialized circumstances. As bots get more complex, it can become increasingly hard for a human to even comprehend all the behavior and come up with a viable plan to add new behavior. Some builders just give up and move on to another bot. Neural nets can alleviate much of this problem and allow bots to more easily grow over time. - Neural Nets allow builders to share behaviors by simply sharing their training data. Builders can implement this data using other tools and platforms.
- A neural net can find "good enough" answers to situations that have not been anticipated, by generalizing from conditions that are already in the training data. This can make your bot much more adaptable.
- Supervised learning models such as this example are only a starting point. Other more advanced types of models can do things that no programmer could ever hope to code.
- There are other reasons both for and against using Neural Nets, I'll leave it at this level of detail for now.
In the next installment, I will talk about how you can write your own code to build the neural net, train the model, and use it to make predictions, or use a third party library to do it for you. I will show to do this with a simple (3 or 4 layer) "fully-connected" network.