python识别手写数字_不用框架,Python识别手写数字

有一句话说得好,要有造轮子的技术和用轮子的觉悟

近年来人工智能火的不行,大家都争相学习机器学习,作为学习大军中的一员,我觉得最好的学习方法就是用python把机器学习算法实现一遍,下面我介绍一下用逻辑回归实现手写数字的识别。

逻辑回归知识点回顾

​ 线性回归简单又易用

,可以进行值的预测,但是不擅长分类。在此基础上进行延伸,把预测的结果和概率结合起来就可以做分类器了,比如预测值大于0.5,则归为1类,否则就归为0类,这个就是逻辑回归算法了。逻辑回归主要解决的就是二分类问题,比如判断图片上是否一只猫,邮件是否垃圾邮件等。

​ 由于逻辑回归的结果是概率值,为0-1之间,因此需要在线性回归的结果上增加一次运算,使得最后的预测结果在0到1之间。

​ Sigmoid函数,表达式为:

sigmoid函数

​ sigmoid的输出在0和1之间,我们在二分类任务中,采用sigmoid的输出的是事件概率,也就是当输出满足满足某一概率条件我们将其划分正类。结合了sigmoid函数,把线性回归的结果概率化,即映射到(0,1)区间上,得到预测函数为

。当概率大于0.5时为1类,否则判定位0类。逻辑回归的得到的概率是线性回归的结果通过sigmoid函数映射到(0,1)区间上

​ 接下来我们开始使用逻辑回归进行手写数字的识别!

读入手写数字数据并进行预览

​ 此次使用的是5000条手写数字的数据。一条训练数据是20px*20px图片的数据,每一个像素点是代表灰度值。我们查看一下前100条手写数据,如下图:前100条手写数据

定义向量化的预测函数

首先我们定义预测函数

,k是参数的个数。

写成向量化的形式为:

,g(z)是激活函数(sigmoid function)

def h(mytheta,myX):

return expit(np.dot(myX, mytheta))

预测函数中$\theta$的值是未知的,接下来的任务就是要根据训练集,求解出θ的值。

计算代价函数(Cost Function)

在线性回归中的最小二乘法,求解参数θ就是最小化残差平方和,也就是代价函数J(θ)。代价函数J(θ)是度量预测错误的程度,逻辑回归的代价函数为对数似然函数,

等价于:

def computeCost(mytheta,myX,myy):

m = len(X) #5000

term1 = np.dot(-np.array(myy).T,np.log(h(mytheta,myX)))#shape(1,401)

term2 = np.dot((1-np.array(myy)).T,np.log(1-h(mytheta,myX)))#shape(1,401)

return float((1./m) * np.sum(term1 - term2) )

使得预测错误的程度最低,即使得J(θ)最小,此时我们把问题转为最优化问题。

下面介绍一种求解最优化的算法:梯度下降。从初始位置每次向梯度方向(就是下降速度最快的方向)迈一小步,一直走到最低点。想象你在下山,你朝着当前位置下降最快的方向走一步。梯度下降

计算梯度

经过数学运算可以得出

def costGradient(mytheta,myX,myy):

m = myX.shape[0]

beta = h(mytheta,myX)-myy.T #shape: (5000,1)

grad = (1./m)*np.dot(myX.T,beta) #shape: (401, 5000)

return grad #shape: (401, 1)

最小化

求解

这里我们使用的是高级算法,scipy中的optimize,求解最小化J(θ)时θ的值。

from scipy import optimize

def optimizeTheta(mytheta,myX,myy):

result = optimize.fmin_cg(computeCost, fprime=costGradient, x0=mytheta, \

args=(myX, myy), maxiter=50, disp=False,\

full_output=True)

return result[0], result[1]

One-VS-All多分类

逻辑回归擅长二分类问题,因此需要把多分类问题转换为多个二分类问题进行解决。如下图,首先把蓝色和绿色标记看为一类,红色记为一类,这样子就可以用预测函数

计算出新数据为红色类别的概率,同理也可以计算出新数据为蓝色、绿色类别的概率,选择概率最高的类别作为新数据的预测分类,这就是One-VS-All多分类算法。多分类问题转为多个二分类问题

def predictOneVsAll(myTheta,myrow):

classes = [10] + list(range(1,10))

hypots = [0]*len(classes)

for i in range(len(classes)):

hypots[i] = h(myTheta[:,i],myrow)

return classes[np.argmax(np.array(hypots))]

预测并计算准确率

计算测试集得到逻辑回归预测的准确度为 89.1%。抽看第1601个数据观察预测情况

predictOneVsAll(Theta,X[1600])

#3

scipy.misc.toimage(X[1600][1:].reshape(20,20).T)第1601个数据

逻辑回归的预测准确率是89.1%,那么以逻辑回归作为神经元的神经网络算法,是否会更加强大呢,我们下期见!

你可能感兴趣的:(python识别手写数字)