我注意到在某些情况下,特征缩放会完全破坏神经网络的性能。以下是我的结果,您可以轻松复制。
我使用神经网络来近似函数 在 如下:
在哪里 . 然后我随机抽样一些 () 作为我的训练集,并使用 作为目标。
通常 是一个 Keras Sequential 模型,有几个隐藏层,有 15-20 个神经元 (elu),还有一个没有激活函数的输出层。使用 初始化参数kernel_initializer='normal'
。
现在我在 1dim 中测试我的近似值时注意到以下内容(在尝试推广到更高维度之前):
为了 , 缩放 除以 100 并不会真正改变 , 估计 比较好。
但是,当我使用其他功能时,例如 或者 ,它完全失败了。
你有解释吗?
这非常令人不安,因为如果简单的一维示例完全失败,您如何相信您的网络可以逼近高维函数?
以下是 Python 中的示例实现:
from keras.models import Sequential
from keras.layers import Dense
import numpy as np
import matplotlib.pyplot as plt
d=1
nn_value_batch_size=128
nn_value_epochs=50
nn_value_training_size=10000
def nn_value_get_architecture(layers_sizes):
nn_value = Sequential()
nn_value.add(Dense(layers_sizes[0], input_dim=d, #d=1
kernel_initializer='normal', activation='elu'))
# hidden layers
for nb in layers_sizes[1:]:
nn_value.add(Dense(nb, kernel_initializer='normal',
activation='elu'))
# output layer
nn_value.add(Dense(1, kernel_initializer='normal'))
nn_value.compile(loss="mean_squared_error", optimizer='adam')
return nn_value
def nn_value_optimize(nn_value, objective_function,
x_normalize=True):
# fit the model
x_distribution = lambda size: np.random.uniform(0, 100, size)
for epoch in range(nn_value_epochs):
X_train = x_distribution(nn_value_training_size)
y_train = objective_function(X_train)
if x_normalize==True:
X_train = X_train/100
nn_value.fit(X_train, y_train,
batch_size=nn_value_batch_size,
verbose=1)
return nn_value
def g(X):
#return 1-(np.maximum(0., X-40)/(X-40) - np.maximum(0., X-60)/(X-60))
return (X-50)**2
#return np.maximum(0., X-50) #only example that works
nn_value = nn_value_get_architecture(
layers_sizes=[20,15,15,15,15])
g = np.vectorize(g)
normalize=True
nn_value = nn_value_optimize(nn_value, g, normalize)
# plot results
x = np.arange(0,101,1)
if normalize==True:
plt.plot(x, nn_value.predict(x/100))
else:
plt.plot(x, nn_value.predict(x))
plt.show()
无缩放:
使用缩放: