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

使用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代码的实现

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,对于单分类问题交叉熵损失函数的定义应该为

其中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)

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

(0)

相关推荐

  • 利用TensorFlow训练简单的二分类神经网络模型的方法

    利用TensorFlow实现<神经网络与机器学习>一书中4.7模式分类练习 具体问题是将如下图所示双月牙数据集分类. 使用到的工具: python3.5    tensorflow1.2.1   numpy   matplotlib 1.产生双月环数据集 def produceData(r,w,d,num): r1 = r-w/2 r2 = r+w/2 #上半圆 theta1 = np.random.uniform(0, np.pi ,num) X_Col1 = np.random.unifo

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

    使用TensorFlow构建一个神经网络来实现二分类,主要包括输入数据格式.隐藏层数的定义.损失函数的选择.优化函数的选择.输出层.下面通过numpy来随机生成一组数据,通过定义一种正负样本的区别,通过TensorFlow来构造一个神经网络来实现二分类. 一.神经网络结构 输入数据:定义输入一个二维数组(x1,x2),数据通过numpy来随机产生,将输出定义为0或1,如果x1+x2<1,则y为1,否则y为0. 隐藏层:定义两层隐藏层,隐藏层的参数为(2,3),两行三列的矩阵,输入数据通过隐藏层之

  • laravel 框架实现无限级分类的方法示例

    本文实例讲述了laravel 框架实现无限级分类的方法.分享给大家供大家参考,具体如下: 模型中的代码 namespace App\models\wxj; use Illuminate\Support\Facades\DB; use Session; class Wxjlx { public function r(){ //输出数据库的所有内容 $sql=DB::table('wxjlx')->get(); //调用fl方法 $result=self::fl($sql,$pid=0); retu

  • Java创建、识别条形码和二维码方法示例

    前言 条形码(Barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符.常用于标示物品的生产国.制造厂家.商品名称.生产日期.图书分类号.邮件起止地点.类别.日期等信息,广泛应用于各个领域.常见的包括一维条码(条码).二维条码(二维码).彩色条码,在具体码制上可分为多种不同类型的条码,如UPC(统一产品代码,只能以数字表示).Code 3(能表示字母.数字和其它一些符号共43个字符).Code 128(表示高密度数据,字符串可变长,符号内含校验码).Co

  • TensorFlow高效读取数据的方法示例

    概述 最新上传的mcnn中有完整的数据读写示例,可以参考. 关于Tensorflow读取数据,官网给出了三种方法: 供给数据(Feeding): 在TensorFlow程序运行的每一步, 让Python代码来供给数据. 从文件读取数据: 在TensorFlow图的起始, 让一个输入管线从文件中读取数据. 预加载数据: 在TensorFlow图中定义常量或变量来保存所有数据(仅适用于数据量比较小的情况). 对于数据量较小而言,可能一般选择直接将数据加载进内存,然后再分batch输入网络进行训练(t

  • laravel 5.4中实现无限级分类的方法示例

    前言 本文主要给大家介绍的是关于laravel 5.4中实现无限级分类的相关内容,分享出来供有需要的朋友们参考学习,下面话不多说,来一起看看详细的介绍吧. 方法如下: 1.建立表 php artisan make:migration create_category_table --create=category 在database/migrations/下找到你的迁移文件 建入: <?php use Illuminate\Support\Facades\Schema; use Illuminat

  • python生成tensorflow输入输出的图像格式的方法

    TensorFLow能够识别的图像文件,可以通过numpy,使用tf.Variable或者tf.placeholder加载进tensorflow:也可以通过自带函数(tf.read)读取,当图像文件过多时,一般使用pipeline通过队列的方法进行读取.下面我们介绍两种生成tensorflow的图像格式的方法,供给tensorflow的graph的输入与输出. import cv2 import numpy as np import h5py height = 460 width = 345 w

  • 浅谈keras中自定义二分类任务评价指标metrics的方法以及代码

    对于二分类任务,keras现有的评价指标只有binary_accuracy,即二分类准确率,但是评估模型的性能有时需要一些其他的评价指标,例如精确率,召回率,F1-score等等,因此需要使用keras提供的自定义评价函数功能构建出针对二分类任务的各类评价指标. keras提供的自定义评价函数功能需要以如下两个张量作为输入,并返回一个张量作为输出. y_true:数据集真实值组成的一阶张量. y_pred:数据集输出值组成的一阶张量. tf.round()可对张量四舍五入,因此tf.round(

  • python实现二分类的卡方分箱示例

    解决的问题: 1.实现了二分类的卡方分箱: 2.实现了最大分组限定停止条件,和最小阈值限定停止条件: 问题,还不太清楚,后续补充. 1.自由度k,如何来确定,卡方阈值的自由度为 分箱数-1,显著性水平可以取10%,5%或1% 算法扩展: 1.卡方分箱除了用阈值来做约束条件,还可以进一步的加入分箱数约束,以及最小箱占比,坏人率约束等. 2.需要实现更多分类的卡方分箱算法: 具体代码如下: # -*- coding: utf-8 -*- """ Created on Wed No

  • Pytorch 实现focal_loss 多类别和二分类示例

    我就废话不多说了,直接上代码吧! import numpy as np import torch import torch.nn as nn import torch.nn.functional as F # 支持多分类和二分类 class FocalLoss(nn.Module): """ This is a implementation of Focal Loss with smooth label cross entropy supported which is pro

  • PHP基于phpqrcode类生成二维码的方法示例详解

    HP QR Code是一个PHP二维码生成类库,利用它可以轻松生成二维码,官网提供了下载和多个演示demo,查看地址: http://phpqrcode.sourceforge.net/ 下载官网提供的类库后,只需要使用phpqrcode.php就可以生成二维码了,当然您的PHP环境必须开启支持GD2. phpqrcode.php提供了一个关键的png()方法,其中 参数$text表示生成二位的的信息文本: 参数$outfile表示是否输出二维码图片 文件,默认否: 参数$level表示容错率,

随机推荐