Tensorflow 简单线性规划和逻辑回归

2023-11-16

摘要

线性规划和逻辑回归分别是回归(regression) 和分类 (classification) 问题中最常见的算法之一。许多软件比如 Python, R 等都提供了相关的函数。这里我们介绍如何用 tensorflow 来进行简单的线性规划和逻辑回归。

Tensorflow 中单变量线性回归

假设我们的数据是 ( x i ,   y i ) ,   i = 1 , 2 , ⋯   , m (x_i, \, y_i), \, i = 1, 2, \cdots, m (xi,yi),i=1,2,,m,即一共有 m m m 个数据点。我们须要根据 x i x_i xi 来对 y i y_i yi 进行预测。

在单变量的线性规划模型中,我们须要拟合 y = w x + b y = w x + b y=wx+b。这里 y y y 就是要预测的值, x x x 是我们的feature 值。我们想要用 tensorflow 来根据给出的数据 ( x i ,   y i ) (x_i, \, y_i) (xi,yi) 求解出 w w w b b b 的值。根据最小二乘法的规定,为了求出 w w w b b b,我们须要求出使得
RSS = ∑ i = 1 n ( y i − ( b + w x i ) ) 2 \displaystyle \text{RSS} = \sum_{i = 1}^n \left( y_i - (b + w x_i) \right)^2 RSS=i=1n(yi(b+wxi))2
最小的 w , b w, b w,b

在tensorflow中,我们通过定义损失函数(cost function),来求得使得 RSS (residual sum of squares) 最小的 w , b w, b w,b。具体代码如下。

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior() 
import numpy as np
import matplotlib.pyplot as plt
class demo_tensorflow:
    
    def __init__(self, X, Y):
        self.X = X
        self.Y = Y
        
    def tf_linear_regression(self, learning_rate, training_epoches):
        """
        Use tensorflow for linear regression. 
        """
        # define X and Y. We will fit Y using X.  
        X = tf.placeholder(tf.float32)
        Y = tf.placeholder(tf.float32)
        
        # w and b are the parameters that we need to fit 
        w = tf.Variable(np.random.normal(), name="weights")
        b = tf.Variable(np.random.normal(), name='intercept')
        
        # define the model
        model = tf.add(tf.multiply(X, w), b)
        
        # define the cost function
        cost = tf.reduce_mean(tf.square(model - Y))
        
        train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
        
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            for epoch in range(training_epoches):
                sess.run(train_op, feed_dict={X: self.X, Y: self.Y})
                cur_cost = sess.run(cost, feed_dict={X: self.X, Y: self.Y})
                if (epoch + 1) % 500 == 1:
                    print("Epoch", (epoch + 1), ": cost=", cur_cost)
            weight = sess.run(w)
            intecept = sess.run(b)
        return weight, intecept
x_batch = np.linspace(0, 2, 100) # training x data
y_batch = 1.5 * x_batch + np.random.randn(*x_batch.shape) * 0.2 + 0.5 # training y data
learning_rate = 0.01
training_epoches = 5000
a = demo_tensorflow(x_batch, y_batch)
a.tf_linear_regression(learning_rate, training_epoches)

Epoch 1 : cost= 2.3156583
Epoch 501 : cost= 0.045759827
Epoch 1001 : cost= 0.045451876
Epoch 1501 : cost= 0.04543826
Epoch 2001 : cost= 0.04543766
Epoch 2501 : cost= 0.04543763
Epoch 3001 : cost= 0.045437638
Epoch 3501 : cost= 0.045437627
Epoch 4001 : cost= 0.045437627
Epoch 4501 : cost= 0.045437627

根据训练模型得到的直线如下图所示。

tensorflow_linear_regression

多变量的情况

对于多变量的情况,我们只须要在定义 tf.placeholdertf.Variable 的时候注意矩阵的维度。其余部分是相同的。值得注意的是,我们应该用tf.matmul 来对矩阵进行乘法运算。具体代码如下 [1]。

def tf_multi_linear_regression(self, learning_rate, training_epoches):
        """
        multivariate case for linear regression.
        """
        # m is the number of training data, p is the number of features
        m, p = self.X.shape
        #print(m, p)
        # define X and Y. We will fit Y using X.  
        X = tf.placeholder(tf.float32, shape=(None, p))
        Y = tf.placeholder(tf.float32, shape=(None, 1))
        
        # w and b are the parameters that we need to fit 
        w = tf.Variable(tf.random_normal([p, 1], stddev=0.01), dtype=np.float32, name="weights")
        b = tf.Variable(np.random.normal(), dtype=np.float32, name='intercept')
        # define the model
        model = tf.add(tf.matmul(X, w), b) # Note that we use tf.matmul for matrix multicplication. 
        
        # define the cost function
        cost = tf.reduce_mean(tf.square(model - Y))
        
        train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
        
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            for epoch in range(training_epoches):
                sess.run(train_op, feed_dict={X: np.asarray(self.X), Y: np.asarray(self.Y).reshape(m, 1)})
                cur_cost = sess.run(cost, feed_dict={X: np.asarray(self.X), Y: np.asarray(self.Y).reshape(m, 1)})
                if (epoch + 1) % 500 == 1:
                    print("Epoch", (epoch + 1), ": cost=", cur_cost)
            weight = sess.run(w)
            intecept = sess.run(b)
        return weight, intecept
m = 10 ** 2
x1 = np.linspace(0, 2, m)
x2 = np.linspace(-1, 2, m) + np.random.normal(0, 2, m)
x_multi = np.vstack((x1, x2)).T
y = -2 * x1 + 3 * x2 + 2 + np.random.normal(0, 1, m) * 0.2
a = demo_tensorflow(x_multi, y)
a.tf_multi_linear_regression(learning_rate, training_epoches)

Epoch 1 : cost= 36.237904
Epoch 501 : cost= 0.1619576
Epoch 1001 : cost= 0.03932593
Epoch 1501 : cost= 0.033134725
Epoch 2001 : cost= 0.03282215
Epoch 2501 : cost= 0.032806374
Epoch 3001 : cost= 0.032805584
Epoch 3501 : cost= 0.032805543
Epoch 4001 : cost= 0.032805547
Epoch 4501 : cost= 0.032805547
(array([[-2.016268 ],
[ 3.0005507]], dtype=float32), 2.020361)

用 tensorflow进行逻辑回归分类

有了用tensorflow 进行线性回归的经验之后,对于用罗辑回归(logistic regression) 进行分类,我们只需要定义新的损失函数,而其他大部分代码与线性回归的情况。对于数据 ( x i ,   y i ) ,   i = 1 , 2 , ⋯   , m (x_i, \, y_i), \, i = 1, 2, \cdots, m (xi,yi),i=1,2,,m y i ∈ { 0 ,   1 } y_i \in \{0, \, 1\} yi{0,1}。逻辑回归的损失函数定义为:
cost = − 1 m ∑ i = 1 m ( y i log ⁡ ( y i ^ ) + ( 1 − y i ) log ⁡ ( 1 − y i ^ ) ) \text{cost} = -\frac{1}{m} \sum_{i = 1}^m \left( y_i \log(\hat{y_i}) + (1 - y_i) \log(1 - \hat{y_i}) \right) cost=m1i=1m(yilog(yi^)+(1yi)log(1yi^))

这里 y i ^ \displaystyle \hat{y_i} yi^ 是我们预测数据 x i x_i xi 属于类别 1 的概率。具体的表达式为:
y i ^ = σ ( w x i + b ) \hat{y_i} = \sigma(w x_i + b) yi^=σ(wxi+b)

其中 σ \sigma σ 函数是 sigmoid 函数, σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1 + e^{-x}} σ(x)=1+ex1。可以看出 0 < σ ( x ) < 1 , ∀ x ∈ R 0 < \sigma(x) < 1, \forall x \in \mathbb{R} 0<σ(x)<1,xR,所以 y i ^ \hat{y_i} yi^ 作为概率始终是有意义的。

有了 cost 函数,我们便可以用 tensorflow 中的 optimization 方法进行优化,求出参数 w w w b b b。具体代码如下:

class demo_tf_logisticRegression:
    
    def __init__(self, X, Y):
        self.X = X
        self.Y = Y
    
    
    def tf_logistic_regression(self, learning_rate, training_epoches):
        """
        Train the logistic regression model using tensorflow. 
        """
        # m is the number of training data points, p is the number of features.
        m, p = self.X.shape
        X = tf.placeholder(tf.float32, shape=(None, p))
        Y = tf.placeholder(tf.float32, shape=(None, 1))
        
        w = tf.Variable(tf.random_normal([p, 1]), dtype=tf.float32, name='weights')
        b = tf.Variable(np.random.normal(), dtype=tf.float32, name='bias')
        
        model = tf.sigmoid(tf.add(tf.matmul(X, w), b))
        cost = -tf.reduce_mean(Y * tf.log(model) + (1 - Y) * tf.log(1 - model))
        
        train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
        
        with tf.Session() as sess:
            sess.run(tf.global_variables_initializer())
            for epoch in range(training_epoches):
                sess.run(train_op, feed_dict={X: np.asarray(self.X), Y: np.asarray(self.Y).reshape(m, 1)})
                cur_cost = sess.run(cost, feed_dict={X: np.asarray(self.X), Y: np.asarray(self.Y).reshape(m, 1)})
                if (epoch + 1) % 500 == 1:
                    print("Epoch", (epoch + 1), ": cost=", cur_cost)
            weight = sess.run(w)
            intecept = sess.run(b)
        return weight, intecept
    
    def get_boundary(self, w, b):
        """
        Obtain the classification boundary using the weight and bias that we got from the
        training.
        """
        x_boundary, y_boundary = [], []
        for x in np.linspace(0, 3, 100):
            for y in np.linspace(-1, 5, 100):
                prob = self.sigmoid(w[0] * x + w[1] * y + b)
                if np.abs(prob - 0.5) < 0.01:
                    x_boundary.append(x)
                    y_boundary.append(y)
        return x_boundary, y_boundary
    
    def sigmoid(self, x):
        """
        define the sigmoid function
        """
        return 1 / (1 + np.exp(-x))

假如我们要对下图中的红点(标记为0)和蓝点(标记为1)进行分类。那么我们用逻辑回归得到的分类边界如下图中绿线所示。

# Define the training data
np.random.seed(2)
m = 100
x1 = np.random.uniform(0, 3, m)
y1 = x1 - 1 + np.random.normal(0, 1, m) # with label 0
x2 = np.random.uniform(0, 3, m)
y2 = x2 + 1 + np.random.normal(0, 1, m) # with label 1
x_train_0 = np.vstack((x1, y1))
x_train_1 = np.vstack((x2, y2))
x_train = np.hstack((x_train_0, x_train_1)).T
y_train = np.asarray([0] * m + [1] * m)
# train the logistic model with tensorflow
b = demo_tf_logisticRegression(x_train, y_train)
w, bias = b.tf_logistic_regression(learning_rate, training_epoches)
x_b, y_b = b.get_boundary(w, bias)

Epoch 1 : cost= 1.7830517
Epoch 501 : cost= 0.5220195
Epoch 1001 : cost= 0.44926476
Epoch 1501 : cost= 0.4294767
Epoch 2001 : cost= 0.4218148
Epoch 2501 : cost= 0.41830078
Epoch 3001 : cost= 0.41651848
Epoch 3501 : cost= 0.41554946
Epoch 4001 : cost= 0.41499367
Epoch 4501 : cost= 0.41466048

# plot the data points and the classification boundary
# learned from tensorflow
plt.figure(figsize=(8, 6), dpi=100)
plt.plot(x1, y1, 'o', color='red', markersize=10)
plt.plot(x2, y2, 's', color='blue', markersize=10)
plt.plot(x_b, y_b, '-', color='green', linewidth = 5)
plt.xlabel('x', fontsize = 20)
plt.ylabel('y', fontsize = 20)
plt.xticks(fontsize=20)
plt.yticks(fontsize=20)

tf_logistic_regression

参考文献

[1] Machine learning with tensorflow, Nishant Shukla, Manning Publications, 2017

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Tensorflow 简单线性规划和逻辑回归 的相关文章

随机推荐

  • el-table绑定的数组里面的对象值进行修改时,视图没有更新

    在Vue js中 如果您在对绑定到el table的数组里面的对象值进行修改后发现视图没有更新 可能是因为Vue js无法检测到数据的变化 解决这个问题的方法有以下几种 使用Vue set 方法显式地告诉Vue js数据已经发生了变化 例如
  • GNN等优缺点总结及解决方案

    https www zhihu com question 338051122 https www zhihu com question 346942899 https zhuanlan zhihu com p 291230435 GCN的缺
  • STM32实现MLX90614非接触测温串口显示(标准库与HAL库实现)

    目录 模块选择 编程环境 MLX90614基本原理 通信协议 SMBus通信 类IIC通信 代码实现 STM32与模块之间接线表 1 标准库实现温度采集 2 HAL库实现温度采集 模块选择 STM32F103C8T6 MLX90614 非接
  • 多目标跟踪问题

    A Baseline for 3D Multi Object Tracking 三维多目标跟踪 原文地址 https arxiv org pdf 1907 03961v4 pdf 用到的基础知识 卡尔曼滤波 和 匈牙利算法 匈牙利算法用来求
  • weex<==>nvue书写样式需要注意的点(全部)

    weex书写步骤 全局样式规划 将整个页面分割成合适的模块 flex 布局 排列和对齐页面模块 定位盒子 定位并设置偏移量 细节样式处理 增加特定的具体样式 1 通用样式 除此通用样式之外的属性 均不被支持 1 单位只支持px和wx 不受屏
  • 风起云涌,拓世法宝破茧而出!免费使用无限时长,领航数字人全新时代,你还在等什么?

    随着元宇宙概念的不断推进 数字化转型已经成为了时代的主流趋势 在这个背景下 虚拟数字人的发展迅速崭露头角 为各个行业带来了前所未有的应用机会 尤其是在短视频领域 由于短视频的流量和人力成本持续上升 数字人逐渐被企业视为一个新的探索方向 希望
  • 如何测试Android APP的耗电量?

    现在可以使用google提供的battery historian来测试 适用条件 5 0及以上手机 battery historian链接 google battery historian android吧 所以的android都自带的功能
  • Qt--自定义控件

    写在前面 Qt中提供了应用在各种场景的控件 使开发人员在实际工作中选择 但有些特定的场合中这些控件并不满足需要时 Qt允许使用自定义的控件 例 我们在工作中有这样一种需求 点击按钮会根据一些其他状态来显示不同的图片 这时Qt提供的QPush
  • 阿里巴巴开源的免费数据库工具Chat2DB

    Chat2DB 是一款由阿里巴巴开源的免费数据库工具 它为开发人员提供了一个强大且易于使用的平台 用于存储和查询数据 与传统的数据库工具相比 Chat2DB 具有以下特点和优势 多数据库支持 Chat2DB 可以与多种类型的数据库进行集成
  • GD32 OSC引脚做普通IO配置

    根据用户手册 bit15共同控制了PD0 PD1的重映射的使能 总的来说 比普通IO配置多开启一个复用时钟和重映射使能 rcu periph clock enable RCU GPIOD rcu periph clock enable RC
  • 第1关:Hbase数据库的安装

    在安装HBase之前你需要先安装Hadoop和Zookeeper 如果你还没有安装可以通过这两个实训来学习 Hadoop安装与配置 Zookeeper安装与配置 本次实训的环境已经默认安装好了Hadoop 接下来我们就开始安装配置HBase
  • 500G JAVA视频网盘分享 (Jeecg社区)

    http blog csdn net zhangdaiscott article details 18220411 csdn 排名400多名 500 G JAVA视频网盘分享 Jeecg社区 涵盖从java入门到深入架构 Linux 云计算
  • mermaid 用法

    div class article content tracking ad div class markdown views p 作者 黄永刚 p h2 a target blank a strong mermaid简介 strong h2
  • 11.Linux下Spark的安装配置以及spark-shell的启动和 Spark集群环境搭建

    本案例软件包 链接 https pan baidu com s 1zABhjj2umontXe2CYBW DQ 提取码 1123 若链接失效在下面评论 我会及时更新 目录 1 安装Spark 1 先用xftp将安装包传到home hadoo
  • springBoot整合RabbitMq实现confrim模式回调一直不成功的 坑

    这两天在学习springBoot整合RabbitMq实现confrim模式 网上的demo有很多 但是一直回调不成功 大家的配置大概都是如下图这样 你会发见这个已经废弃了 还有一种你写成这样 又或者你写成这样 没报错 但就是不回调 新版的R
  • 【编程测试题】连续最大和

    题目描述 一个数组有 N 个元素 求连续子数组的最大和 例如 1 2 1 和最大的连续子数组为 2 1 其和为 3 输入描述 输入为两行 第一行一个整数n 1 lt n lt 100000 表示一共有n个元素 第二行为n个数 即每个元素 每
  • 目标检测数据集分析

    原文链接 https ghlcode cn pages 250d97 目标检测数据集分析 新增支持数据集可视化 Ghlerrix DataAnalyze 平时我们经常需要对我们的数据集进行各种分析 以便我们找到更好的提高方式 所以我将我平时
  • ERROR! MySQL server PID file could not be found!解决方案

    首先怀疑是有僵尸mysqld的存在 首先查看进程 ps ef grep mysqld 然后用 kill 9 进程号杀死进程 重启mysql 但是问题并没有得到解决 再然后可以通过mysql的配置文件my cnf查看一下mysql的数据存储目
  • Python + ttkbootstrap 制作全网小说下载神器

    前言 ttkbootstrap是一个基于Python的开源库 用于创建漂亮且交互式的GUI应用程序 它是在Tkinter框架之上构建的 提供了一系列的Widget组件和样式 可以帮助开发者快速构建现代化的用户界面 今天做的是这个东西 蓝色的
  • Tensorflow 简单线性规划和逻辑回归

    Tensorflow 简单线性规划和逻辑回归 摘要 Tensorflow 中单变量线性回归 多变量的情况 用 tensorflow进行逻辑回归分类 参考文献 摘要 线性规划和逻辑回归分别是回归 regression 和分类 classifi