机器学习源码分析-逻辑回归

现在网上已经有很多高质量的关于机器学习算法理论的文章,但只有理论部分很难让人理解透彻,软件人对代码更熟悉,接下来我就从源码的角度去介绍各种机器学习算法,理论部分这里不做重点介绍,今天来分析一下逻辑回归。
逻辑回归是用于解决二分类问题的机器学习方法,其数学表达式如下:
图片

图片

其中x是输入,可以是标量也可能是多个维度的向量,w和b是我们要求的参数,其中g称为激活函数,能将输入映射到0-1范围内,表示样本属于正例概率。
机器学习源码分析-逻辑回归_第1张图片

机器学习源码分析-逻辑回归_第2张图片

如上图,对于输入特征是二维的,逻辑回归就是找到正负样本的分解线,特征维度超过2维时,就是找到一个分界面,同理,一维数据,就是找一个分界点。
源码分析,那首先就要找到实现算法的开源库,一提到机器学习库,应用最为广泛的莫过于scikit-learn,其实OpenCV中的ml模块也提供了对于机器学习算法的实现,所有机器学习库都是依据相同的数学原理来实现的,只是使用的语言不同而已,为了调试方便,我最终决定使用OpenCV。
接下来我们看OpenCV中一个逻辑回归的例子:手写数字分类
训练数据:
训练数据包含20幅只包含0或者1手写数字的图像,图像大小2828,展开成向量的形式:1784,逻辑回归分类器就是在784维度空间找一个分界面将数字0和数字1尽量分开,而这个分界面是由w和b来确定,输出大于一定阈值(默认0.5)代表该图像上的数字是1,否则代表该图像上的数字是0。
该训练数据保存成了xml格式:
图像:
机器学习源码分析-逻辑回归_第3张图片

标签:
图片

通过Opencv FileStorage类将图像和标签读取到Mat中。

Mat data, labels;
FileStorage f;
if(f.open(filename, FileStorage::READ))
{
   
f["datamat"] >> data;
f["labelsmat"] >> labels;
f.release();
}

读取完成后data是20784维,labels是201维。
将训练数据20幅小图像打印到一个大图像上:
图片

设置参数:

Ptr<LogisticRegression> lr1 = LogisticRegression::create();
lr1->setLearningRate(0.001);学习率
lr1->setIterations(10);训练迭代轮数
lr1->setRegularization(LogisticRegression::REG_L2);L2正则化
lr1->setTrainMethod(LogisticRegression::BATCH);批梯度下降

训练:
lr1->train(data_train, ROW_SAMPLE, labels_train);
接下来我们看看训练过程中都干了什么:
根据逻辑回归的数学表达式,前向计算第一步就是要计算上面的公式,输入x是784维向量,所以w也是784维, b是一维标量,通常为了计算效率,可以将上面的公式转换成矩阵的运算:
机器学习源码分析-逻辑回归_第4张图片

上面我们设置的训练方法为BATCH方式,也就是说每一次梯度更新要用到所有的训练数据,那所有训练数据作为输入转换成矩阵的运算表达式为:
机器学习源码分析-逻辑回归_第5张图片

其中X矩阵水平方向为特征维度,垂直方向为训练数据个数,矩阵乘法的输出120,代表20个训练数据wx+b的结果,Opencv中代码如下:
将输入矩阵加一列,且值都是1,也就是构造上图右边的20
785维的X矩阵。

Mat data_t;
hconcat( cv::Mat::ones( _data_i.rows, 1, CV_32F ), _data_i, data_t );
接下来构造上图左边w和b组成的矩阵,1*785维:
Mat thetas;
Mat init_theta = Mat::zeros(data_t.cols, 1

你可能感兴趣的:(机器学习,逻辑回归,人工智能)