What does it mean to understand a physics equation? More specifically, students learn to understand physics equations in terms of a vocabulary of elements that are called symbolic forms. Each symbolic form associates a simple conceptual schema with a pattern of symbols in an equation.
How do physicists (and physics students) take a conceptual understanding of some physical situation and express that idea in an equation? In what conceptual terms are physics equations understood? It is possible that the understanding of physics equations is of a limited sort. For example, consider the equation
In what sense is this equation understood by people with some physics expertise? One possibility is that an understanding of this equation, even for an expert physicist, does not extend beyond knowing the conditions under which the equation can be used and how it can be used.
IntroductionMachine Learning is becoming powerful day by day from powering and modeling nuclear reactions to biomolecule synthesis, which has paved a new dimension for future generations to come. But with advancements, there is a great deal of complexity. The knowledge and equations are flourishing at such a pace that elementary learning cannot cope. Demystifying laws and equations no longer seem to be worth toil since complexity is great and school teachings, are pretty much outdated and no training on sophisticated simulation programming leaves the only option for young physicists to blindly follow the equations without many experimental validations.
Through this project, we aim to show how a no-code machine learning platform can help budding scientists predict the result of certain phenomena and in some cases even reveal the underlying laws themselves.
Let's beginWe will take a look at a fairly simple example: the force of gravity on a falling object. If you took an introductory physics or calculus class you will have seen the formula. But even if you have only taken high school algebra you can handle the math behind it. The formula for the location of a falling object is:
Where:
X₀ = the initial location of the object, i.e. its initial height.
V₀ = the initial velocity (or speed) of the object when it is at this initial position.
t = time after the object was dropped.
g = the force of gravity, which is an acceleration of approximately 9.8 meters/second².
The most remarkable and unexpected fact about falling objects is that, if air resistance and friction are negligible, then in a given location all objects fall toward the centre of Earth with the same constant acceleration, independent of their mass. This experimentally determined fact is unexpected because we are so accustomed to the effects of air resistance and friction that we expect light objects to fall slower than heavy ones.
In order to proceed, we need some data. We could drop a number of different objects 10, 000 times and record their locations at different times, but that is pretty time-consuming. Instead, we will create our dataset from the above example equation. Fortunately, due to the work of Isaac Newton and experiments repeated over hundreds of years, we can be certain that our data will mirror what happens in the real world.
First, we will create a Python function to calculate the location of a falling object:
# location of falling objectis given by eq, y = Xo + Vot - 1/2*g*t^2
def location(x_0, v_0, t):
return x_0 + v_0*t - (9.8/2)*t**2
Next, we use this function to create a dataset and save it in a CSV file:
random.seed
with open('gravity_location_data.csv', mode='w', newline='') as gravity_file:
gravity_writer = csv.writer(gravity_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
gravity_writer.writerow(['initial_position', 'initial_velocity', 'mass', 'time', 'location'])
for i in range (0, 10000):
initial_position = random.randrange(1, 10000)
initial_velocity = random.randrange(1, 100)
mass = random.randrange(1, 1000)
time = random.randrange(1, 100)
gravity_writer.writerow([initial_position, initial_velocity, mass, time, location(initial_position, initial_velocity, time)])
What we are doing here is creating 10, 000 examples, using randomized values for all of our variables, and then calculating the location at a certain (randomly selected) time.
Aristotle VS GalileoAristotle says that the heavier things are, the quicker they will fall, whereas Galileo felt that the mass of an object made no difference to the speed at which it fell.
If you see the dataset which we created, we included the mass of the object as well. That is entirely irrelevant from Galileo's point of view but if you think deeper you will understand that our dataset was calculated based upon an existingformula that has been approved and challenged many times, but in real-world physicists don't come up with a fancy equation, formula or law first, they perform rigorous experimentation before coming to conclusion.
Look at the original equation. Mass is nowhere to be found. So why include mass in this data set? Because we want to try to trick the machine learning algorithm into using it! We will see whether our machine learning experiment can understand the underlying variable relationship better or not.
Step 2: Model TrainingUsing Neuton.ai no-code tool saves you from installing tens of machine-learning packages and processing datasets. Using the Neuton Ai platform you don't need to come up with your own algorithm, the training agent is smart enough to understand the dataset.
Add a new solution,
Upload the dataset which we created in the previous step and choose a target variable (in our case it is the location column)
Set the training feature as follows, Task Type -> Regression. Select TinyML so that we can deploy this model on any kind of device (can be useful to demonstrate how physics and students can take advantage of it in small embedded experiment equipment)
Proceed by clicking on the Start Training button. Once the training is complete, we can go to Metrics and Analytics tools.
Note that the r² value is 0.999744! Also, the root mean squared error (RMSE) and mean absolute error (MAE) are tiny — need to multiply the preceding number by e-09 [ 0.000000001 * 213.191494 ]. So the root mean squared error is actually at this scale that is minuscule (0.000000213191494), essentially zero.
Let's have a look at the data analysis,
Now here comes the most exciting part for which we started exploring Machine Learning for understanding physics equations and behaviors. It is called Feature Importance Matrix. See below,
If you see the feature importance matrix, there are very interesting final points to be made here. First, the resulting model found the mass to be irrelevant to making the prediction, which is correct, the mass has a negligible role in determining or predicting location according to the equation we started with. Secondly, we didn't need any knowledge of complex calculus here to understand the important relationships between the variables of the equation.
Step 3: Model DeploymentDownload the C library for the generated model to embed on our device.
This step is going to be interesting for all :) Practically Neuton TinyML model can be deployed on any device or baremetal hardware with a very small memory footprint. In this case, the Model Size is 0.95 KB and the File Size for Embedding is 1.078 KB. Which is lesser than ~1 KB. I decided to run this on my old Sony PSP 3000 which I had treasured since 2010.
The device has good and powerful FPU, vFPU and CPU, and 64 MB RAM. The device runs a custom OS. The device is very powerful as compared to MCUs but the real aim is to show how easily Neuton TinyML models can be deployed anywhere and across all industries.
I chose PSP as a target for my Neuton TinyML model because:
- Sony PSP runs a game engine and with machine learning, hackers can add ML capabilities to their games without wasting memory.
- It has been discontinued but can be used to make graphic simulations using machine learning and is helpful for learning game console essentials.
Settingup SDK and toolchain:
Download the PSP SDK from this website, https://darksectordds.github.io/html/MinimalistPSPSDK/index.html. Install and add its bin folder to Windows Environment Variables -> System Variable -> Path
C:\pspsdk\bin
Install Visual Studio and install essential, C/C++ toolchains.
Once everything is ready, you can write apps for your Sony PSP using VSCode. Firstly, we will configure Makefile for our target device:
TARGET = hello_tinyml
OBJS = main.o ../common/callback.o normalize/normalize.o neuton.o gfx.o
INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS = $(CFLAGS)
LIBDIR =
LIBS = -lm -lpspfpu -lpspgum -lpspgu
LDFLAGS =
# PSP SDK
BUILD_PRX = 1
PSP_FW_VERSION = 500
PSP_LARGE_MEMORY = 1
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = HelloTinyML
PSP_EBOOT_ICON = NEUTON_ICON.PNG
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
We need to extract the Neuton Model file we downloaded into our PSP project directory. It should look something similar,
| main.c
│ Makefile
│ neuton.c
│ neuton.h
│ NEUTON_ICON.PNG
│
├───model
│ model.h
│
└───normalize
normalize.c
normalize.h
We are going to use Neuton callbacks to check if our model loaded correctly or not,
int main(int argc, char *argv[])
{
// basic init
setupExitCallback();
pspDebugScreenInit();
pspDebugScreenClear();
printf("Loading Neuton model.... \r\n\n");
printf("Model size: %d bytes\r\n", neuton_model_size());
printf("Model RAM usage: %d bytes\r\n", neuton_model_ram_usage());
printf("Model neurons count: %d \r\n", neuton_model_neurons_count());
printf("Model weights count: %d \r\n", neuton_model_weights_count());
printf("Model quantization level: %d \r\n", neuton_model_quantization_level());
printf("Model float calculations: %s \r\n", neuton_model_float_calculations() == 1 ? "yes" : "no");
printf("Model task type: %s \r\n", neuton_model_task_type() == 2 ? "regression" : "classification");
Once the model is ready we are going to feed input in sequence as we provided in the training dataset and run inference,
// while this program is alive
while (isRunning())
{
// delay 5 seconds
sceKernelDelayThread(5000000);
pspDebugScreenClear();
printf("Model RAM usage: %d bytes\r\n", neuton_model_ram_usage());
printf("\n");
// generate random number between 1 - 100
initial_position = rand() % 50000 + 1; // random distance from 1 - 50,000 meters
initial_velocity = rand() % 50 + 1; // random velocity between 1 - 50 m/s
mass = rand() % 1000 + 1; // random mass between 1 - 1000 kg
time = rand() % 100 + 1; // random time between 1 - 100 seconds
input_t inputs[] = {(float) initial_position, (float) initial_velocity, (float) mass, (float) time};
if (neuton_model_set_inputs(inputs) == 0)
{
uint16_t index;
float *outputs;
if (neuton_model_run_inference(&index, &outputs) == 0)
{
// code for handling prediction result
printf("Initial position: %d meters\r\n", initial_position);
printf("Initial velocity: %d m/s\r\n", initial_velocity);
printf("Mass: %d kg\r\n", mass);
printf("Time: %d seconds\r\n", time);
printf("\n");
printf("Prediction result: %f meters\r\n", outputs[0]);
printf("\n");
}
}
// screen refresh
sceDisplayWaitVblankStart();
}
// exit
sceKernelExitGame();
return 0;
}
Run make command on theterminal to compile the program to EBOOT.PBP format and export it to a PSP device.
PS C:\pspsdk\projects\Hello> make
psp-gcc -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=500 -c -o main.o main.c
psp-gcc -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=500 -c -o normalize/normalize.o normalize/normalize.c
psp-gcc -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=500 -c -o neuton.o neuton.c
psp-gcc -I. -IC:/pspsdk/psp/sdk/include -O2 -G0 -Wall -D_PSP_FW_VERSION=500 -L. -LC:/pspsdk/psp/sdk/lib -specs=C:/pspsdk/psp/sdk/lib/prxspecs -Wl,-q,-TC:/pspsdk/psp/sdk/lib/linkfile.prx main.o ../common/callback.o normalize/normalize.o neuton.o C:/pspsdk/psp/sdk/lib/prxexports.o -lm -lpspfpu -lpspgum -lpspgu -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o hello_tinyml.elf
psp-fixup-imports hello_tinyml.elf
psp-prxgen hello_tinyml.elf hello_tinyml.prx
mksfoex -d MEMSIZE=1 'HelloTinyML' PARAM.SFO
pack-pbp EBOOT.PBP PARAM.SFO NEUTON_ICON.PNG \
NULL NULL NULL \
NULL hello_tinyml.prx NULL
[0] 316 bytes | PARAM.SFO
[1] 12336 bytes | NEUTON_ICON.PNG
[2] 0 bytes | NULL
[3] 0 bytes | NULL
[4] 0 bytes | NULL
[5] 0 bytes | NULL
[6] 76538 bytes | hello_tinyml.prx
[7] 0 bytes | NULL
Final ResultsHurray! It all went smoothly. Check the results. It would have been even better if we could use the location prediction to simulate 2D objects using PSP vector operations, but that's sure for next time.
This project gives us a glimpse of how insights into fundamental laws of the universe can be extracted from data. With just three steps students, physicists, and teachers can understand the equations and experimental laws better. In fact, this is proof that tinyML models can find a great way in game design, quality education, and research. The game console programmers can take great advantage of machine learning to simulate models rather than spend time building algorithms for body motions.
Comments
Please log in or sign up to comment.