训练神经网络学习多项式方程
Training a neural network to learn polynomial equation
我创建了y~x**2的数据集
然而,当我训练神经网络时,它就是无法拟合二次方程。
这是我的模型。
model2 = tf.keras.models.Sequential(
[tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(1)]
)
loss = tf.keras.losses.mse
optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)
model2.compile(optimizer=optimizer, loss=loss, metrics=tf.metrics.RootMeanSquaredError())
model2.fit(tf.expand_dims(X_train, -1), y_train, epochs=1000, verbose=1)
我对上述模型的思考过程是,我认为每个relu
激活会拟合一条局部线性线,慢慢地把所有的神经元连接起来形成一条二次线。
最后,我通过在输出层上使用 lambda x:x**2
的激活来设法拟合它,但是,那是因为我知道函数是 x**2。
所以我的问题是,在不知道真实函数的情况下,如何训练神经网络来拟合非线性曲线?
你的代码对我来说工作正常。
注意,我使用了更大的学习率和提前停止(总共 2000 个 epoch 中有 300 个耐心)。
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
train_x = np.linspace(0, 80, 160)
train_y = train_x**2
test_x = np.linspace(80, 100, 40)
test_y = test_x**2
model2 = tf.keras.models.Sequential(
[tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(1)]
)
loss = tf.keras.losses.mse
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-2)
early_stop = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=300, restore_best_weights=True)
model2.compile(optimizer=optimizer, loss=loss, metrics=tf.metrics.RootMeanSquaredError())
model2.fit(tf.expand_dims(train_x, -1), train_y, epochs=2000, verbose=1, callbacks=[early_stop])
train_pred = model2.predict(train_x)
test_pred = model2.predict(test_x)
plt.scatter(train_x, train_y, c='blue', label='train x')
plt.scatter(test_x, test_y, c='green', label='test x')
plt.scatter(train_x, train_pred, c='red', label='train pred')
plt.scatter(test_x, test_pred, c='orange', label='test pred')
plt.legend()
plt.show()
Training and test results photo here
我创建了y~x**2的数据集
然而,当我训练神经网络时,它就是无法拟合二次方程。
这是我的模型。
model2 = tf.keras.models.Sequential(
[tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(1)]
)
loss = tf.keras.losses.mse
optimizer = tf.keras.optimizers.Adam(learning_rate=0.0001)
model2.compile(optimizer=optimizer, loss=loss, metrics=tf.metrics.RootMeanSquaredError())
model2.fit(tf.expand_dims(X_train, -1), y_train, epochs=1000, verbose=1)
我对上述模型的思考过程是,我认为每个relu
激活会拟合一条局部线性线,慢慢地把所有的神经元连接起来形成一条二次线。
最后,我通过在输出层上使用 lambda x:x**2
的激活来设法拟合它,但是,那是因为我知道函数是 x**2。
所以我的问题是,在不知道真实函数的情况下,如何训练神经网络来拟合非线性曲线?
你的代码对我来说工作正常。
注意,我使用了更大的学习率和提前停止(总共 2000 个 epoch 中有 300 个耐心)。
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
train_x = np.linspace(0, 80, 160)
train_y = train_x**2
test_x = np.linspace(80, 100, 40)
test_y = test_x**2
model2 = tf.keras.models.Sequential(
[tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(100, activation='relu'),
tf.keras.layers.Dense(1)]
)
loss = tf.keras.losses.mse
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-2)
early_stop = tf.keras.callbacks.EarlyStopping(monitor='loss', patience=300, restore_best_weights=True)
model2.compile(optimizer=optimizer, loss=loss, metrics=tf.metrics.RootMeanSquaredError())
model2.fit(tf.expand_dims(train_x, -1), train_y, epochs=2000, verbose=1, callbacks=[early_stop])
train_pred = model2.predict(train_x)
test_pred = model2.predict(test_x)
plt.scatter(train_x, train_y, c='blue', label='train x')
plt.scatter(test_x, test_y, c='green', label='test x')
plt.scatter(train_x, train_pred, c='red', label='train pred')
plt.scatter(test_x, test_pred, c='orange', label='test pred')
plt.legend()
plt.show()
Training and test results photo here