使用TensorFlow实现二分类的方法示例


Posted in Python onFebruary 05, 2019

使用TensorFlow构建一个神经网络来实现二分类,主要包括输入数据格式、隐藏层数的定义、损失函数的选择、优化函数的选择、输出层。下面通过numpy来随机生成一组数据,通过定义一种正负样本的区别,通过TensorFlow来构造一个神经网络来实现二分类。

一、神经网络结构

输入数据:定义输入一个二维数组(x1,x2),数据通过numpy来随机产生,将输出定义为0或1,如果x1+x2<1,则y为1,否则y为0。

隐藏层:定义两层隐藏层,隐藏层的参数为(2,3),两行三列的矩阵,输入数据通过隐藏层之后,输出的数据为(1,3),t通过矩阵之间的乘法运算可以获得输出数据。

损失函数:使用交叉熵作为神经网络的损失函数,常用的损失函数还有平方差。

优化函数:通过优化函数来使得损失函数最小化,这里采用的是Adadelta算法进行优化,常用的还有梯度下降算法。

输出数据:将隐藏层的输出数据通过(3,1)的参数,输出一个一维向量,值的大小为0或1。

使用TensorFlow实现二分类的方法示例

二、TensorFlow代码的实现

import tensorflow as tf
from numpy.random import RandomState
 
if __name__ == "__main__":
  #定义每次训练数据batch的大小为8,防止内存溢出
  batch_size = 8
  #定义神经网络的参数
  w1 = tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
  w2 = tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))
  #定义输入和输出
  x = tf.placeholder(tf.float32,shape=(None,2),name="x-input")
  y_ = tf.placeholder(tf.float32,shape=(None,1),name="y-input")
  #定义神经网络的前向传播过程
  a = tf.matmul(x,w1)
  y = tf.matmul(a,w2)
  #定义损失函数和反向传播算法
  #使用交叉熵作为损失函数
  #tf.clip_by_value(t, clip_value_min, clip_value_max,name=None)
  #基于min和max对张量t进行截断操作,为了应对梯度爆发或者梯度消失的情况
  cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y,1e-10,1.0)))
  # 使用Adadelta算法作为优化函数,来保证预测值与实际值之间交叉熵最小
  train_step = tf.train.AdamOptimizer(0.001).minimize(cross_entropy)
  #通过随机函数生成一个模拟数据集
  rdm = RandomState(1)
  # 定义数据集的大小
  dataset_size = 128
  # 模拟输入是一个二维数组
  X = rdm.rand(dataset_size,2)
  #定义输出值,将x1+x2 < 1的输入数据定义为正样本
  Y = [[int(x1+x2 < 1)] for (x1,x2) in X]
  #创建会话运行TensorFlow程序
  with tf.Session() as sess:
    #初始化变量 tf.initialize_all_variables()
    init = tf.initialize_all_variables()
    sess.run(init)
    #设置神经网络的迭代次数
    steps = 5000
    for i in range(steps):
      #每次选取batch_size个样本进行训练
      start = (i * batch_size) % dataset_size
      end = min(start + batch_size,dataset_size)
      #通过选取样本训练神经网络并更新参数
      sess.run(train_step,feed_dict={x:X[start:end],y_:Y[start:end]})
      #每迭代1000次输出一次日志信息
      if i % 1000 == 0 :
        # 计算所有数据的交叉熵
        total_cross_entropy = sess.run(cross_entropy,feed_dict={x:X,y_:Y})
        # 输出交叉熵之和
        print("After %d training step(s),cross entropy on all data is %g"%(i,total_cross_entropy))
    #输出参数w1
    print(w1.eval(session=sess))
    #输出参数w2
    print(w2.eval(session=sess))
    '''
    After 0 training step(s),cross entropy on all data is 0.0674925
    After 1000 training step(s),cross entropy on all data is 0.0163385
    After 2000 training step(s),cross entropy on all data is 0.00907547
    After 3000 training step(s),cross entropy on all data is 0.00714436
    After 4000 training step(s),cross entropy on all data is 0.00578471
    [[-1.96182752 2.58235407 1.68203771]
     [-3.46817183 1.06982315 2.11788988]]
    [[-1.82471502]
     [ 2.68546653]
     [ 1.41819501]]
    '''

上面的TensorFlow二分类我是参考Google深度学习框架,al_kk评论说这个损失函数的定义存在问题,之前没有仔细的去考虑这个问题,al_kk提醒之后,我发现这个损失函数的定义的确存在问题,经过测试发现这个模型也存在一些问题。其实,我们的主要目的是想去学习一个x1+x2=1的直线,来区分0和1两类不同的类别,下面我对这个模型进行了一些修改并说明一下为什么这个损失函数的定义存在问题。

一、为什么说这个损失函数的定义存在问题呢?

上面程序中定义的输入的y的shape为[1],也就是y的类别为0或1,对于单分类问题交叉熵损失函数的定义应该为

使用TensorFlow实现二分类的方法示例

其中n为y的种类,在上面的例子中需要包含0和1的y_*log(y)(y_表示真实类别,y表示预测类别),而上面的例子中只包含了一个y_*log(y),在上例中正确的损失函数定义应该为loss = y_*log(y) + (1-y_) * log(1-y)。为了便于大家理解,我引用al_kk:“如果只有一个类别的交叉熵即y_ * log(y),如果真实类别y_为0,那么无论预测值y为任何值的时候,损失函数始终为0”。除此之外,大家可以想一下,当预测值始终为1的时候,那么损失函数是不是就会一直为0,这也是为什么输出预测值y的时候,y的值都是大于1的。如果将y的shape改为[2]的话,就可以使用y_*log(y)。

二、修改之后的二分类程序

import tensorflow as tf
import numpy as np
from numpy.random import RandomState
import matplotlib.pyplot as plt
 
if __name__ == "__main__":
  #定义神经网络的参数
  w = tf.Variable(tf.random_normal([2,1],stddev=1,seed=1))
  b = tf.Variable(tf.random_normal([1],stddev=1,seed=1))
  #定义输入和输出
  x = tf.placeholder(tf.float32,shape=(None,2),name="x-input")
  y_ = tf.placeholder(tf.float32,shape=(None,1),name="y-input")
  #定义神经网络的前向传播过程
  y = tf.nn.sigmoid(tf.matmul(x,w) + b)
  #基于min和max对张量t进行截断操作,为了应对梯度爆发或者梯度消失的情况
  cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y,1e-10,1.0))+(1-y_) * tf.log(tf.clip_by_value(1-y,1e-10,1.0)))
  # 使用Adadelta算法作为优化函数,来保证预测值与实际值之间交叉熵最小
  train_step = tf.train.AdamOptimizer(0.01).minimize(cross_entropy)
  #通过随机函数生成一个模拟数据集
  rdm = RandomState(1)
  # 定义数据集的大小
  dataset_size = 100
  # 模拟输入是一个二维数组
  X = rdm.rand(dataset_size,2)
  #定义输出值,将x1+x2 < 1的输入数据定义为正样本
  Y = [[int(x1+x2 < 1)] for (x1,x2) in X]
  #创建会话运行TensorFlow程序
  with tf.Session() as sess:
    #初始化变量 tf.initialize_all_variables()
    init = tf.initialize_all_variables()
    sess.run(init)
    #设置神经网络的迭代次数
    steps = 500
    for i in range(steps):
      #通过选取样本训练神经网络并更新参数
      for (input_x,input_y) in zip(X,Y):
        input_x = np.reshape(input_x,(1,2))
        input_y = np.reshape(input_y,(1,1))
        sess.run(train_step,feed_dict={x:input_x,y_:input_y})
      #每迭代1000次输出一次日志信息
      if i % 100 == 0:
        # 计算所有数据的交叉熵
        total_cross_entropy = sess.run(cross_entropy,feed_dict={x:X,y_:Y})
        # 输出交叉熵之和
        print("After %d training step(s),cross entropy on all data is %g"%(i,total_cross_entropy))
    #预测输入X的类别
    pred_Y = sess.run(y,feed_dict={x:X})
    index = 1
    for pred,real in zip(pred_Y,Y):
      print(pred,real)

使用TensorFlow实现二分类的方法示例

使用TensorFlow实现二分类的方法示例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 写的一个爬虫程序源码
Feb 28 Python
python实现人脸识别经典算法(一) 特征脸法
Mar 13 Python
浅谈Pandas中map, applymap and apply的区别
Apr 10 Python
python爬虫之xpath的基本使用详解
Apr 18 Python
opencv实现静态手势识别 opencv实现剪刀石头布游戏
Jan 22 Python
Python对象与引用的介绍
Jan 24 Python
python实现诗歌游戏(类继承)
Feb 26 Python
PyQt5 加载图片和文本文件的实例
Jun 14 Python
python安装scipy的方法步骤
Jun 26 Python
Python 装饰器@,对函数进行功能扩展操作示例【开闭原则】
Oct 17 Python
Python unittest 自动识别并执行测试用例方式
Mar 09 Python
Python requests.post方法中data与json参数区别详解
Apr 30 Python
Tensorflow分类器项目自定义数据读入的实现
Feb 05 #Python
在Python 字典中一键对应多个值的实例
Feb 03 #Python
Django csrf 两种方法设置form的实例
Feb 03 #Python
解决django前后端分离csrf验证的问题
Feb 03 #Python
Python利用heapq实现一个优先级队列的方法
Feb 03 #Python
对Python3中dict.keys()转换成list类型的方法详解
Feb 03 #Python
对python中字典keys,values,items的使用详解
Feb 03 #Python
You might like
PHP 和 MySQL 基础教程(二)
2006/10/09 PHP
浅析ThinkPHP的模板输出功能
2014/07/01 PHP
php保存信息到当前Session的方法
2015/03/16 PHP
ThinkPHP3.2.2实现持久登录(记住我)功能的方法
2016/05/16 PHP
php实现图片按比例截取的方法
2017/02/06 PHP
PHP判断是手机端还是PC端 PHP判断是否是微信浏览器
2017/03/15 PHP
php+redis消息队列实现抢购功能
2018/02/08 PHP
给网站上的广告“加速”显示的方法
2007/04/08 Javascript
jQuery截取指定长度字符串的实现原理及代码
2014/07/01 Javascript
javascript实现全角半角检测的方法
2015/07/23 Javascript
JavaScript统计网站访问次数的实现代码
2015/11/18 Javascript
javascript实现PC网页里的拖拽效果
2016/03/14 Javascript
Vue 2.0的数据依赖实现原理代码简析
2017/07/10 Javascript
Angular angular-file-upload文件上传的示例代码
2018/08/23 Javascript
Vuex 在Vue 组件中获得Vuex 状态state的方法
2018/08/27 Javascript
分享vue里swiper的一些坑
2018/08/30 Javascript
详解基于vue-cli3.0如何构建功能完善的前端架子
2018/10/09 Javascript
Nodejs实现图片上传、压缩预览、定时删除功能
2019/10/25 NodeJs
解决vue+router路由跳转不起作用的一项原因
2020/07/19 Javascript
Vue页面跳转传递参数及接收方式
2020/09/09 Javascript
[01:17:55]VGJ.T vs Mineski 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/20 DOTA
Python numpy实现数组合并实例(vstack,hstack)
2018/01/09 Python
python基础学习之如何对元组各个元素进行命名详解
2018/07/12 Python
不知道这5种下划线的含义,你就不算真的会Python!
2018/10/09 Python
一篇文章弄懂Python中的可迭代对象、迭代器和生成器
2019/08/12 Python
Python 实现劳拉游戏的实例代码(四连环、重力四子棋)
2021/03/03 Python
美国五金商店:Ace Hardware
2018/03/27 全球购物
Kingsoft金山公司C/C++笔试题
2016/05/10 面试题
广州喜创信息技术有限公司JAVA软件工程师笔试题
2012/10/17 面试题
异步传递消息系统的作用
2016/05/01 面试题
电子专业毕业生自我鉴定
2014/01/22 职场文书
政府信息公开实施方案
2014/05/09 职场文书
教师四风自我剖析材料
2014/09/30 职场文书
党的群众路线查摆剖析材料
2014/10/10 职场文书
白酒代理协议书范本
2014/10/26 职场文书
六一儿童节致辞
2015/07/31 职场文书