如何利用Python做简单的验证码识别

Python017

如何利用Python做简单的验证码识别,第1张

先是获取验证码样本。。。我存了大概500个。

用dia测了测每个字之间的间距,直接用PIL开始切。

from PIL import Image

for j in range(0,500):

f=Image.open("../test{}.jpg".format(j))

for i in range(0,4):

f.crop((20+20*i,0,40+20*i,40)).save("test{0}-{1}.jpg".format(j,i+1))

上面一段脚本的意思是把jpg切成四个小块然后保存

之后就是二值化啦。

def TotallyShit(im):

x,y=im.size

mmltilist=list()

for i in range(x):

for j in range(y):

if im.getpixel((i,j))<200:

mmltilist.append(1)

else:

mmltilist.append(0)

return mmltilist

咳咳,不要在意函数的名字。上面的一段代码的意思是遍历图片的每个像素点,颜色数值小于200的用1表示,其他的用0表示。

其中的im代表的是Image.open()类型。

切好的图片长这样的。

只能说这样切的图片还是很粗糙,很僵硬。

下面就是分类啦。

把0-9,“+”,”-“的图片挑好并放在不同的文件夹里面,这里就是纯体力活了。

再之后就是模型建立了。

这里我试了自己写的还有sklearn svm和sklearn neural_network。发现最后一个的识别正确率高的多。不知道是不是我样本问题QAQ。

下面是模型建立的代码

from sklearn.neural_network import MLPClassifier

import numpy as np

def clf():

clf=MLPClassifier()

mmltilist=list()

X=list()

for i in range(0,12):

for j in os.listdir("douplings/douplings-{}".format(i)):

mmltilist.append(TotallyShit(Image.open("douplings/douplings-{0}/{1}".format(i,j)).convert("L")))

X.append(i)

clf.fit(mmltilist,X)

return clf

大概的意思是从图片源中读取图片和label然后放到模型中去跑吧。

之后便是图像匹配啦。

def get_captcha(self):

with open("test.jpg","wb") as f:

f.write(self.session.get(self.live_captcha_url).content)

gim=Image.open("test.jpg").convert("L")

recognize_list=list()

for i in range(0,4):

part=TotallyShit(gim.crop((20+20*i,0,40+20*i,40)))

np_part_array=np.array(part).reshape(1,-1)

predict_num=int(self.clf.predict(np_part_array)[0])

if predict_num==11:

recognize_list.append("+")

elif predict_num==10:

recognize_list.append("-")

else:

recognize_list.append(str(predict_num))

return ''.join(recognize_list)

最后eval一下识别出来的字符串就得出结果了。。

顺便提一句现在的bilibili登陆改成rsa加密了,麻蛋,以前的脚本全部作废,心好痛。

登陆的代码。

import time

import requests

import rsa

r=requests.session()

data=r.get("act=getkey&_="+str(int(time.time()*1000))).json()

pub_key=rsa.PublicKey.load_pkcs1_openssl_pem(data['key'])

payload = {

'keep': 1,

'captcha': '',

'userid': "youruserid",

'pwd': b64encode(rsa.encrypt((data['hash'] +"yourpassword").encode(), pub_key)).decode(),

}

r.post("",data=payload)

上周末利用python简单实现了一个卷积神经网络,只包含一个卷积层和一个maxpooling层,pooling层后面的多层神经网络采用了softmax形式的输出。实验输入仍然采用MNIST图像使用10个feature map时,卷积和pooling的结果分别如下所示。

部分源码如下:

[python] view plain copy

#coding=utf-8

'''''

Created on 2014年11月30日

@author: Wangliaofan

'''

import numpy

import struct

import matplotlib.pyplot as plt

import math

import random

import copy

#test

from BasicMultilayerNeuralNetwork import BMNN2

def sigmoid(inX):

if 1.0+numpy.exp(-inX)== 0.0:

return 999999999.999999999

return 1.0/(1.0+numpy.exp(-inX))

def difsigmoid(inX):

return sigmoid(inX)*(1.0-sigmoid(inX))

def tangenth(inX):

return (1.0*math.exp(inX)-1.0*math.exp(-inX))/(1.0*math.exp(inX)+1.0*math.exp(-inX))

def cnn_conv(in_image, filter_map,B,type_func='sigmoid'):

#in_image[num,feature map,row,col]=>in_image[Irow,Icol]

#features map[k filter,row,col]

#type_func['sigmoid','tangenth']

#out_feature[k filter,Irow-row+1,Icol-col+1]

shape_image=numpy.shape(in_image)#[row,col]

#print "shape_image",shape_image

shape_filter=numpy.shape(filter_map)#[k filter,row,col]

if shape_filter[1]>shape_image[0] or shape_filter[2]>shape_image[1]:

raise Exception

shape_out=(shape_filter[0],shape_image[0]-shape_filter[1]+1,shape_image[1]-shape_filter[2]+1)

out_feature=numpy.zeros(shape_out)

k,m,n=numpy.shape(out_feature)

for k_idx in range(0,k):

#rotate 180 to calculate conv

c_filter=numpy.rot90(filter_map[k_idx,:,:], 2)

for r_idx in range(0,m):

for c_idx in range(0,n):

#conv_temp=numpy.zeros((shape_filter[1],shape_filter[2]))

conv_temp=numpy.dot(in_image[r_idx:r_idx+shape_filter[1],c_idx:c_idx+shape_filter[2]],c_filter)

sum_temp=numpy.sum(conv_temp)

if type_func=='sigmoid':

out_feature[k_idx,r_idx,c_idx]=sigmoid(sum_temp+B[k_idx])

elif type_func=='tangenth':

out_feature[k_idx,r_idx,c_idx]=tangenth(sum_temp+B[k_idx])

else:

raise Exception

return out_feature

def cnn_maxpooling(out_feature,pooling_size=2,type_pooling="max"):

k,row,col=numpy.shape(out_feature)

max_index_Matirx=numpy.zeros((k,row,col))

out_row=int(numpy.floor(row/pooling_size))

out_col=int(numpy.floor(col/pooling_size))

out_pooling=numpy.zeros((k,out_row,out_col))

for k_idx in range(0,k):

for r_idx in range(0,out_row):

for c_idx in range(0,out_col):

temp_matrix=out_feature[k_idx,pooling_size*r_idx:pooling_size*r_idx+pooling_size,pooling_size*c_idx:pooling_size*c_idx+pooling_size]

out_pooling[k_idx,r_idx,c_idx]=numpy.amax(temp_matrix)

max_index=numpy.argmax(temp_matrix)

#print max_index

#print max_index/pooling_size,max_index%pooling_size

max_index_Matirx[k_idx,pooling_size*r_idx+max_index/pooling_size,pooling_size*c_idx+max_index%pooling_size]=1

return out_pooling,max_index_Matirx

def poolwithfunc(in_pooling,W,B,type_func='sigmoid'):

k,row,col=numpy.shape(in_pooling)

out_pooling=numpy.zeros((k,row,col))

for k_idx in range(0,k):

for r_idx in range(0,row):

for c_idx in range(0,col):

out_pooling[k_idx,r_idx,c_idx]=sigmoid(W[k_idx]*in_pooling[k_idx,r_idx,c_idx]+B[k_idx])

return out_pooling

#out_feature is the out put of conv

def backErrorfromPoolToConv(theta,max_index_Matirx,out_feature,pooling_size=2):

k1,row,col=numpy.shape(out_feature)

error_conv=numpy.zeros((k1,row,col))

k2,theta_row,theta_col=numpy.shape(theta)

if k1!=k2:

raise Exception

for idx_k in range(0,k1):

for idx_row in range( 0, row):

for idx_col in range( 0, col):

error_conv[idx_k,idx_row,idx_col]=\

max_index_Matirx[idx_k,idx_row,idx_col]*\

float(theta[idx_k,idx_row/pooling_size,idx_col/pooling_size])*\

difsigmoid(out_feature[idx_k,idx_row,idx_col])

return error_conv

def backErrorfromConvToInput(theta,inputImage):

k1,row,col=numpy.shape(theta)

#print "theta",k1,row,col

i_row,i_col=numpy.shape(inputImage)

if row>i_row or col> i_col:

raise Exception

filter_row=i_row-row+1

filter_col=i_col-col+1

detaW=numpy.zeros((k1,filter_row,filter_col))

#the same with conv valid in matlab

for k_idx in range(0,k1):

for idx_row in range(0,filter_row):

for idx_col in range(0,filter_col):

subInputMatrix=inputImage[idx_row:idx_row+row,idx_col:idx_col+col]

#print "subInputMatrix",numpy.shape(subInputMatrix)

#rotate theta 180

#print numpy.shape(theta)

theta_rotate=numpy.rot90(theta[k_idx,:,:], 2)

#print "theta_rotate",theta_rotate

dotMatrix=numpy.dot(subInputMatrix,theta_rotate)

detaW[k_idx,idx_row,idx_col]=numpy.sum(dotMatrix)

detaB=numpy.zeros((k1,1))

for k_idx in range(0,k1):

detaB[k_idx]=numpy.sum(theta[k_idx,:,:])

return detaW,detaB

def loadMNISTimage(absFilePathandName,datanum=60000):

images=open(absFilePathandName,'rb')

buf=images.read()

index=0

magic, numImages , numRows , numColumns = struct.unpack_from('>IIII' , buf , index)

print magic, numImages , numRows , numColumns

index += struct.calcsize('>IIII')

if magic != 2051:

raise Exception

datasize=int(784*datanum)

datablock=">"+str(datasize)+"B"

#nextmatrix=struct.unpack_from('>47040000B' ,buf, index)

nextmatrix=struct.unpack_from(datablock ,buf, index)

nextmatrix=numpy.array(nextmatrix)/255.0

#nextmatrix=nextmatrix.reshape(numImages,numRows,numColumns)

#nextmatrix=nextmatrix.reshape(datanum,1,numRows*numColumns)

nextmatrix=nextmatrix.reshape(datanum,1,numRows,numColumns)

return nextmatrix, numImages

def loadMNISTlabels(absFilePathandName,datanum=60000):

labels=open(absFilePathandName,'rb')

buf=labels.read()

index=0

magic, numLabels  = struct.unpack_from('>II' , buf , index)

print magic, numLabels

index += struct.calcsize('>II')

if magic != 2049:

raise Exception

datablock=">"+str(datanum)+"B"

#nextmatrix=struct.unpack_from('>60000B' ,buf, index)

nextmatrix=struct.unpack_from(datablock ,buf, index)

nextmatrix=numpy.array(nextmatrix)

return nextmatrix, numLabels

def simpleCNN(numofFilter,filter_size,pooling_size=2,maxIter=1000,imageNum=500):

decayRate=0.01

MNISTimage,num1=loadMNISTimage("F:\Machine Learning\UFLDL\data\common\\train-images-idx3-ubyte",imageNum)

print num1

row,col=numpy.shape(MNISTimage[0,0,:,:])

out_Di=numofFilter*((row-filter_size+1)/pooling_size)*((col-filter_size+1)/pooling_size)

MLP=BMNN2.MuiltilayerANN(1,[128],out_Di,10,maxIter)

MLP.setTrainDataNum(imageNum)

MLP.loadtrainlabel("F:\Machine Learning\UFLDL\data\common\\train-labels-idx1-ubyte")

MLP.initialweights()

#MLP.printWeightMatrix()

rng = numpy.random.RandomState(23455)

W_shp = (numofFilter, filter_size, filter_size)

W_bound = numpy.sqrt(numofFilter * filter_size * filter_size)

W_k=rng.uniform(low=-1.0 / W_bound,high=1.0 / W_bound,size=W_shp)

B_shp = (numofFilter,)

B= numpy.asarray(rng.uniform(low=-.5, high=.5, size=B_shp))

cIter=0

while cIter<maxIter:

cIter += 1

ImageNum=random.randint(0,imageNum-1)

conv_out_map=cnn_conv(MNISTimage[ImageNum,0,:,:], W_k, B,"sigmoid")

out_pooling,max_index_Matrix=cnn_maxpooling(conv_out_map,2,"max")

pool_shape = numpy.shape(out_pooling)

MLP_input=out_pooling.reshape(1,1,out_Di)

#print numpy.shape(MLP_input)

DetaW,DetaB,temperror=MLP.backwardPropogation(MLP_input,ImageNum)

if cIter%50 ==0 :

print cIter,"Temp error: ",temperror

#print numpy.shape(MLP.Theta[MLP.Nl-2])

#print numpy.shape(MLP.Ztemp[0])

#print numpy.shape(MLP.weightMatrix[0])

theta_pool=MLP.Theta[MLP.Nl-2]*MLP.weightMatrix[0].transpose()

#print numpy.shape(theta_pool)

#print "theta_pool",theta_pool

temp=numpy.zeros((1,1,out_Di))

temp[0,:,:]=theta_pool

back_theta_pool=temp.reshape(pool_shape)

#print "back_theta_pool",numpy.shape(back_theta_pool)

#print "back_theta_pool",back_theta_pool

error_conv=backErrorfromPoolToConv(back_theta_pool,max_index_Matrix,conv_out_map,2)

#print "error_conv",numpy.shape(error_conv)

#print error_conv

conv_DetaW,conv_DetaB=backErrorfromConvToInput(error_conv,MNISTimage[ImageNum,0,:,:])

#print "W_k",W_k

#print "conv_DetaW",conv_DetaW

作者 | Vihar Kurama

编译 | 荷叶

来源 | 云栖社区

摘要:深度学习背后的主要原因是人工智能应该从人脑中汲取灵感。本文就用一个小例子无死角的介绍一下深度学习!

人脑模拟

深度学习背后的主要原因是人工智能应该从人脑中汲取灵感。此观点引出了“神经网络”这一术语。人脑中包含数十亿个神经元,它们之间有数万个连接。很多情况下,深度学习算法和人脑相似,因为人脑和深度学习模型都拥有大量的编译单元(神经元),这些编译单元(神经元)在独立的情况下都不太智能,但是当他们相互作用时就会变得智能。

我认为人们需要了解到深度学习正在使得很多幕后的事物变得更好。深度学习已经应用于谷歌搜索和图像搜索,你可以通过它搜索像“拥抱”这样的词语以获得相应的图像。-杰弗里·辛顿

神经元

神经网络的基本构建模块是人工神经元,它模仿了人类大脑的神经元。这些神经元是简单、强大的计算单元,拥有加权输入信号并且使用激活函数产生输出信号。这些神经元分布在神经网络的几个层中。

inputs 输入 outputs 输出 weights 权值 activation 激活

人工神经网络的工作原理是什么?

深度学习由人工神经网络构成,该网络模拟了人脑中类似的网络。当数据穿过这个人工网络时,每一层都会处理这个数据的一方面,过滤掉异常值,辨认出熟悉的实体,并产生最终输出。

输入层:该层由神经元组成,这些神经元只接收输入信息并将它传递到其他层。输入层的图层数应等于数据集里的属性或要素的数量。输出层:输出层具有预测性,其主要取决于你所构建的模型类型。隐含层:隐含层处于输入层和输出层之间,以模型类型为基础。隐含层包含大量的神经元。处于隐含层的神经元会先转化输入信息,再将它们传递出去。随着网络受训练,权重得到更新,从而使其更具前瞻性。

神经元的权重

权重是指两个神经元之间的连接的强度或幅度。你如果熟悉线性回归的话,可以将输入的权重类比为我们在回归方程中用的系数。权重通常被初始化为小的随机数值,比如数值0-1。

前馈深度网络

前馈监督神经网络曾是第一个也是最成功的学习算法。该网络也可被称为深度网络、多层感知机(MLP)或简单神经网络,并且阐明了具有单一隐含层的原始架构。每个神经元通过某个权重和另一个神经元相关联。

该网络处理向前处理输入信息,激活神经元,最终产生输出值。在此网络中,这称为前向传递。

inputlayer 输入层 hidden layer 输出层 output layer 输出层

激活函数

激活函数就是求和加权的输入到神经元的输出的映射。之所以称之为激活函数或传递函数是因为它控制着激活神经元的初始值和输出信号的强度。

用数学表示为:

我们有许多激活函数,其中使用最多的是整流线性单元函数、双曲正切函数和solfPlus函数。

激活函数的速查表如下:

反向传播

在网络中,我们将预测值与预期输出值相比较,并使用函数计算其误差。然后,这个误差会传回这个网络,每次传回一个层,权重也会根绝其导致的误差值进行更新。这个聪明的数学法是反向传播算法。这个步骤会在训练数据的所有样本中反复进行,整个训练数据集的网络更新一轮称为一个时期。一个网络可受训练数十、数百或数千个时期。

prediction error 预测误差

代价函数和梯度下降

代价函数度量了神经网络对给定的训练输入和预期输出“有多好”。该函数可能取决于权重、偏差等属性。

代价函数是单值的,并不是一个向量,因为它从整体上评估神经网络的性能。在运用梯度下降最优算法时,权重在每个时期后都会得到增量式地更新。

兼容代价函数

用数学表述为差值平方和:

target 目标值 output 输出值

权重更新的大小和方向是由在代价梯度的反向上采取步骤计算出的。

其中η 是学习率

其中Δw是包含每个权重系数w的权重更新的向量,其计算方式如下:

target 目标值 output 输出值

图表中会考虑到单系数的代价函数

initial weight 初始权重 gradient 梯度 global cost minimum 代价极小值

在导数达到最小误差值之前,我们会一直计算梯度下降,并且每个步骤都会取决于斜率(梯度)的陡度。

多层感知器(前向传播)

这类网络由多层神经元组成,通常这些神经元以前馈方式(向前传播)相互连接。一层中的每个神经元可以直接连接后续层的神经元。在许多应用中,这些网络的单元会采用S型函数或整流线性单元(整流线性激活)函数作为激活函数。

现在想想看要找出处理次数这个问题,给定的账户和家庭成员作为输入

要解决这个问题,首先,我们需要先创建一个前向传播神经网络。我们的输入层将是家庭成员和账户的数量,隐含层数为1, 输出层将是处理次数。

将图中输入层到输出层的给定权重作为输入:家庭成员数为2、账户数为3。

现在将通过以下步骤使用前向传播来计算隐含层(i,j)和输出层(k)的值。

步骤:

1, 乘法-添加方法。

2, 点积(输入*权重)。

3,一次一个数据点的前向传播。

4, 输出是该数据点的预测。

i的值将从相连接的神经元所对应的输入值和权重中计算出来。

i = (2 * 1) + (3* 1) → i = 5

同样地,j = (2 * -1) + (3 * 1) → j =1

K = (5 * 2) + (1* -1) → k = 9

Python中的多层感知器问题的解决

激活函数的使用

为了使神经网络达到其最大预测能力,我们需要在隐含层应用一个激活函数,以捕捉非线性。我们通过将值代入方程式的方式来在输入层和输出层应用激活函数。

这里我们使用整流线性激活(ReLU):

用Keras开发第一个神经网络

关于Keras:

Keras是一个高级神经网络的应用程序编程接口,由Python编写,能够搭建在TensorFlow,CNTK,或Theano上。

使用PIP在设备上安装Keras,并且运行下列指令。

在keras执行深度学习程序的步骤

1,加载数据;

2,创建模型;

3,编译模型;

4,拟合模型;

5,评估模型。

开发Keras模型

全连接层用Dense表示。我们可以指定层中神经元的数量作为第一参数,指定初始化方法为第二参数,即初始化参数,并且用激活参数确定激活函数。既然模型已经创建,我们就可以编译它。我们在底层库(也称为后端)用高效数字库编译模型,底层库可以用Theano或TensorFlow。目前为止,我们已经完成了创建模型和编译模型,为进行有效计算做好了准备。现在可以在PIMA数据上运行模型了。我们可以在模型上调用拟合函数f(),以在数据上训练或拟合模型。

我们先从KERAS中的程序开始,

神经网络一直训练到150个时期,并返回精确值。