- #1
docnet
Gold Member
- 799
- 486
- TL;DR Summary
- I coded a neural network model to predict solutions to ##u''(x)=100\sin(5x)## over ##[-1,1]## using Tensorflow. The boundary conditions at ##x=-1## and ##x=1## uniquely determine the solutions. I'm using a very basic model architecture with the relu activation function.
To train the model, I generated a set of deterministic solutions with random boundary conditions ##u(-1)=a## and ##u(1)=b##. I then added a small amount of noise to these solutions. However, the model's accuracy is significantly worse compared to the most basic finite difference methods. Is there anything that I did wrong in the code below? Thanks in advance for your input regarding the model, suggestions to make the project more interesting, etc.
Can someone with more experience provide guidance on improving this project? Additionally, does anyone have ideas to make this project more interesting?
Can someone with more experience provide guidance on improving this project? Additionally, does anyone have ideas to make this project more interesting?
Python:
# data generation function
def generate_data(num_samples):
'''generates boundary conditions and solution points'''
boundary_conditions = np.random.uniform(-1, 1, size=(num_samples, 2))
x = np.linspace(-1,1,100)
# loop for the output
solution_points = []
for row in boundary_conditions:
a, b = row
# determine coefficients
c_1 = 4* np.sin(5) - (a/2) + (b/2)
c_2 = a/2 + b/2
# define solution
u = lambda x: -4 * np.sin(5* x) + c_1*x + c_2
output = u(x)
solution_points.append(output)
return boundary_conditions, np.array(solution_points)
Code:
# Add noise function
def add_noise(data, noise_level=0.1):
noise = np.random.normal(-noise_level, noise_level, data.shape)
return data + noise
# Generate base data
X, y = generate_data(100000)
# Split data into training and validation sets
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)
# Add noise to the training data
noise_level = 0.1
X_train_noisy = add_noise(X_train, noise_level)
y_train_noisy = add_noise(y_train, noise_level)
print("X_train_noisy shape:", X_train_noisy.shape) # (800, 2)
print("y_train_noisy shape:", y_train_noisy.shape) # (800, 100)
print("X_val shape:", X_val.shape) # (200, 2)
print("y_val shape:", y_val.shape) # (200, 100)
'''
print("X_train_shape:", X_train.shape) # (800, 2)
print("y_train shape:", y_train.shape) # (800, 100)
print("X_val shape:", X_val.shape) # (200, 2)
print("y_val shape:", y_val.shape) # (200, 100)'''
# Define the model
model = Sequential([
Dense(64, activation='relu', input_shape=(2,)), # Input layer with 2 neurons
Dense(128, activation='relu'), # Hidden layer with 128 neurons
Dense(256, activation='relu'), # Hidden layer with 256 neurons
Dense(128, activation='relu'), # Hidden layer with 128 neurons
Dense(100) # Output layer with 100 neurons
])
# Compile the model
model.compile(optimizer='adam', loss='mse')
# Set up early stopping
early_stopping = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)
# Train the model with noisy training data and clean validation data
history = model.fit(X_train_noisy, y_train_noisy, epochs=50, batch_size=32, validation_data=(X_val, y_val), callbacks = [early_stopping])
'''
# Train the model with clean training data and clean validation data
history = model.fit(X_train, y_train, epochs=50, batch_size=32, validation_data=(X_val, y_val))'''
# Evaluate the model on the validation set
val_loss = model.evaluate(X_val, y_val)
print(f"Validation loss: {val_loss}")
Code:
# Example prediction
a = .5
b = -.5
boundary_conditions_test = np.array([[a, b]]) # Example test boundary conditions
predicted_solution = model.predict(boundary_conditions_test)
#test the prediction
# determine coefficients
c_1 = 4* np.sin(5) - (a/2) + (b/2)
c_2 = a/2 + b/2
u = lambda x: -4 * np.sin(5* x) + c_1*x + c_2
x = np.linspace(-1,1,100)
error2 = np.linalg.norm(u(x)-predicted_solution[0],ord = 2)
error = np.linalg.norm(u(x)-predicted_solution[0],ord = np.infty)
# plot the prediction
fig = plt.figure(figsize=(12,7))
axes = fig.add_subplot(1, 1, 1)
axes.plot(x, u(x), 'k',label="u_true", markersize = '5')
axes.plot(x, predicted_solution[0], 'bo',label="Predicttion".format(error), markersize = '5')
plt.plot([], [], ' ', label= 'global Error={}'.format(error2))
plt.plot([], [], ' ', label='max error = {}'.format(error))
axes.set_xlabel("$x$", fontsize= 20)
axes.set_ylabel("$u(x)$", fontsize= 20)
axes.grid(True)
fig.patch.set_facecolor('xkcd:sky')
axes.set_facecolor("xkcd:very light blue")
axes.set_title(label = "u(x)", fontsize = 20)
plt.legend(fontsize = 13)
plt.show()