详解tensorflow之过拟合问题实战


Posted in Python onNovember 01, 2020

过拟合问题实战

1.构建数据集

我们使用的数据集样本特性向量长度为 2,标签为 0 或 1,分别代表了 2 种类别。借助于 scikit-learn 库中提供的 make_moons 工具我们可以生成任意多数据的训练集。

import matplotlib.pyplot as plt
# 导入数据集生成工具
import numpy as np
import seaborn as sns
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from tensorflow.keras import layers, Sequential, regularizers
from mpl_toolkits.mplot3d import Axes3D

为了演示过拟合现象,我们只采样了 1000 个样本数据,同时添加标准差为 0.25 的高斯噪声数据:

def load_dataset():
 # 采样点数
 N_SAMPLES = 1000
 # 测试数量比率
 TEST_SIZE = None

 # 从 moon 分布中随机采样 1000 个点,并切分为训练集-测试集
 X, y = make_moons(n_samples=N_SAMPLES, noise=0.25, random_state=100)
 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=TEST_SIZE, random_state=42)
 return X, y, X_train, X_test, y_train, y_test

make_plot 函数可以方便地根据样本的坐标 X 和样本的标签 y 绘制出数据的分布图:

def make_plot(X, y, plot_name, file_name, XX=None, YY=None, preds=None, dark=False, output_dir=OUTPUT_DIR):
 # 绘制数据集的分布, X 为 2D 坐标, y 为数据点的标签
 if dark:
  plt.style.use('dark_background')
 else:
  sns.set_style("whitegrid")
 axes = plt.gca()
 axes.set_xlim([-2, 3])
 axes.set_ylim([-1.5, 2])
 axes.set(xlabel="$x_1$", ylabel="$x_2$")
 plt.title(plot_name, fontsize=20, fontproperties='SimHei')
 plt.subplots_adjust(left=0.20)
 plt.subplots_adjust(right=0.80)
 if XX is not None and YY is not None and preds is not None:
  plt.contourf(XX, YY, preds.reshape(XX.shape), 25, alpha=0.08, cmap=plt.cm.Spectral)
  plt.contour(XX, YY, preds.reshape(XX.shape), levels=[.5], cmap="Greys", vmin=0, vmax=.6)
 # 绘制散点图,根据标签区分颜色m=markers
 markers = ['o' if i == 1 else 's' for i in y.ravel()]
 mscatter(X[:, 0], X[:, 1], c=y.ravel(), s=20, cmap=plt.cm.Spectral, edgecolors='none', m=markers, ax=axes)
 # 保存矢量图
 plt.savefig(output_dir + '/' + file_name)
 plt.close()
def mscatter(x, y, ax=None, m=None, **kw):
 import matplotlib.markers as mmarkers
 if not ax: ax = plt.gca()
 sc = ax.scatter(x, y, **kw)
 if (m is not None) and (len(m) == len(x)):
  paths = []
  for marker in m:
   if isinstance(marker, mmarkers.MarkerStyle):
    marker_obj = marker
   else:
    marker_obj = mmarkers.MarkerStyle(marker)
   path = marker_obj.get_path().transformed(
    marker_obj.get_transform())
   paths.append(path)
  sc.set_paths(paths)
 return sc
X, y, X_train, X_test, y_train, y_test = load_dataset()
make_plot(X,y,"haha",'月牙形状二分类数据集分布.svg')

详解tensorflow之过拟合问题实战

2.网络层数的影响

为了探讨不同的网络深度下的过拟合程度,我们共进行了 5 次训练实验。在? ∈ [0,4]时,构建网络层数为n + 2层的全连接层网络,并通过 Adam 优化器训练 500 个 Epoch

def network_layers_influence(X_train, y_train):
 # 构建 5 种不同层数的网络
 for n in range(5):
  # 创建容器
  model = Sequential()
  # 创建第一层
  model.add(layers.Dense(8, input_dim=2, activation='relu'))
  # 添加 n 层,共 n+2 层
  for _ in range(n):
   model.add(layers.Dense(32, activation='relu'))
  # 创建最末层
  model.add(layers.Dense(1, activation='sigmoid'))
  # 模型装配与训练
  model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
  model.fit(X_train, y_train, epochs=N_EPOCHS, verbose=1)
  # 绘制不同层数的网络决策边界曲线
  # 可视化的 x 坐标范围为[-2, 3]
  xx = np.arange(-2, 3, 0.01)
  # 可视化的 y 坐标范围为[-1.5, 2]
  yy = np.arange(-1.5, 2, 0.01)
  # 生成 x-y 平面采样网格点,方便可视化
  XX, YY = np.meshgrid(xx, yy)
  preds = model.predict_classes(np.c_[XX.ravel(), YY.ravel()])
  print(preds)
  title = "网络层数:{0}".format(2 + n)
  file = "网络容量_%i.png" % (2 + n)
  make_plot(X_train, y_train, title, file, XX, YY, preds, output_dir=OUTPUT_DIR + '/network_layers')

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

3.Dropout的影响

为了探讨 Dropout 层对网络训练的影响,我们共进行了 5 次实验,每次实验使用 7 层的全连接层网络进行训练,但是在全连接层中间隔插入 0~4 个 Dropout 层并通过 Adam优化器训练 500 个 Epoch

def dropout_influence(X_train, y_train):
 # 构建 5 种不同数量 Dropout 层的网络
 for n in range(5):
  # 创建容器
  model = Sequential()
  # 创建第一层
  model.add(layers.Dense(8, input_dim=2, activation='relu'))
  counter = 0
  # 网络层数固定为 5
  for _ in range(5):
   model.add(layers.Dense(64, activation='relu'))
  # 添加 n 个 Dropout 层
   if counter < n:
    counter += 1
    model.add(layers.Dropout(rate=0.5))

  # 输出层
  model.add(layers.Dense(1, activation='sigmoid'))
  # 模型装配
  model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
  # 训练
  model.fit(X_train, y_train, epochs=N_EPOCHS, verbose=1)
  # 绘制不同 Dropout 层数的决策边界曲线
  # 可视化的 x 坐标范围为[-2, 3]
  xx = np.arange(-2, 3, 0.01)
  # 可视化的 y 坐标范围为[-1.5, 2]
  yy = np.arange(-1.5, 2, 0.01)
  # 生成 x-y 平面采样网格点,方便可视化
  XX, YY = np.meshgrid(xx, yy)
  preds = model.predict_classes(np.c_[XX.ravel(), YY.ravel()])
  title = "无Dropout层" if n == 0 else "{0}层 Dropout层".format(n)
  file = "Dropout_%i.png" % n
  make_plot(X_train, y_train, title, file, XX, YY, preds, output_dir=OUTPUT_DIR + '/dropout')

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

4.正则化的影响

为了探讨正则化系数?对网络模型训练的影响,我们采用 L2 正则化方式,构建了 5 层的神经网络,其中第 2,3,4 层神经网络层的权值张量 W 均添加 L2 正则化约束项:

def build_model_with_regularization(_lambda):
 # 创建带正则化项的神经网络
 model = Sequential()
 model.add(layers.Dense(8, input_dim=2, activation='relu')) # 不带正则化项
 # 2-4层均是带 L2 正则化项
 model.add(layers.Dense(256, activation='relu', kernel_regularizer=regularizers.l2(_lambda)))
 model.add(layers.Dense(256, activation='relu', kernel_regularizer=regularizers.l2(_lambda)))
 model.add(layers.Dense(256, activation='relu', kernel_regularizer=regularizers.l2(_lambda)))
 # 输出层
 model.add(layers.Dense(1, activation='sigmoid'))
 model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # 模型装配
 return model

下面我们首先来实现一个权重可视化的函数

def plot_weights_matrix(model, layer_index, plot_name, file_name, output_dir=OUTPUT_DIR):
 # 绘制权值范围函数
 # 提取指定层的权值矩阵
 weights = model.layers[layer_index].get_weights()[0]
 shape = weights.shape
 # 生成和权值矩阵等大小的网格坐标
 X = np.array(range(shape[1]))
 Y = np.array(range(shape[0]))
 X, Y = np.meshgrid(X, Y)
 # 绘制3D图
 fig = plt.figure()
 ax = fig.gca(projection='3d')
 ax.xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
 ax.yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
 ax.zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0))
 plt.title(plot_name, fontsize=20, fontproperties='SimHei')
 # 绘制权值矩阵范围
 ax.plot_surface(X, Y, weights, cmap=plt.get_cmap('rainbow'), linewidth=0)
 # 设置坐标轴名
 ax.set_xlabel('网格x坐标', fontsize=16, rotation=0, fontproperties='SimHei')
 ax.set_ylabel('网格y坐标', fontsize=16, rotation=0, fontproperties='SimHei')
 ax.set_zlabel('权值', fontsize=16, rotation=90, fontproperties='SimHei')
 # 保存矩阵范围图
 plt.savefig(output_dir + "/" + file_name + ".svg")
 plt.close(fig)

在保持网络结构不变的条件下,我们通过调节正则化系数 ? = 0.00001,0.001,0.1,0.12,0.13 来测试网络的训练效果,并绘制出学习模型在训练集上的决策边界曲线

def regularizers_influence(X_train, y_train):
 for _lambda in [1e-5, 1e-3, 1e-1, 0.12, 0.13]: # 设置不同的正则化系数
  # 创建带正则化项的模型
  model = build_model_with_regularization(_lambda)
  # 模型训练
  model.fit(X_train, y_train, epochs=N_EPOCHS, verbose=1)
  # 绘制权值范围
  layer_index = 2
  plot_title = "正则化系数:{}".format(_lambda)
  file_name = "正则化网络权值_" + str(_lambda)
  # 绘制网络权值范围图
  plot_weights_matrix(model, layer_index, plot_title, file_name, output_dir=OUTPUT_DIR + '/regularizers')
  # 绘制不同正则化系数的决策边界线
  # 可视化的 x 坐标范围为[-2, 3]
  xx = np.arange(-2, 3, 0.01)
  # 可视化的 y 坐标范围为[-1.5, 2]
  yy = np.arange(-1.5, 2, 0.01)
  # 生成 x-y 平面采样网格点,方便可视化
  XX, YY = np.meshgrid(xx, yy)
  preds = model.predict_classes(np.c_[XX.ravel(), YY.ravel()])
  title = "正则化系数:{}".format(_lambda)
  file = "正则化_%g.svg" % _lambda
  make_plot(X_train, y_train, title, file, XX, YY, preds, output_dir=OUTPUT_DIR + '/regularizers')
regularizers_influence(X_train, y_train)

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

详解tensorflow之过拟合问题实战

到此这篇关于详解tensorflow之过拟合问题实战的文章就介绍到这了,更多相关tensorflow 过拟合内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python 面向对象 成员的访问约束
Dec 23 Python
详解Python中的多线程编程
Apr 09 Python
python采集百度百科的方法
Jun 05 Python
Python操作csv文件实例详解
Jul 31 Python
Django实现组合搜索的方法示例
Jan 23 Python
python 获取字符串MD5值方法
May 29 Python
Python BS4库的安装与使用详解
Aug 08 Python
对python添加模块路径的三种方法总结
Oct 16 Python
使用Python批量修改文件名的代码实例
Jan 24 Python
Pandas 重塑(stack)和轴向旋转(pivot)的实现
Jul 22 Python
Python自动化之UnitTest框架实战记录
Sep 08 Python
Python系统公网私网流量监控实现流程
Nov 23 Python
python cookie反爬处理的实现
Nov 01 #Python
10个python爬虫入门实例(小结)
Nov 01 #Python
利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境
Nov 01 #Python
Python经纬度坐标转换为距离及角度的实现
Nov 01 #Python
详解Anaconda安装tensorflow报错问题解决方法
Nov 01 #Python
python Cartopy的基础使用详解
Nov 01 #Python
Python中使用aiohttp模拟服务器出现错误问题及解决方法
Oct 31 #Python
You might like
PHP中使用smarty生成静态文件的例子
2014/04/24 PHP
对比分析php中Cookie与Session的异同
2016/02/19 PHP
php array_walk 对数组中的每个元素应用用户自定义函数详解
2016/11/18 PHP
[转]JS宝典学习笔记
2007/02/07 Javascript
js一组验证函数
2008/12/20 Javascript
javascript自定义的addClass()方法
2014/05/28 Javascript
jquery实现导航固定顶部的效果仿蘑菇街
2014/10/22 Javascript
jQuery中:file选择器用法实例
2015/01/04 Javascript
JavaSacript中charCodeAt()方法的使用详解
2015/06/05 Javascript
jQuery实现选项卡切换效果简单演示
2015/12/09 Javascript
基于jQuery实现的无刷新表格分页实例
2016/02/17 Javascript
微信小程序 数据遍历的实现
2017/04/05 Javascript
浅谈 vue 中的 watcher
2017/12/04 Javascript
聊聊Vue 中 title 的动态修改问题
2019/06/11 Javascript
vue组件讲解(is属性的用法)模板标签替换操作
2020/09/04 Javascript
二种python发送邮件实例讲解(python发邮件附件可以使用email模块实现)
2013/12/03 Python
Python实现设置windows桌面壁纸代码分享
2015/03/28 Python
浅谈Python中带_的变量或函数命名
2017/12/04 Python
Django实现支付宝付款和微信支付的示例代码
2018/07/25 Python
python使用xlsxwriter实现有向无环图到Excel的转换
2018/12/12 Python
Python 使用 attrs 和 cattrs 实现面向对象编程的实践
2019/06/12 Python
Pyqt5 实现跳转界面并关闭当前界面的方法
2019/06/19 Python
利用python-docx模块写批量生日邀请函
2019/08/26 Python
python主要用于哪些方向
2020/07/05 Python
用css3实现转换过渡和动画效果
2020/03/13 HTML / CSS
html5调用摄像头功能的实现代码
2018/05/07 HTML / CSS
Weekendesk意大利:探索多种引人入胜的周末主题
2016/10/14 全球购物
南非最大的花卉和送礼服务:NetFlorist
2017/09/13 全球购物
爱尔兰旅游网站:ebookers.ie
2020/01/24 全球购物
英国鲜花递送:Blossoming Gifts
2020/07/10 全球购物
广州足迹信息技术有限公司Java软件工程师试题
2014/02/15 面试题
Delphi工程师笔试题
2013/09/21 面试题
寄语是什么意思
2014/04/10 职场文书
简历自荐信范文
2015/03/09 职场文书
运动会通讯稿300字
2015/07/20 职场文书
JavaScript函数柯里化
2021/11/07 Javascript