深度学习(基于Tensorflow2.0)学习笔记——数据归一化与回调函数

主要内容

昨天我们已经成功训练了一个有效的神经网络,并且对官方提供的Fashion-MNIST数据集进行了分类,准确率达到了80%以上。但是这个准确率远远达不到应用的要求,那么,如何来提高神经网络的分类效率呢?这也就引出了我们接下来学习的内容:

  1. 数据归一化处理
  2. 回调函数的作用

数据归一化处理

归一化大家都不陌生,简单的理解,它的作用就是把你需要用到的数据经过处理后(通过某种算法)将其限制在你所规定的范围内。那么神经网络为什么需要归一化呢?我总结了以下几点:

  1. 取消量纲。举一个直观的例子,若样本x的一个特征A是从10000 -> 10000,另外一个特征B是从0.1 -> 1,这样在训练神经网络的时候,由于会求偏导数,导致A的参数变化极大,B参数变化极小。
  2. 使得梯度始终朝着最小值的方向走。
  3. 加速收敛。

关于最后两点详见吴恩达的机器学习课程,吴教授讲的十分生动形象,这里总结他的话大体意思为:由于数据的分布不同,必然会导致每一维的梯度下降不同,使用同一个learning rate 也就很难迭代到代价函数最低点。经过归一化(正则化)处理后,代价函数变得“更圆”,也就很容易进行梯度下降。

那么如何在函数中实现对数据的归一化呢,接下来进入实战。

实战数据归一化

我们打开昨天的工程,还是先要对所有的输出进行清空。这里我们归一化的方式和你在其他地方见到的归一化原理是一样的,只不过这里实现的方式有所区别。我们的基本思想还是x = x(x - u)/ std。其中u为均值,std为方差。这样便得到了一个正态分布。这里使用sklearn库中预处理API进行归一化:

from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
x_train_scaled = scaler.fit_transform(
	x_train.astype(np.float32).reshape(-1,1)).reshape(-1, 28, 28)
x_valid_scaled = scaler.transform(
	x_valid.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28)
x_test_scaled = scaler.transform(
	x_test.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28)

其中的fit_transform()在完成数据类型转换的同时,也将训练集中的均值和方差均记录了下来,以便于之后在测试集中使用,从而提高准确性。
然后用归一化的数据来训练模型:

history = model.fit(x_trian_scaled, y_train, epochs=10,
validation_data(x_valid_scaled, y_valid))

点击运行进行训练。
我们可以看到我们的准确率相较于归一化之前会有一定程度的提高。(这里由于我们训练的数据集规模比较小,提高的幅度可能较小)

然后再测试集进行测试:

model.evaluate(x_test_scaled, y_test)

同样,我们得到的最终结果相较于归一化之前准确度会有相应的提高,同时也伴随着损失率的下降。

回调函数(callbacks)

对于回调函数大家应该都不陌生,那么神经网络中的回调函数的作用是什么呢?举个最简单的栗子,在一次训练中,如果训练的迭代次数比较大,达到了几千,但是你发现,当神经网络训练到一般的时候他的准确率或者损失就已经达到你的要求了,这就意味着在往后的训练中神经网络所做的工作意义并不大,但是这时迭代次数才到了二分之一。这时候就需要回调函数了,在这里你可以规定在达到你要求的准确度之后停止训练,从而节省时间,大大提高了效率。

以上只是回调函数的一个作用,在回调函数的官方文档中,详细介绍了回调函数的各个参数。这里我们仅实现我们刚才要求的功能(EarlyStopping)。

实战回调函数

tf.keras中使用回调函数的做法是定义一个回调函数的参数列表,然后将其传入fit()函数中。

callbacks=[
	keras.callbacks.EarlyStopping(patience=5,min_delta=1e-3)
]
history = model.fit(x_train_scaled, y_train_scaled, epochs =10,
validation_data=(x_valid_scaled, y_valid),
callbacks = callbacks)

这里的回调函数EarlyStopping中有两个参数,分别是patience(等待次数),min_delta(最小差距)。即,当你的前后两次的损失下降率均低于min_delta时,若持续patience (次),训练将自动结束。由此可见,回调函数可以触发的前提是你的迭代次数要足够多,在这里我们如果将迭代次数增加到100次,回调函数的作用才能比较明显。

发布了5 篇原创文章 · 获赞 7 · 访问量 433

猜你喜欢

转载自blog.csdn.net/qq_43632917/article/details/104413863