В этом вопросе добрые господа указали на мою ошибку, и программа смогла подогнать кривую. Однако после некоторых экспериментов подобранная кривая оказалась недостаточно точной. Например, при n_e = 1,7899 и V_e = 48, используя предсказанные 6 коэффициентов для восстановления дисперсии, вычисленное n_e составило около 1,8 и V_e > около 33, слишком неточно для оптического моделирования.
Затем я решил попробовать нейронную сеть предсказать 6 коэффициентов.
Для расчета n_e можно использовать 6 коэффициентов, установив лямбду равной 546,07 нм, а V_e можно рассчитать по двум другим длинам волн, используя определение:

Где:
Код: Выделить всё
lambda_e = 0.54607 # e-line (546.07 nm)
lambda_Fp = 0.47999 # F'-line (479.99 nm)
lambda_Cp = 0.64385 # C'-line (643.85 nm)
Код: Выделить всё
def schott_dispersion(A, lam):
A0, A1, A2, A3, A4, A5 = A[:, 0], A[:, 1], A[:, 2], A[:, 3], A[:, 4], A[:, 5]
n_squared = A0 + A1* lam + A2 * lam**(-2) + A3 * lam**(-4) + A4 * lam**(-6) + A5 * lam**(-8)
n_squared = tf.clip_by_value(n_squared, clip_value_min=1e-6, clip_value_max=tf.float32.max)
return tf.sqrt(n_squared)
Код: Выделить всё
def custom_loss(y_true, y_pred):
# Split y_true into x_true (n_e and V_e) and the actual coefficients
n_e_true = y_true[:, 0] # Refractive index n_e
V_e_true = y_true[:, 1] # Abbe number V_e
schott_true = y_true[:, 2:] # True Schott coefficients
# Calculate refractive indices for e, F' and C' lines
n_e_pred = schott_dispersion(y_pred, lambda_e)
n_F_pred = schott_dispersion(y_pred, lambda_Fp)
n_C_pred = schott_dispersion(y_pred, lambda_Cp)
# Calculate predicted Abbe number V_e
epsilon = 1e-6 # Small value to prevent division by zero
V_e_pred = (n_e_pred - 1) / (tf.abs(n_F_pred - n_C_pred) + epsilon)
# Compute the loss
loss_n_e = tf.square(n_e_true - n_e_pred)
loss_V_e = tf.square(V_e_true - V_e_pred)
total_loss = tf.reduce_mean(loss_n_e + loss_V_e)
return total_loss
Код: Выделить всё
def build_model():
model = models.Sequential()
model.add(layers.Dense(64, activation='relu', input_shape=(2,))) # Input: (n_e, V_e)
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(0.1))
model.add(layers.Dense(128, activation='relu', kernel_regularizer=regularizers.l2(0.0001)))
model.add(layers.Dense(6)) # Output: (y1, y2, y3, y4, y5, y6)
return model
scaler_X = StandardScaler()
X_train = input_data.values
y_train = concat.values
X_train_scaled = scaler_X.fit_transform(X_train)
model = build_model()
optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001, clipvalue=1.0)
model.compile(optimizer=optimizer, loss=custom_loss, run_eagerly=True)
lr_scheduler = tf.keras.callbacks.ReduceLROnPlateau(monitor='loss', factor=0.5, patience=5, min_lr=1e-6)
history = model.fit(X_train_scaled, y_train, epochs=100, batch_size=32)
Однако потери колеблются в районе 3000-
Код: Выделить всё
300,000
Приложение
Данные обучения (таблица CSV) ссылка здесь.
Для чтения данных используется следующий код:
Код: Выделить всё
df = pd.read_csv(path)
input_data = df[['n_e', 'V_e']].dropna()
concat = df[['n_e', 'V_e', 'A0', 'A1', 'A2', 'A3', 'A4', 'A5']].dropna()
Это получился такой длинный пост... Благодарю всех за помощь и мнение, даже просто прочитав это.
Подробнее здесь: https://stackoverflow.com/questions/790 ... -high-accu