你犯了两个非常基本的错误:
- 您的超简单模型(具有单个单元的单层网络)根本不符合神经网络的条件,更不用说“深度学习”模型(因为您的问题已被标记)
- 同样,您的数据集(仅 20 个样本)也非常小
当然,如果神经网络要解决像x*x 这样“简单”的问题,就需要具有一定的复杂性;而它们真正闪耀的地方是在输入大型训练数据集时。
尝试解决此类函数近似的方法不仅仅是列出(少数可能的)输入,然后将其连同所需的输出一起馈送到模型中;请记住,NN 通过示例学习,而不是通过符号推理。而且例子越多越好。在类似情况下,我们通常会生成大量示例,然后将这些示例输入模型进行训练。
话虽如此,这里是一个相当简单的 Keras 3 层神经网络演示,用于逼近函数 x*x,使用在 [-50, 50] 中生成的 10,000 个随机数作为输入:
import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam
from keras import regularizers
import matplotlib.pyplot as plt
model = Sequential()
model.add(Dense(8, activation='relu', kernel_regularizer=regularizers.l2(0.001), input_shape = (1,)))
model.add(Dense(8, activation='relu', kernel_regularizer=regularizers.l2(0.001)))
model.add(Dense(1))
model.compile(optimizer=Adam(),loss='mse')
# generate 10,000 random numbers in [-50, 50], along with their squares
x = np.random.random((10000,1))*100-50
y = x**2
# fit the model, keeping 2,000 samples as validation set
hist = model.fit(x,y,validation_split=0.2,
epochs= 15000,
batch_size=256)
# check some predictions:
print(model.predict([4, -4, 11, 20, 8, -5]))
# result:
[[ 16.633354]
[ 15.031291]
[121.26833 ]
[397.78638 ]
[ 65.70035 ]
[ 27.040245]]
嗯,没那么糟糕!请记住,NN 是函数逼近器:我们应该期望它们既不完全再现函数关系,也不“知道”4 和 -4 的结果应该是一样的。
让我们在[-50,50] 中生成一些新的随机数据(请记住,出于所有实际目的,这些都是模型的unseen数据)并将它们与原始数据一起绘制,以获得更多大图:
plt.figure(figsize=(14,5))
plt.subplot(1,2,1)
p = np.random.random((1000,1))*100-50 # new random data in [-50, 50]
plt.plot(p,model.predict(p), '.')
plt.xlabel('x')
plt.ylabel('prediction')
plt.title('Predictions on NEW data in [-50,50]')
plt.subplot(1,2,2)
plt.xlabel('x')
plt.ylabel('y')
plt.plot(x,y,'.')
plt.title('Original data')
结果:
嗯,可以说它确实看起来确实是一个很好的近似值......
您还可以查看this thread 以获得正弦近似值。
最后要记住的是,虽然我们确实得到了一个不错的近似值,即使使用我们相对简单的模型,我们应该不期望的是外推,即在[-50, 50]之外表现良好;详情请看我在Is deep learning bad at fitting simple non linear functions outside training scope?的回答