TensorFlow实践(7)——逻辑回归模型

(一)前 言

首先,我们要明确一点,逻辑回归与线性回归类似,但它不属于回归分析算法家族,而是一种分类算法,主要应用在二分类任务中。在线性回归中,特征都表示为一个列向量,而在逻辑回归中,特别是涉及到二维图像的分类,特征则表示为一个矩阵。逻辑回归的训练目标也是去学习权重和偏置值,然后对目标进行分类。我们通过训练最终要学的就是图中的权重值和偏置值。
TensorFlow实践(7)——逻辑回归模型
其中y1,y2,y3为三个类别,通俗的说就是针对每一个类别我们都得到了一个线性回归模型,而当一个数据实例输入时,会得到三个模型值,然后将这三个模型值送入softmax函数,得到三个概率值,哪一个值大,则该实例被分为哪类,softmax的函数式如下所示:
TensorFlow实践(7)——逻辑回归模型
即样本为类别i的概率,而在逻辑回归中,我们采用交叉熵做为损失函数,公式如下:
TensorFlow实践(7)——逻辑回归模型

(二)实例应用——肾癌细胞的转移判断

(本实例来自《TensorFlow深度学习应用实践》,王晓华著)

(1)问题描述

某研究人员在探讨肾细胞癌转移的有关临床病理因素研究中,收集了一批根治性肾切除术患者的肾癌标本资料,现从中抽取26例资料作为示例进行逻辑回归分析,数据说明如下:

  • Y:肾细胞转移情况(有转移Y=1,无转移Y=0)
  • X1:确诊时患者的年龄
  • X2:肾细胞癌血管内皮生长因子,其阳性表述由低到高共3个等级
  • X3:肾细胞癌组织内微血管数
  • X4:肾癌细胞核组织学分级,由低到高共4级
  • X5:肾细胞癌分期,由低到高共4期

(2)数据展示

对数据进行标准化处理后,进行可视化:
TensorFlow实践(7)——逻辑回归模型
绘图代码如下:

import csv
import numpy as np
import matplotlib.pyplot as plt
with open('D:/Machine Learning/research data/肾癌转移数据集/肾癌转移训练集.csv') as file:
    reader = csv.reader(file)
    a, b = [], []
    for item in reader:
        b.append([item[0],item[1]])
        del(item[0],item[1])
        a.append(item)
    file.close()
x_data = np.array(a)
y_data = np.array(b)
plt.figure(figsize = (10, 6))
for i in range(24):
    point = a[i]
    plt.plot(point)
plt.xticks(np.arange(5), ('X1','X2','X3','X4','X5'),fontsize = 13)
plt.grid(True)
plt.show()

(三)逻辑回归的TensorFlow实现

(1)模型参数设置

# 设置学习率
learning_rate = 0.01
# 设置训练次数
train_steps = 1000

(2)输入数据

with open('D:/Machine Learning/research data/肾癌转移数据集/肾癌转移训练集.csv') as file:
    reader = csv.reader(file)
    a, b = [], []
    for item in reader:
        b.append([item[0],item[1]])
        del(item[0],item[1])
        a.append(item)
    file.close()
x_data = np.array(a)
y_data = np.array(b)

(3)构建模型

weight = tf.Variable(np.random.rand(5, 2).astype(np.float32))
bias = tf.Variable(np.random.rand(1, 2).astype(np.float32))
x_ = tf.placeholder(tf.float32, [None, 5])
y_ = tf.placeholder(tf.float32, [None, 2])
y_model = tf.nn.softmax(tf.matmul(x_, weight) + bias)

(4)定义损失函数

# 采用交叉熵做为损失函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels = y_model, logits = y_))

(5)选择优化器及定义训练操作

# 使用随机梯度下降算法
train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)

(6)创建会话进行训练

with tf.Session() as sess:
# 数据初始化
    sess.run(tf.global_variables_initializer())
# 开始训练
    print("Start training!")
    lo = []
    sample = np.arange(1000)
# 训练1000次
    for i in range(train_steps):
        for (x,y) in zip(x_data, y_data):
            z1 = x.reshape(1, 5)
            z2 = y.reshape(1, 2)
            sess.run(train_op, feed_dict = {x_ : z1, y_ : z2})
        l = sess.run(loss, feed_dict = {x_ : z1, y_ : z2}) 
        lo.append(l)
    print(weight.eval(sess))
    print(bias.eval(sess))

(7)训练结果

在学习率为0.01时,循环训练5000次,训练损失降至0.3153329,由于训练数据量较少,故此精度在可接受范围内,以下为训练损失变化图:
TensorFlow实践(7)——逻辑回归模型

(8)完整代码

import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
import csv
# 设置学习率
learning_rate = 0.01
# 设置训练次数
train_steps = 5000
with open('D:/Machine Learning/research data/肾癌转移数据集/肾癌转移训练集.csv') as file:
    reader = csv.reader(file)
    a, b = [], []
    for item in reader:
        b.append([item[0],item[1]])
        del(item[0],item[1])
        a.append(item)
    file.close()
x_data = np.array(a)
y_data = np.array(b)
weight = tf.Variable(np.random.rand(5, 2).astype(np.float32))
bias = tf.Variable(np.random.rand(1, 2).astype(np.float32))
x_ = tf.placeholder(tf.float32, [None, 5])
y_ = tf.placeholder(tf.float32, [None, 2])
y_model = tf.nn.softmax(tf.matmul(x_, weight) + bias)
# 采用交叉熵做为损失函数
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(labels = y_model, logits = y_))
# 使用随机梯度下降算法
train_op = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)
with tf.Session() as sess:
# 数据初始化
    sess.run(tf.global_variables_initializer()) # 开始训练
    print("Start training!")
    lo = []
    sample = np.arange(train_steps) # 训练train_steps次
    for i in range(train_steps):
        for (x,y) in zip(x_data, y_data):
            z1 = x.reshape(1, 5)
            z2 = y.reshape(1, 2)
            sess.run(train_op, feed_dict = {x_ : z1, y_ : z2})
        l = sess.run(loss, feed_dict = {x_ : z1, y_ : z2})
        lo.append(l)
    print(weight.eval(sess))
    print(bias.eval(sess))
# 绘制训练损失变化图
    plt.plot(sample, lo, marker="*", linewidth=1, linestyle="--", color="red")
    plt.title("The variation of the loss")
    plt.xlabel("Sampling Point")
    plt.ylabel("Loss")
    plt.grid(True)
    plt.show()

(四)结 论

本文基于逻辑回归模型,通过对24个根治性肾切除术患者的肾癌标本数据进行学习,建立了肾癌细胞转移判断模型,读者若想进一步提高精度,可通过增加训练数据量、改变学习率、增加训练次数等方式实现,读者若遇到其他可通过回归模型解决的问题时,可仿照上述过程进行,有任何疑问请在评论区留言,我会尽快回复,谢谢支持!
下一节:TensorFlow应用(8)——利用优化器寻找函数最小值