TensorFlow-Course项目教程:使用TensorFlow实现逻辑回归
概述
逻辑回归是机器学习中最基础且重要的分类算法之一。本文基于TensorFlow-Course项目中的逻辑回归教程,将详细介绍如何使用TensorFlow实现一个完整的逻辑回归模型,用于MNIST数据集中数字0和1的二分类任务。
逻辑回归基础
逻辑回归虽然名字中有"回归"二字,但实际上是一种广泛使用的分类算法。与线性回归预测连续值不同,逻辑回归预测的是离散的类别标签。
核心数学原理
逻辑回归的核心在于sigmoid函数:
$$σ(z) = \frac{1}{1+e^{-z}}$$
这个函数将线性组合$z=W^Tx$映射到(0,1)区间,可以解释为样本属于正类的概率:
$$P(y=1|x) = h_W(x) = σ(W^Tx)$$
对应的损失函数(交叉熵损失)为:
$$Loss(W) = -\sum_i [y^{(i)}\log h_W(x^{(i)}) + (1-y^{(i)})\log(1-h_W(x^{(i)}))]$$
实现步骤详解
1. 数据准备
我们从MNIST数据集中提取仅包含数字0和1的样本:
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", reshape=True, one_hot=False)
# 数据处理
data = {}
data['train/image'] = mnist.train.images
data['train/label'] = mnist.train.labels
data['test/image'] = mnist.test.images
data['test/label'] = mnist.test.labels
# 筛选0和1的样本
index_list_train = [i for i, label in enumerate(data['train/label']) if label in [0,1]]
data['train/image'] = data['train/image'][index_list_train]
data['train/label'] = data['train/label'][index_list_train]
index_list_test = [i for i, label in enumerate(data['test/label']) if label in [0,1]]
data['test/image'] = data['test/image'][index_list_test]
data['test/label'] = data['test/label'][index_list_test]
2. 模型构建
在TensorFlow中,我们可以使用全连接层配合softmax来实现逻辑回归:
import tensorflow as tf
# 定义占位符
image_place = tf.placeholder(tf.float32, shape=([None, 784]), name='image')
label_place = tf.placeholder(tf.int32, shape=([None,]), name='gt')
label_one_hot = tf.one_hot(label_place, depth=2, axis=-1)
# 模型结构 - 相当于逻辑回归
logits = tf.contrib.layers.fully_connected(
inputs=image_place,
num_outputs=2,
scope='fc'
)
# 定义损失函数
with tf.name_scope('loss'):
loss = tf.reduce_mean(
tf.nn.softmax_cross_entropy_with_logits(
logits=logits,
labels=label_one_hot
)
)
# 定义准确率计算
with tf.name_scope('accuracy'):
correct_pred = tf.equal(
tf.argmax(logits, 1),
tf.argmax(label_one_hot, 1)
)
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
3. 模型训练
定义优化器和训练操作:
# 定义优化器
optimizer = tf.train.AdamOptimizer(learning_rate=0.001)
train_op = optimizer.minimize(loss)
# 初始化变量
init = tf.global_variables_initializer()
# 开始训练
with tf.Session() as sess:
sess.run(init)
for epoch in range(num_epochs):
# 分批训练
for batch in range(num_batches):
batch_x, batch_y = get_next_batch(data, batch_size)
# 运行训练操作
sess.run(train_op, feed_dict={
image_place: batch_x,
label_place: batch_y
})
# 每个epoch结束后评估模型
train_acc = sess.run(accuracy, feed_dict={
image_place: data['train/image'],
label_place: data['train/label']
})
test_acc = sess.run(accuracy, feed_dict={
image_place: data['test/image'],
label_place: data['test/label']
})
print(f"Epoch {epoch}, Train Acc: {train_acc}, Test Acc: {test_acc}")
关键点解析
-
从线性回归到逻辑回归:
- 线性回归:$y = W^Tx$,直接预测连续值
- 逻辑回归:$P(y=1|x) = σ(W^Tx)$,预测概率值
-
为什么使用交叉熵损失:
- 相比均方误差(MSE),交叉熵损失在分类问题上表现更好
- 当预测值与真实值差距较大时,交叉熵损失能提供更大的梯度
-
softmax与sigmoid的关系:
- 二分类时,softmax与sigmoid等效
- softmax可以自然地扩展到多分类问题
实际应用建议
-
特征工程:
- 逻辑回归对特征缩放敏感,建议对输入特征进行标准化
- 可以考虑添加多项式特征增强模型表达能力
-
正则化:
- 为防止过拟合,可以添加L1或L2正则化
- 在TensorFlow中可通过
tf.contrib.layers.l1_regularizer
实现
-
学习率调整:
- 使用学习率衰减策略可以提高模型性能
- 可尝试
tf.train.exponential_decay
扩展思考
虽然本教程使用softmax实现二分类逻辑回归,但实际上有以下几种实现方式:
-
单输出+sigmoid:
- 输出层只有一个神经元,使用sigmoid激活
- 使用
tf.nn.sigmoid_cross_entropy_with_logits
计算损失
-
双输出+softmax(本教程采用):
- 输出层有两个神经元,使用softmax激活
- 可以自然地扩展到多分类
-
单输出+hinge loss:
- 适用于支持向量机风格的分类器
总结
通过本教程,我们学习了:
- 逻辑回归的基本原理和数学表达
- 如何使用TensorFlow实现逻辑回归模型
- 如何处理MNIST数据集中的二分类问题
- 模型评估和优化的基本方法
逻辑回归虽然简单,但仍然是许多复杂模型的基础。理解其原理和实现方式,对于后续学习更复杂的神经网络模型大有裨益。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考