[机器学习]人工神经网络手写数字识别

00.写在前面

  由于最近要出去实习,所以开始接触机器学习的内容,逐步将自己的实验内容整理成博,以供以后使用。这次主要是关于验证码的识别和手写数字的识别,其实两者根本上是相同的原理

工具: pycharm + python3.5 + keras

01.训练数据的获取

  为了能得到后面实验所需的数据,我自己手写了一部分数据用于制作训练数据,并将其转化为数字格式。
  

1.1 调整图像大小与明暗,使得手写部分更为突出
  这里在ps里面调整为32*32像素的大小,并且更改了对比度等,使得手写部分更为容易识别。
    

1.2 图片转为数字文本
  我们知道在算法当中,直接的图片是无法识别的,需要使用能表征图片特征的元素来代替它。所以这里很容易想到用图片的像素值来代替,即原本的白色用0表示,黑色用1表示。(这里存在一定问题,在像素改变后,原本的黑色像素值不再是(0,0,0)而是接近黑色的灰色,所以在程序中可以识别白色,然后剩下的赋1。这里假设都是优质数据,所以直接按黑白来区分了
  
  Ps.读取的时候,图片会被颠倒,不是你在windows里面看到的样子,所以是getpixel((j,i))

from PIL import Image
im = Image.open("21.jpg")
fh = open('2_1.txt','w')
for i in range(0,im.size[1]):
    for j in range(0,im.size[0]):
        cl = im.getpixel((j,i))
        clall = cl[0]+cl[1]+cl[2]
        if clall == 0:
          fh.write("1")
        else:
          fh.write("0")
    fh.write("\n")
fh.close()

1.3 重复操作,得到足够多的训练样本
 这里收集了每个数字的多种写法,一共得到1000+的训练样本,最后一并上传在github中供大家使用。

02.数据的预处理

 为了后面训练模型的使用,我们需要从样本数据中得到两部分数据:(1)特征值,即我们上一步中得到的32*32的矩阵;(2)结果值,即每个矩阵代表的数字,也是我们识别的结果。

def datatoarray(fname):
    arr = []
    fh = open(fname)
    for i in range(0, 32):
        thisline = fh.readline()
        for j in range(0, 32):
            arr.append(int(thisline[j]))
    return arr

 def seplabel(fname):
    filestr = fname.split(".")[0]
    label = int(filestr.split("_")[0])
    return label

 def traindata():
    labels = []
    trainfile = listdir("D:/13.NerveNet/traindata")
    num = len(trainfile)
    # 长度1024(列),每一行存储一个文件
    # 用一个数组存储所有训练数据,行:文件总数,列:1024
    trainarr=zeros((num, 1024))
    for i in range(0, num):
        thisfname = trainfile[i]
        thislabel = seplabel(thisfname)
        labels.append(thislabel)
        trainarr[i, :] = datatoarray("D:/13.NerveNet/traindata/"+thisfname)
    return trainarr, labels


trainarr, labels = traindata()
# 数据类型和存储格式的转换
xf = pda.DataFrame(trainarr)
yf = pda.DataFrame(labels)
tx2 = xf.as_matrix().astype(int)
ty2 = yf.as_matrix().astype(int)
03.数据的预处理

  根据bp神经网络的原理,确定输入层、输出层、激活函数等参数。

model = Sequential()
# 输入层
# 需指定输入层的层数和特征维数
model.add(Dense(10, input_dim=1024))
model.add(Activation("relu"))
# 输出层
model.add(Dense(1, input_dim=1))
model.add(Activation("sigmoid"))
# 模型的编译
model.compile(loss="mean_squared_error", optimizer="adam")
# 训练
model.fit(tx2, ty2, nb_epoch=10000, batch_size=10)
# 预测分类
rst = model.predict_classes(tx2).reshape(len(tx2))
# 计算正确率
x = 0
for i in range(0, len(tx2)):
    if rst[i] != ty2[i]:
        x += 1
print(1-x/len(tx2))
04.写在最后

 其实最总要的不是代码如何写,而是去理解神经网络的原理。这里只是简答的一个运用。当然可以用来做一些预测,还有待学习。
 代码和训练数据已经上传到github,供大家使用。神秘地址:
 https://github.com/moonlighf/Leetcode/tree/master/04.bpNerveNet_WriteNum

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值