通过Keras搭建神经网络实现线性和非线性回归,并通过分析损失函数及网络对数据的拟合曲线,对比训练效果。Python程序如下
需要用到的第三方库:
(1)numpy,用于生成训练数据
(2)Keras,搭建神经网络,进行模型训练
(3)matplotlib,画图,直观展示训练过程中损失函数变化以及网络拟合能力
'''
全连接神经网络
1 实现线性回归
2 实现非线性回归
'''
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import SGD
import matplotlib.pyplot as plt
# 画图函数
def Plot(Loss, x, y, net):
y_pre = net.predict(x)
x, y, y_pre = x.reshape(1, -1)[0].tolist(), y.reshape(1, -1)[0].tolist(), y_pre.reshape(1, -1)[0].tolist()
plt.figure(1)
plt.subplot(1, 2, 1)
plt.plot(Loss)
plt.xlabel('eposide')
plt.ylabel('Loss')
plt.subplot(1, 2, 2)
plt.scatter(x, y)
plt.plot(x, y_pre, linewidth = 3, color = 'r')
plt.xlabel('x')
plt.ylabel('y')
plt.show()
# 定义线性神经网络
Linear_net = Sequential([
Dense(10, input_dim = 1),
Dense(1)
])
opt = SGD(lr = 0.0002)
Linear_net.compile(loss = 'mse', optimizer = opt)
# 定义非线性神经网络
Nonlinear_net = Sequential([
Dense(10, activation = 'relu', input_dim = 1),
Dense(16, activation = 'tanh'),
Dense(15, activation = 'relu'),
Dense(1)
])
opt = SGD(lr = 0.0002)
Nonlinear_net.compile(loss = 'mse', optimizer = opt)
x_data = np.linspace(-5, 5, 100).reshape(100, 1) # 构造训练数据
w, b = 0.8, 0.6 # 线性函数的权重和偏置
w1, w2, c = 0.9, 0.7, 1.2 # 二次函数的权重和偏置
noise = np.random.normal(0, 0.2, x_data.shape) # 噪声
y_data_1 = w * x_data + b + noise # y1 = w * x + b + noise
y_data_2 = w1 * x_data ** 2 + w2 * x_data + c + noise # y2 = w1 * x ^ 2 + w2 * x + b + noise
c = input('拟合线性函数(输入L)或非线性函数(输入N)?')
y_data = y_data_1 if c == 'L' else y_data_2
c = input('线性网络(输入L)或非线性网络(输入N)?')
if c == 'L':
history = Linear_net.fit(x_data, y_data, batch_size = 64, epochs = 500)
Loss = history.history['loss']
Plot(Loss, x_data, y_data, Linear_net)
else:
history = Nonlinear_net.fit(x_data, y_data, batch_size = 64, epochs = 1000)
Loss = history.history['loss']
Plot(Loss, x_data, y_data, Nonlinear_net)
使用线性网络拟合线性数据,结果如下
使用线性网络拟合非线性数据,结果如下
使用非线性网络拟合线性数据,结果如下
使用非线性网络拟合非线性数据,结果如下
读者可自行调节神经网络的隐藏层个数、各层神经元数量、 激活函数、学习率、优化器等参数,观察训练结果。