多类逻辑回归训练和测试
简介本文将介绍多类逻辑分类器的训练与测试。逻辑回归是一种概率性的线性分类器。它由权重矩阵 $W$ 和偏置向量 $b$ 参数化。分类是通过将数据点投影到一组超平面上来实现的,超平面到数据点的距离用于确定类成员概率。
引言
本文将介绍多类逻辑分类器的训练与测试。
- 逻辑回归是一种概率性的线性分类器。它由权重矩阵 \(W\) 和偏置向量 \(b\) 参数化。分类是通过将数据点投影到一组超平面上来实现的,超平面到数据点的距离用于确定类成员概率。
- 数学上可以表示为:\begin{eqnarray*} & P(Y=i|x, W,b) =\frac {e^{W_i x + b_i}}{\sum_j e^{W_j x + b_j}} \\ \end{eqnarray*}
- 与每个类 \(y_i\) 对应,逻辑分类器由一组参数 \(W_i,b_i\) 参数化。
- 这些参数用于计算类概率。
- 给定一个未知向量 x,预测过程如下:\begin{eqnarray*} & y_{pred} = argmax_i P(Y=i|x,W,b) \\ & y_{pred} = argmax_i \frac {e^{W_i x + b_i}}{\sum_j e^{W_j x + b_j}} \end{eqnarray*}
- 给定一组带标签的训练数据 \({X_i,Y_i}\),其中 \(i\) 在 \({1,\ldots,N}\) 中,我们需要估计这些参数。
损失函数
- 理想情况下,我们希望计算参数以最小化 \(0-1\) 损失:\begin{eqnarray*} & \ell_{0,1} = \sum_{i=0}^{|\mathcal{D}|} I_{f(x^{(i)}) \neq y^{(i)}} \\ & f(x)= argmax_k P(Y=y_k |x,\theta) \end{eqnarray*}
- \(P(Y=y_k |x,\theta)\) 使用逻辑函数进行建模。
- \(0-1\) 损失函数不可微分,因此对于大型模型进行优化在计算上是不可行的。
- 相反,我们最大化分类器在给定训练数据 \(\mathcal{D}\) 时的对数似然。
- 最大似然估计用于执行此操作。
- 估计参数,使得模型参数下的训练数据 \(\mathcal{D} \) 的似然性最大化。
- 假设数据样本是独立的,因此集合的概率是个别样本概率的乘积。\begin{eqnarray*} & L(\theta={W,b},\mathcal{D}) =argmax \prod_{i=1}^N P(Y=y_i | X=x_i,W,b) \\ & L(\theta,\mathcal{D}) = argmax \sum_{i=1}^N log P(Y=y_i | X=x_i,W,b) \\ & L(\theta,\mathcal{D}) = - argmin \sum_{i=1}^N log P(Y=y_i | X=x_i,W,b) \\ \end{eqnarray*}
- 需要注意的是,正确类的似然性与正确预测的数量不同。
- 对数似然函数可以看作是 \(0-1\) 损失函数的微分版本。
- 在当前应用中,负对数似然用作损失函数。
- 通过最小化损失函数来学习最优参数。
- 在当前应用中,使用基于梯度的下降方法进行最小化。
- 具体来说,使用随机梯度下降和共轭梯度下降来最小化损失函数。
- 成本函数表示为:\begin{eqnarray*} & L(\theta,\mathcal{D}) = - \sum_{i=1}^N log P(Y=y_i | X=x_i,W,b) \\ & L(\theta,\mathcal{D}) = - \sum_{i=1}^N log \frac {e^{W_i x + b_i}}{\sum_j e^{W_j x + b_j}} \\ & L(\theta,\mathcal{D}) = - \sum_{i=1}^N log {e^{W_i x + b_i}}- log {\sum_j e^{W_j x + b_j}} \\ & L(\theta,\mathcal{D}) = - \sum_{i=1}^N {W_i x + b_i} + log \frac{1}{\sum_j e^{W_j x + b_j}} \\ \end{eqnarray*}
- 求和的第一部分是仿射的,第二部分是对指数之和的对数,这是凸的。因此,损失函数是凸的。
- 因此,我们可以使用梯度下降方法计算损失函数的全局最大值对应的参数。
- 因此,我们计算损失函数 \(L(\theta,\mathcal{D})\) 相对于 \(\theta,\partial{\ell}/\partial{W}\) 和 \(\partial{\ell}/\partial{b}\) 的导数。
Theano
- Theano 是一个 Python 库,允许您高效地定义、优化和评估涉及多维数组的数学表达式。
- 它是一个表达式编译器,可以在执行时评估符号表达式。通常,用 C/C++ 实现的程序可以用 Theano 简洁高效地编写。
- 在大多数编程语言(C/C++、Matlab、Python)中计算梯度需要手动推导出损失函数相对于参数 \(\partial{\ell}\partial{W}\) 和 \(\partial{\ell}/\partial{b}\) 的梯度表达式。
- 这种方法不仅涉及手动编码,而且对于复杂的模型,导数可能难以计算。
- 使用 Theano,由于它执行自动微分,这项工作大大简化了。
示例
- 为了演示,我们将使用 MNIST 数据集。MNIST 数据集包含手写数字图像,分为 60,000 个训练样本和 10,000 个测试样本。官方的 60,000 个训练集被分为 50,000 个实际训练样本和 10,000 个验证样本。所有数字图像都经过尺寸归一化并居中在一个固定大小为 28 x 28 像素的图像中。在原始数据集中,图像的每个像素由 0 到 255 之间的值表示,其中 0 是黑色,255 是白色,两者之间的任何值都是不同深浅的灰色。
- 数据集可在 http://deeplearning.net/data/mnist/mnist.pkl.gz 找到。
- 数据集是 pickle 格式的,可以使用 Python 的 pickle 包加载。
- 数据集包含训练集、验证集和测试集。
- 数据集由长度为 \((28x28=784)\) 的特征向量组成,类别数为 10。
- 定义了一个名为 Logistic Regression 的类,它封装了用于执行多类逻辑回归分类器训练和测试的方法。
Theano 代码
- 训练和测试的 Python 代码可以在 git 仓库 https://github.com/pi19404/OpenVision 中的 ImgML/LogisticRegression.py 文件中找到。
- ImgML/load_datasets.py 包含从 pickle 文件或 SVM 格式文件加载数据集的方法。
""" symbolic expressions defining input and output vectors""" x=T.matrix('x'); y=T.ivector('y'); """ The mnist dataset in pickel format""" model_name1="/media/LENOVO_/repo/mnist.pkl.gz" """ creating object of class Logistic regression""" """ input is 28*28 dimension feature vector ,and output lables are digits from 0-9 """ classifier = LogisticRegression(x,y,28*28,10); """ loading the datasets""" [train,test,validate]=load_datasets.load_pickle_data(model_name1); """ setting the dataset""" classifier.set_datasets(train,test,validate); # #classifier.init_classifier(model_name1);n_out """ Training the classifiers""" classifier.train_classifier(0.13,1000,30); """ Saving the model """ classifier.save('1'); #x=classifier.train[0].get_value(borrow=True)[0]; #classifier.predict(x); """ Loading the model""" classifier.load('1') x=train[0].get_value(borrow=True); y=train[1].eval(); print 'True class:'+`y` xx,yy=classifier.predict(x); print 'Predicted class:' + `yy` classifier.testing();
- 还使用 Eigen/OpenCV 编写了 C/C++ 代码,并将其合并到 OpenVision 库中。可以在文件 https://github.com/pi19404/OpenVision 中的 ImgML/LogisticRegression.cpp 和 ImgML/LogisticRegression.hpp 中找到。