# Using Machine Learning to Interpolate Values

--

Machine learning is bursting with potential applications, but one important (and simple!) usage is using a machine learning algorithm for interpolation. In this post, I will demonstrate how a simple neural network can be used to interpolate on 1D or 2D grids. This is of particular interest for me in interpolating large vectors on a 2D spatial grid.

1-D interpolation asks the simple question of given an x value predict a y value. Since neural networks are thought of as universal function estimators, they should be well suited to this type of problem (spoiler — they are). Let’s check out how this looks in practice.

But first! Let’s do some imports. We are going to be using keras’ Sequential model for the neural network, numpy for creating our data, matplotlib for visualizing our results, and sklearn for splitting our data into training and testing sets.

`from keras.models import Sequential`

from keras.layers import Dense

import numpy as np

import matplotlib.pyplot as plt

import sklearn.model_selection as skm

Let’s make a simple sine wave with a little bit of random noise.

`# Define 1D function we want to learn`

def function1d(x):

return np.sin(2*np.pi*x)

# Create sample

x = np.random.random_sample(1000)

y = function1d(x) + np.random.normal(0, .1, 1000)

# Plot

plt.scatter(x,y, label='Generated Data')

plt.plot(np.linspace(0,1,100), function1d(np.linspace(0,1,100)), label='Real Sine Function', color='r', linestyle='--', linewidth=3)

plt.xlabel('X value')

plt.ylabel('Y value')

plt.title("Randomly Sampled Sine Function")

And let’s go ahead and make a really simple neural network with two hidden layers and only 100

`### Model creation: adding layers and compilation`

model = Sequential()

model.add(Dense(100, input_dim=1, activation='relu'))

model.add(Dense(100, activation='relu'))

model.add(Dense(1, activation='linear'))

model.compile(optimizer='adam', loss='mse', metrics=['mse'])

We will also do the standard data split (i.e. 80% for training and 20% for testing).

`X_train, X_test, y_train, y_test = skm.train_test_split(x, y, test_size=0.2)`

plt.scatter(X_train, y_train, label='training data')

plt.scatter(X_test, y_test, label='test data')

plt.legend()

plt.xlabel('X value')

plt.ylabel('Y value')

plt.title("Randomly Sampled Sine Function")

Now we are going to train our neural network using some standard parameters.

`history = model.fit(X_train, y_train, epochs=20, batch_size=4)`

With the trained model, we can now predict values for our test set. Let’s take a look at how these line up with the actual model.

`y_pred = model.predict(X_test)`

plt.scatter(X_train, y_train, label='Training Data')

plt.scatter(X_test, y_pred, label='Model Predictions')

plt.plot(np.linspace(0,1,100), function1d(np.linspace(0,1,100)), label='Real Sine Function', color='r', linestyle='--', linewidth=3)

plt.legend()

plt.xlabel('X value')

plt.ylabel('Y value')

plt.title("Randomly Sampled Sine Function")

And voila! We can see that even a really simple neural network does a great job at this interpolation problem with noisy data.

Let’s check out the 2D case. First, we need to start by making our dataset.

`# Define 2D function we want to learn`

def function2d(x, y):

return (x+y)*np.exp(-5.0*(x**2+y**2))

# Create sample

x = 2*np.random.random_sample(2000) - 1

y = 2*np.random.random_sample(2000) - 1

z = function2d(x, y)

# Plot

plt.scatter(x,y, c=z)

plt.xlabel('X value')

plt.ylabel('Y value')

plt.title("Randomly Sampled 2D Function")

plt.colorbar()

So here we want to take our x and y value pairs (x,y) as input and predict the z-value (i.e. the color). Let’s start by splitting up our data.

`X_train, X_test, y_train, y_test = skm.train_test_split(np.column_stack((x, y)), z, test_size=0.2)`

# Plot

plt.scatter(X_train[:,0], X_train[:,1], c=y_train)

plt.xlabel('X value')

plt.ylabel('Y value')

plt.title("Training Set")

plt.colorbar()

Now we can build our neural network by just changing the input to take two vakues instead of one.

`### Model creation: adding layers and compilation`

model2D = Sequential()

model2D.add(Dense(100, input_shape=(None, 2), activation='relu'))

model2D.add(Dense(100, activation='relu'))

model2D.add(Dense(1, activation='linear'))

model2D.compile(optimizer='adam', loss='mse', metrics=['mse'])

And let’s go ahead and fit our network and see how the output looks.

`history = model2D.fit(X_train, y_train, epochs=20, batch_size=4)`

z_pred = model2D.predict(X_test)

plt.scatter(X_test[:,0], X_test[:,1], c=z_pred)

plt.xlabel('X value')

plt.ylabel('Y value')

plt.title("Predicted Set")

plt.colorbar()

Alright so it looks promising. Let’s plot this and our training data to see if it all looks OK.

`plt.scatter(X_train[:,0], X_train[:,1], c=y_train)`

plt.scatter(X_test[:,0], X_test[:,1], c=z_pred)

plt.xlabel('X value')

plt.ylabel('Y value')

plt.title("All Data")

plt.colorbar()

And everything checks out!

So in this short article I’ve shown you how a neural network can be used for 1D or 2D interpolation!

You can find the full notebook here:

https://github.com/crhea93/Medium/blob/master/MachineLearning/BasicInterpolation.ipynb