神经网络多用于分类,回归比较少,所以就想实践一下做非线性回归效果如何。
不想看过程的可以直接看代码, 代码地址github
回归 非线性函数 y=x1*x2
模型:
def Mul(input_dim):
inputs = Input(shape=(input_dim, ))
out = Dense(10)(inputs)
out = Activation('relu')(out)
out = Dense(10)(out)
out = Activation('relu')(out)
out = Dense(10)(out)
out = Activation('relu')(out)
out = Dense(10)(out)
out = Activation('relu')(out)
out = Dense(8)(out)
out = Activation('relu')(out)
out = Dense(1)(out)
model = Model(inputs = inputs, outputs = out)
return model
模型一开始并不是这样的,网络层数和隐藏层神经元个数是在拟合y=x * x(便于可视化)时试出来的,暂且先用来拟合y=x1*x2。
生成数据:
def gen_data(num, dst=None):
X1 = np.linspace(-1, 1, num)
X2 = np.linspace(-1, 1, num)
np.random.shuffle(X1)
np.random.shuffle(X2)
Y = X1*X2 + np.random.normal(0, 0.05, (num, )) #生成Y并添加噪声
data = pd.DataFrame(columns=['Y','X1','X2'])
data['Y'] = Y
data['X1'] = X1
data['X2'] = X2
if dst is not None:
data.to_csv(dst, index=None)
return data
loss就用 mse, 优化用sgd
model.compile(loss='mse', optimizer='sgd')
训练:
由于数据比较多(8000条),训练了30个epoch还没有early_stopping,说明模型还不是很复杂。
看loss这么低,效果应该还不错,再看一下预测结果:
从结果上来看,预测值pred和Y还是有差距的。一方面是因为Y值加了高斯噪声,另一方面误差函数是mse,而X1,X2,Y又都在区间(-1,1),所以mse衡量误差并不是非常有说服力。
把高斯噪声去掉:
去掉了噪声后loss更小了,不过几个epoch下降的慢了一些。再看一下预测结果:
pred和Y之间还是有不小的差距的。
把损失函数换成mape
loss已经不忍直视了
从结果来看,可能是发生了梯度问题,看一下梯度
梯度消失,权重和偏置爆炸了。
目标函数mape, 激活函数换成elu
loss是Nan,权重也出现了Nan
又重新试了下map+relu和mse+relu效果差不多
代码地址github
另外有一点值得注意的是,如果数据不在(-1,1)之间,网络就很难收敛
会产生梯度问题