天天看点

BP神经网络入门学习笔记回归模型(keras)

因为要用到神经网络算法,之前接触过一些机器学习的皮毛还是半知半解,先着手练习一些比较好理解的小项目吧,新手上路见笑了。开始:

文章目录

  • 回归模型(keras)
    • 一元二次模型
    • 调整与改进
      • 阶段1——修改epochs
      • 阶段2——修改学习率

回归模型(keras)

一元二次模型

先放模型:

y = x 2 + 1 y=x^2+1 y=x2+1

样本训练数据随机模拟就好了。引入tf库中的keras模块,程序小,所以要用到的函数我就直接单独加载了:

import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import SGD
from tensorflow.keras.initializers import Ones
import matplotlib.pyplot as plt
           

接下来生成200组数据样本,加入随机噪声,其中前160组作为训练样本,后40组用于测试评估网络

X = np.linspace(-10, 10, 200)
np.random.shuffle(X)    # randomize the data
Y = X * X + 1 + np.random.normal(0, 0.05, (200, ))
X_train, Y_train = X[:160], Y[:160]     # train 前 160 data points
X_test, Y_test = X[160:], Y[160:]       # test 后 40 data points
           

画出训练集

BP神经网络入门学习笔记回归模型(keras)

以及测试集

BP神经网络入门学习笔记回归模型(keras)

接下来建立网络层。从这个部分开始,就要一点一点尝试设置参数了,以下参数的调整对结果均有影响(不调整有可能也有影响orz…)

# 建立神经网络
model = Sequential()
model.add(Dense(units=10, input_dim=1, activation='relu')) 
model.add(Dense(units=10, activation='relu')) 
model.add(Dense(units=1, activation='relu'))
           

先解释一下这个代码块的含义,Sequential()函数keras模块中的堆叠模型(简单理解就是网络层直接一层一层的叠加 )

add函数给这个模型增加Dense层,Dense即全连接层,存放每个权重的通道,这几行函数其实构建了如下这样一个网络:

BP神经网络入门学习笔记回归模型(keras)

一元变量X对应输入层是一维的,这时Dense1必须要告知输入维度

Input_dim = 1

,后面的连接层的input_dim参数就没必要写了,可以推算出来。每个dense层还要给出units个数,表示下个层的单元节个数,这里两个隐藏层节点数分别都为10个。这样一来,每一层的节点数就很清楚了。激活函数选择了"relu"。

接下来配置学习过程,损失函数选择均方根对数误差,优化器是SGD(随机梯度下降)参数lr是学习率,评估标准为精度值:

# 选择损失函数和优化器
model.compile(loss='mean_squared_logarithmic_error', optimizer=SGD(lr=0.01),metrics=["accuracy"])
           

开始训练,fit函数参数设置:epoch为训练次数,verbose=0表示我不想看到训练中输出的每个epoch,batch_size默认为32,我没有设置,validation_data放上测试集

# 训练
print('Training ----------')
history = model.fit(X_train, Y_train, epochs=50, verbose=0, validation_data=(X_test, Y_test))
           

这一部分是可视化的部分,精度值:

# 绘制训练 & 验证的准确率值
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('Model accuracy')
plt.ylabel('Accuracy')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()
           
BP神经网络入门学习笔记回归模型(keras)

(好像出现了点问题,待解决。。)

损失函数:

# 绘制训练 & 验证的损失值
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(['Train', 'Test'], loc='upper left')
plt.show()
           
BP神经网络入门学习笔记回归模型(keras)

(有时候这个loss函数也会居高不下)

# 评估
loss_and_metrics = model.evaluate(X_test, Y_test)
           
loss_and_metrics
           

[0.22141730785369873, 0.0]

(误差很大,精度一直是0)

再做一个数据集预测一下

# 预测
X_pre = np.linspace(-10, 10, 200)
Y_pre = X_pre * X_pre + 1
classes = model.predict(X_pre, batch_size=7)
plt.scatter(X_pre, Y_pre)
plt.scatter(X_pre, classes)
           
BP神经网络入门学习笔记回归模型(keras)

(看得出来误差很大。。)

调整与改进

阶段1——修改epochs

epochs = 500 试一下

loss:

BP神经网络入门学习笔记回归模型(keras)

预测:

BP神经网络入门学习笔记回归模型(keras)

(???!@#¥%……&# )

重新跑一下。。。

loss:

BP神经网络入门学习笔记回归模型(keras)

预测:

BP神经网络入门学习笔记回归模型(keras)

参数没调整的情况下也会出现全为0的问题,是否梯度下降过程中卡在局部极小点?

阶段2——修改学习率

前面的成图发现拟合的函数有了大概的雏形了,但最终曲线没有弯曲成想要的弧度。学习样本不足,步伐太慢,网络太小,都有可能。先调整一下学习率,令lr = 0.1

loss:

BP神经网络入门学习笔记回归模型(keras)

预测:

BP神经网络入门学习笔记回归模型(keras)

可以看到,loss函数收敛更快了,曲线拟合效果变好了。

令 lr = 0.2

loss:

BP神经网络入门学习笔记回归模型(keras)

预测:

BP神经网络入门学习笔记回归模型(keras)

比刚刚的效果要好。

令 lr = 0.3

loss:

BP神经网络入门学习笔记回归模型(keras)

预测:

BP神经网络入门学习笔记回归模型(keras)

这次变化不是很大了,我想我应该找出一个让它效果变差的界限。

当我把学习率加到1时,

loss:

BP神经网络入门学习笔记回归模型(keras)

预测:

BP神经网络入门学习笔记回归模型(keras)

loss函数收敛的不那么平滑,但拟合结果更好了。

至于精度值一直为0的问题,有待解决,再去研究一下。

  • 函数拟合
  • 精度值的问题

------------------------------------------更新 2019/09/05------------------------------------------

回归模型不需要用到accuracy评估,accuracy是评估分类问题的,把那部分的代码和可视化去掉就行。

尝试了一下把优化器SGD改成了Adam,效果很明显:

# 选择损失函数和优化器
model.compile(loss='mean_squared_logarithmic_error', optimizer=Adam(lr=0.1))
           

loss:

BP神经网络入门学习笔记回归模型(keras)

预测:

BP神经网络入门学习笔记回归模型(keras)

继续阅读