# Neural networks.
import tensorflow.keras as kr
# Numerical arrays
import numpy as np
# Data frames.
import pandas as pd
# Plotting
import matplotlib.pyplot as plt
# Plot style.
plt.style.use("ggplot")
# Plot size.
plt.rcParams['figure.figsize'] = [14, 8]
# Simple linear equation.
f = lambda x: 3.0 * x + 1.0
# Create a training data frame with x and y values.
# The x values are randomly selected between 0 and 100.
# y_i is f(x_i)
train = pd.DataFrame()
train['x'] = np.random.uniform(0.0, 100.0, 1000)
train['y'] = f(train['x'])
train
# Create a corresponding test data frame.
# It might be better to create one big data frame and randomly select test cases.
test = pd.DataFrame()
test['x'] = np.random.uniform(0.0, 100.0, 100)
test['y'] = f(test['x'])
test
# Create a neural network with one neuron.
model = kr.models.Sequential()
model.add(kr.layers.Dense(1, input_shape=(1,), activation="linear", kernel_initializer='ones', bias_initializer='zeros'))
model.compile('adam', loss='mean_squared_error')
# Train the neural network on our training data.
model.fit(train['x'], train['y'], epochs=500)
# Take four hand-picked values and see their predictions.
model.predict([1.0,2.0,3.0,100.0])
# See what f says they are.
np.array([[f(i)] for i in [1.0, 2.0, 3.0, 100.0]])
# Let's plot our predictions of the x values we trained on
plt.plot(test['x'], test['y'], label='actual')
plt.plot(test['x'], model.predict(test['x']), label='prediction')
plt.legend();
# Evaluate the neural network on the test data.
model.evaluate(test['x'], test['y'])
# Let's set f to a polynomial instead.
f = lambda x: 2.0 * x**2 + 3.0 * x + 4.0
poly = pd.DataFrame()
poly['x'] = np.linspace(-10.0, 10.0, 1000)
poly['y'] = poly['x'].apply(f)
# Have a look.
plt.plot(poly['x'], poly['y']);
# Re-build our model.
model = kr.models.Sequential()
model.add(kr.layers.Dense(1, input_shape=(1,), activation='linear', kernel_initializer="ones", bias_initializer="zeros"))
model.compile('adam', loss='mean_squared_error')
# Fit the data.
model.fit(poly['x'], poly['y'], epochs=500)
# Plot the predictions (on the training set itself).
plt.plot(poly['x'], poly['y'], label='actual')
plt.plot(poly['x'], model.predict(poly['x']), label='prediction')
plt.legend();
# Change the activation function.
model = kr.models.Sequential()
model.add(kr.layers.Dense(1, input_shape=(1,), activation='sigmoid', kernel_initializer="ones", bias_initializer="zeros"))
model.compile('adam', loss='mean_squared_error')
# Without training, let's have a look at the output.
sigdata = pd.DataFrame()
sigdata['x'] = np.linspace(-10.0, 10.0, 1000)
sigdata['y'] = model.predict(sigdata['x'])
# Let's see what that looks like.
plt.plot(sigdata['x'], sigdata['y']);
# Same polynomial.
f = lambda x: 2.0 * x**2 + 3.0 * x + 4.0
poly = pd.DataFrame()
poly['x'] = np.linspace(-10.0, 10.0, 1000)
poly['y'] = poly['x'].apply(f)
# Train a different model.
model = kr.models.Sequential()
model.add(kr.layers.Dense(50, input_shape=(1,), activation='sigmoid', kernel_initializer="glorot_uniform", bias_initializer="glorot_uniform"))
model.add(kr.layers.Dense(1, activation='linear', kernel_initializer="glorot_uniform", bias_initializer="glorot_uniform"))
model.compile(kr.optimizers.Adam(lr=0.001), loss='mean_squared_error')
# Fit the data.
model.fit(poly['x'], poly['y'], epochs=500, batch_size=10)
# Now let's see.
plt.plot(poly['x'], poly['y'], label='actual')
plt.plot(poly['x'], model.predict(poly['x']), label='prediction')
plt.legend();
Note that re-running the fitting code will generally give different results.