首页
/ DeepLearningTutorials中的逻辑回归模型详解:MNIST手写数字分类

DeepLearningTutorials中的逻辑回归模型详解:MNIST手写数字分类

2025-07-09 01:21:12作者:贡沫苏Truman

前言

逻辑回归是机器学习中最基础但非常重要的分类算法之一。本文将基于深度学习教程项目中的实现,详细介绍如何使用Theano框架构建逻辑回归模型,并在MNIST手写数字数据集上进行分类任务。

逻辑回归模型概述

逻辑回归是一种概率型的线性分类器,通过将输入向量投影到一组超平面上进行分类。每个超平面对应一个类别,输入到超平面的距离反映了输入属于该类的概率。

数学表达

给定输入向量x,属于类别i的概率可以表示为:

P(Y=i|x, W,b) = softmaxᵢ(Wx + b) = e^{Wᵢx + bᵢ} / ∑ⱼ e^{Wⱼx + bⱼ}

其中:

  • W是权重矩阵
  • b是偏置向量
  • softmax函数将线性输出转换为概率分布

模型的预测y_pred是概率最大的类别: y_pred = argmaxᵢ P(Y=i|x,W,b)

Theano实现详解

1. 模型构建

在Theano中,我们首先定义共享变量来表示模型的参数W和b:

# 初始化权重矩阵W
W = theano.shared(
    value=numpy.zeros((n_in, n_out), dtype=theano.config.floatX),
    name='W',
    borrow=True
)

# 初始化偏置向量b
b = theano.shared(
    value=numpy.zeros((n_out,), dtype=theano.config.floatX),
    name='b',
    borrow=True
)

然后计算类别概率分布:

# 计算线性输出
linear_output = T.dot(input, W) + b

# 应用softmax得到概率分布
p_y_given_x = T.nnet.softmax(linear_output)

预测类别则是概率最大的索引:

y_pred = T.argmax(p_y_given_x, axis=1)

2. 损失函数定义

在训练模型时,我们需要定义一个损失函数来评估模型性能。对于多类逻辑回归,通常使用负对数似然作为损失函数:

def negative_log_likelihood(self, y):
    return -T.mean(T.log(self.p_y_given_x)[T.arange(y.shape[0]), y])

这里使用均值而非总和,使得学习率的选择对批量大小不那么敏感。

3. 模型训练

使用随机梯度下降(SGD)进行优化,计算梯度并更新参数:

# 计算梯度
g_W = T.grad(cost=cost, wrt=classifier.W)
g_b = T.grad(cost=cost, wrt=classifier.b)

# 定义更新规则
updates = [(classifier.W, classifier.W - learning_rate * g_W),
           (classifier.b, classifier.b - learning_rate * g_b)]

# 编译训练函数
train_model = theano.function(
    inputs=[index],
    outputs=cost,
    updates=updates,
    givens={
        x: train_set_x[index * batch_size:(index + 1) * batch_size],
        y: train_set_y[index * batch_size:(index + 1) * batch_size]
    }
)

4. 模型评估

为了评估模型性能,我们定义错误率计算函数:

def errors(self, y):
    # 检查预测是否正确
    return T.mean(T.neq(self.y_pred, y))

然后编译测试和验证函数:

# 验证函数
validate_model = theano.function(
    inputs=[index],
    outputs=classifier.errors(y),
    givens={
        x: valid_set_x[index * batch_size:(index + 1) * batch_size],
        y: valid_set_y[index * batch_size:(index + 1) * batch_size]
    }
)

# 测试函数
test_model = theano.function(
    inputs=[index],
    outputs=classifier.errors(y),
    givens={
        x: test_set_x[index * batch_size:(index + 1) * batch_size],
        y: test_set_y[index * batch_size:(index + 1) * batch_size]
    }
)

训练流程

完整的训练流程包括:

  1. 加载MNIST数据集
  2. 构建逻辑回归模型
  3. 定义训练、验证和测试函数
  4. 实施早期停止策略
  5. 迭代训练模型

典型的训练输出如下:

epoch 72, minibatch 83/83, validation error 7.510417 %
epoch 72, minibatch 83/83, test error of best model 7.510417 %
epoch 73, minibatch 83/83, validation error 7.500000 %
epoch 73, minibatch 83/83, test error of best model 7.489583 %
Optimization complete with best validation score of 7.500000 %,with test performance 7.489583 %
The code run for 74 epochs, with 1.936983 epochs/sec

模型预测

训练完成后,我们可以使用训练好的模型进行预测:

def predict():
    # 加载保存的模型
    classifier = pickle.load(open('best_model.pkl'))
    
    # 编译预测函数
    predict_model = theano.function(
        inputs=[classifier.input],
        outputs=classifier.y_pred
    )
    
    # 对新数据进行预测
    predicted_values = predict_model(test_set_x[:10])
    print("Predicted values for the first 10 examples in test set:")
    print(predicted_values)

性能优化

在实际应用中,我们可以通过以下方式优化模型性能:

  1. 批量大小调整:不同的批量大小会影响训练速度和模型性能
  2. 学习率调整:适当的学习率对收敛至关重要
  3. GPU加速:使用GPU可以显著提高训练速度
  4. 更高级的优化算法:如共轭梯度法等

总结

本文详细介绍了如何使用Theano实现逻辑回归模型进行MNIST手写数字分类。通过构建概率模型、定义损失函数、实施梯度下降优化以及模型评估,我们完成了一个完整的机器学习流程。逻辑回归虽然简单,但作为深度学习的基础,理解其原理和实现对于后续学习更复杂的模型至关重要。