From 1eab34dbe3832d4254fb100cd6940d7b5a76e40b Mon Sep 17 00:00:00 2001 From: armantovmasyan Date: Fri, 19 Jan 2024 16:08:58 +0300 Subject: [PATCH] fix: functions.py fix based on given feedback --- functions.py | 85 ++++++++++++++++++++-------------------------------- main.py | 69 ++++++++++++++++++++++++++++-------------- 2 files changed, 79 insertions(+), 75 deletions(-) diff --git a/functions.py b/functions.py index fb374b9..ba104d2 100644 --- a/functions.py +++ b/functions.py @@ -4,40 +4,37 @@ Also model creation and training. """ -from numbers import Real from scipy.integrate import odeint import numpy as np import matplotlib.pyplot as plt from tensorflow.keras.layers import Dense, Input, Concatenate from tensorflow.keras.models import Model +from tensorflow.keras.optimizers import Adam -def system(y: Real, a: Real, b: Real, c: Real, d: Real) -> list[Real]: - """Definition of a system of differential equations""" +# Определение системы дифференциальных уравнений +def system(y, t, a, b, c, d): y1, y2 = y dy1_dt = a * y1 + b * y2 dy2_dt = c * y1 + d * y2 return [dy1_dt, dy2_dt] -def calculate_mse(y_true: Real, y_pred: Real) -> Real: - """Function for calculating MSE""" +# Функция для расчета MSE +def calculate_mse(y_true, y_pred): return np.mean((y_true - y_pred) ** 2) -def build_neural_ode_model_system() -> Model: - """Definition of the NeuralODE model for the system of equations""" +# Определение модели NeuralODE для системы уравнений +def build_neural_ode_model_system(): input_y = Input(shape=(2,)) input_t = Input(shape=(1,)) combined_input = Concatenate()([input_y, input_t]) x = Dense(units=64, activation='relu')(combined_input) x = Dense(units=64, activation='relu')(x) x = Dense(units=64, activation='relu')(x) - output_a = Dense(units=1, name='output_a')(x) - output_b = Dense(units=1, name='output_b')(x) - output_c = Dense(units=1, name='output_c')(x) - output_d = Dense(units=1, name='output_d')(x) - model = Model(inputs=[input_y, input_t], outputs=[output_a, output_b, output_c, output_d]) + output_dy = Dense(units=2)(x) # Предсказание производных dy1_dt и dy2_dt + model = Model(inputs=[input_y, input_t], outputs=output_dy) return model @@ -45,75 +42,59 @@ def build_neural_ode_model_system() -> Model: neural_ode_model_system.compile(optimizer='adam', loss='mse') -def conduct_experiment(a: Real, b: Real, c: Real, d: Real, experiment_id: int) -> None: - """Function for a single experiment""" - # Initial conditions for all experiments +# Функция для проведения одного эксперимента +def conduct_experiment(a, b, c, d, experiment_id, time_points): + # Начальные условия для всех экспериментов y0 = [1.0, 2.0] - time_points = np.linspace(0, 5, 100) - # Solving the system of equations and adding noise to the data + # Решение системы уравнений и добавление шума к данным solution = odeint(system, y0, time_points, args=(a, b, c, d)) noise = np.random.normal(0, 0.5, solution.shape) noisy_data = solution + noise - # Preparing data for training - x_train = [noisy_data, time_points.reshape(-1, 1)] - y_train = [np.full((len(time_points), 1), a), - np.full((len(time_points), 1), b), - np.full((len(time_points), 1), c), - np.full((len(time_points), 1), d)] + # Подготовка данных для обучения + X_train = [noisy_data, time_points.reshape(-1, 1)] + y_train = solution - # Model training - neural_ode_model_system.fit(x_train, y_train, epochs=200, verbose=1) + # Обучение модели + neural_ode_model_system.fit(X_train, y_train, epochs=200, verbose=1) - # Prediction of parameters - predicted_params = neural_ode_model_system.predict(x_train) + # Предсказание производных + predicted_derivatives = neural_ode_model_system.predict(X_train) - # Predicted parameters - predicted_a, predicted_b, predicted_c, predicted_d = [p.flatten()[0] for p in predicted_params] - - # Results output + # Вывод результатов print(f"Эксперимент {experiment_id}:") print("Истинные параметры:", [a, b, c, d]) - print("Предсказанные параметры (с шумом):", [predicted_a, predicted_b, predicted_c, predicted_d]) - - # Prediction of parameters based on true data (without noise) - predicted_params_clean = neural_ode_model_system.predict([solution, time_points.reshape(-1, 1)]) - predicted_a_clean, predicted_b_clean, predicted_c_clean, predicted_d_clean = [p.flatten()[0] for p in - predicted_params_clean] - print("Предсказанные параметры (без шума):", - [predicted_a_clean, predicted_b_clean, predicted_c_clean, predicted_d_clean]) - - # Creating a predicted solution based on the predicted parameters - predicted_solution = odeint(system, y0, time_points, args=(predicted_a, predicted_b, predicted_c, predicted_d)) - - # MSE calculation for predicted parameters - mse = calculate_mse(solution, predicted_solution) - print("MSE:", mse) - # Visualization of results + # Визуализация plt.figure(figsize=(10, 8)) - # Subgraph for y1 + # Подграфик для y1 plt.subplot(2, 1, 1) plt.scatter(time_points, noisy_data[:, 0], label='Симулированные данные y1 с шумом', color='blue') plt.scatter(time_points, solution[:, 0], label='Входные данные y1', color='orange') - plt.plot(time_points, predicted_solution[:, 0], label='Оптимизированные данные y1', color='red') plt.plot(time_points, solution[:, 0], label='Истинные данные y1', color='green') + plt.plot(time_points, predicted_derivatives[:, 0], label='Предсказанные данные y1', color='red') plt.xlabel('Время') plt.ylabel('y1') plt.title(f"Результаты эксперимента {experiment_id} для y1") plt.legend() - # Subgraph for y2 + # Подграфик для y2 plt.subplot(2, 1, 2) plt.scatter(time_points, noisy_data[:, 1], label='Симулированные данные y2 с шумом', color='blue') plt.scatter(time_points, solution[:, 1], label='Входные данные y2', color='orange') - plt.plot(time_points, predicted_solution[:, 1], label='Оптимизированные данные y2', color='red') - plt.plot(time_points, solution[:, 1], label='Истинные данные y2', color='blue') + plt.plot(time_points, solution[:, 1], label='Истинные данные y2', color='green') + plt.plot(time_points, predicted_derivatives[:, 1], label='Предсказанные данные y2', color='red') plt.xlabel('Время') plt.ylabel('y2') plt.title(f"Результаты эксперимента {experiment_id} для y2") plt.legend() plt.tight_layout() plt.show() + + # Расчёт MSE для предсказанных производных + mse = calculate_mse(solution, predicted_derivatives) + print("MSE:", mse) + + return solution, predicted_derivatives, mse diff --git a/main.py b/main.py index fdf6864..54c4c68 100644 --- a/main.py +++ b/main.py @@ -3,29 +3,52 @@ Execution of the whole program should be done from here. """ +import numpy as np +import matplotlib.pyplot as plt from functions import conduct_experiment +# Параметры экспериментов +experiment_params = [ + (-2, 1, 3, -4), # Эксперимент 1 + (-1, 2, -3, 4), # Эксперимент 2 + (0.5, -1.5, 2, -2.5), # Эксперимент 3 + (1, -1, 1.5, -1.5), # Эксперимент 4 + (-2.5, 2.5, -0.5, 0.5), # Эксперимент 5 + (2, -2, 3, -3), # Эксперимент 6 + (-1.5, 1, 2.5, -2), # Эксперимент 7 + (1.5, -1, -2, 2), # Эксперимент 8 + (-3, 3, -1, 1), # Эксперимент 9 + (2.5, -2.5, 0.5, -0.5) # Эксперимент 10 +] -def main(): - """Main function""" - # Experimental parameters - experiment_params = [ - (-2, 1, 3, -4), # Experiment 1 - (-1, 2, -3, 4), # Experiment 2 - (0.5, -1.5, 2, -2.5), # Experiment 3 - (1, -1, 1.5, -1.5), # Experiment 4 - (-2.5, 2.5, -0.5, 0.5), # Experiment 5 - (2, -2, 3, -3), # Experiment 6 - (-1.5, 1, 2.5, -2), # Experiment 7 - (1.5, -1, -2, 2), # Experiment 8 - (-3, 3, -1, 1), # Experiment 9 - (2.5, -2.5, 0.5, -0.5) # Experiment 10 - ] - - # Running experiments - for i, params in enumerate(experiment_params, start=1): - conduct_experiment(*params, experiment_id=i) - - -if __name__ == '__main__': - main() +time_points = np.linspace(0, 5, 100) + +# Переменные для хранения результатов +solutions = [] +predicted_solutions = [] +mse_values = [] +max_derivatives = [] + +for i, params in enumerate(experiment_params, start=1): + solution, predicted_solution, mse = conduct_experiment(*params, experiment_id=i, time_points=time_points) + + # Добавление результатов в массивы + mse_values.append(mse) + + # Вычисление максимального значения производной для текущего решения + dy1_dt = np.gradient(solution[:, 0], time_points) + dy2_dt = np.gradient(solution[:, 1], time_points) + max_derivative = max(np.max(np.abs(dy1_dt)), np.max(np.abs(dy2_dt))) + max_derivatives.append(max_derivative) + +print("Длина max_derivatives:", len(max_derivatives)) +print("Длина mse_values:", len(mse_values)) + +# Визуализация зависимости погрешности от максимального значения производной +plt.figure(figsize=(10, 6)) +plt.scatter(max_derivatives, mse_values, color='blue') +plt.xlabel('Максимальное значение производной') +plt.ylabel('MSE') +plt.title('Зависимость MSE от максимума производной на отрезке') +plt.grid(True) +plt.show()