人工智能中文网
  • 主页
  • 线代考研视频
  • 线性代数
  • Python机器学习与算法
  • 大数据与机器学习
  • Python基础入门教程
  • 人工智能中文网
    教程目录
    阅读:

    softmax回归算法(Softmax Regression算法)详解

    上一章中介绍的 Logistic Regression 算法主要用于处理二分类问题,其类标签 y 取值个数为 2,即 y∈{0,1} 或 y∈{-1,1}。但是存在一类多分类的问题,即类标签 y 的取值个数大于 2,如手写字识别,即识别是 {0,1,…,9} 中的数字,手写字如图 1 所示。


    图 1 手写字识别

    在图 1 中,手写字选自 MNIST 数据集。在 MNIST 手写字识别的数据集中,需要将图 1 中的手写字体划分到 0~9 的 10 个类别中。通常对于这样的多分类问题,可以使用多个二分类算法进行划分,同样,也有一些专门用于处理多分类问题的算法,如 Softmax Regression 算法

    Softmax Regression模型

    Softmax Regression 算法是 Logistic Regression 算法在多分类上的推广,即类标签 y 的取值大于或等于 2。假设有 m 个训练样本{(X(1),y(1) ),(X(2),y(2) ),…,(X(m),y(m))},对于 Softmax Regression 算法,其输入特征为:X(i)∈Rn+1 ,类标记为:y(i)∈{0,1,…,k}。假设函数为每一个样本估计其所属的类别的概率 P(y=jX),具体的假设函数为:


    其中 θ 表示的向量,且 θi∈Rn+1。则对于每一个样本估计其所属的类别的概率为:

    Softmax Regression算法的代价函数

    类似于 Logistic Regression 算法,在 Softmax Regression 算法的损失函数中引入指示函数 I(x),其具体形式为:


    那么,对于 Softmax Regression 算法的损失函数为:


    其中,I{y(i) =j} 表示的是当 y(i) 属于第 j 类时,I{y(i) =j}=1,否则,I{y(i) =j}=0。

    Softmax Regression算法的求解

    对于上述的代价函数,可以使用梯度下降法对其进行求解,首先对其进行求梯度:


    (点击查看高清大图)

    最终的结果为:


    注意,此处的 θj 表示的是一个向量。通过梯度下降法的公式可以更新:


    现在,让我们一起利用 Python 实现上述 Softmax Regression 的更新过程。首先,我们需要导入 numpy:
    import numpy as np
    Softmax Regression 的更新过程的实现函数如下所示:
    def gradientAscent(feature_data, label_data, k, maxCycle, alpha):
        '''利用梯度下降法训练Softmax模型
        input:  feature_data(mat):特征
                label_data(mat):标签
                k(int):类别的个数
                maxCycle(int):最大的迭代次数
                alpha(float):学习率
        output: weights(mat):权重
        '''
        m, n = np.shape(feature_data)
        weights = np.mat(np.ones((n, k)))  # 权重的初始化
        i = 0
        while i <= maxCycle:
            err = np.exp(feature_data * weights)
            if i % 500 == 0:
                print "	-----iter: ", i , ", cost: ", cost(err, label_data)
            rowsum = -err.sum(axis=1)
            rowsum = rowsum.repeat(k, axis=1)
            err = err / rowsum
            for x in range(m):
                err[x, label_data[x, 0]] += 1
            weights = weights + (alpha / m) * feature_data.T * err     
            i += 1          
        return weights
    程序中,梯度更新的函数 gradientAscent 是 Softmax Regression 算法的核心程序,实现了 Softmax Regression 模型中权重的更新。函数 gradientAscent 的输入为训练数据的特征 feature_data,训练数据的标签 label_data,总的类别的个数 k,最大的迭代次数 maxCycle 以及梯度下降法中的学习步长 alpha。函数的输出为 Softmax Regression 的模型权重。函数 cost 用于计算损失函数的值,具体实现如下所示。利用梯度下降法,根据计算的误差更新模型中的权重:
    def cost(err, label_data):
        '''计算损失函数值
        input:  err(mat):exp的值
                label_data(mat):标签的值
        output: sum_cost / m(float):损失函数的值
        '''
        m = np.shape(err)[0]
        sum_cost = 0.0
        for i in xrange(m):
            if err[i, label_data[i, 0]] / np.sum(err[i, :]) > 0:
                sum_cost -= np.log(err[i, label_data[i, 0]] / np.sum(err[i, :]))
            else:
                sum_cost -= 0
        return sum_cost / m
    程序中,函数 cost 用于计算当前的损失函数的值,其输入分别为当前的预测值 err 和样本标签 label_data。