深度学习[入门]-Keras使用CNN+NN识别自己的手写数据


Mnist数据集作为深度学习领域的Hello World,想必大家早已熟悉,但是大家有没有想过自己写数据集,用自己训练好的网络去识别呢?效果又如何呢?

阿J昨晚也是手撸代码上试了试 ,发现效果好像还不错,也有一些容易忽视的细节,放在这里供大家雅正。


废话不多说,训练结果放下

版本一(准确率较低的全连接层网络,不做解释):

可以看到,模型在最后的误差达到了7.05,准确率也只有接近52%的准确率

版本二(运用了卷积层+全连接层的网络):

使用卷积层后,可以看到准确率得到了明显的提升,到达了88%

关于自己的手写数据集,我自己使用各类画图软件画了一些数字或者在百度上找到一些图片,放在文件夹下,类似这样:

图片集
右击图片~>编辑~>重新调整大小~>更改像素28*28

这里有一些注意的点:

1.由于网络模型只接受输入为28x28像素的图片,所以我们必须通过图片编辑软件进行预处理;
2.标签需要人工标注;
3.换成png或者jpg格式(方便后面使用scipy.misc处理);

以下是完整代码:

    import scipy.misc #读取图片数据
    from keras.datasets import mnist
    from keras import models
    from keras import layers
    from keras.utils import to_categorical
    import numpy as np

    (train_images, train_labels),(test_images, test_labels) = mnist.load_data()

    train_images = train_images.reshape((60000,28,28,1))
    train_images = train_images.astype('float32') / 255
    '''test_images = test_images.reshape((10000,28,28,1))
    test_images = test_images.astype('float32') / 255'''#这里不使用测试集

    def to_one_hot(labels, dimension=10):    #自定义one_hot独热编码函数,理解其工作机制
        results = np.zeros((len(labels), dimension))   
        for i, label in enumerate(labels):       
            results[i, label] = 1.   
        return results

    train_labels = to_one_hot(train_labels)
    #test_labels = to_one_hot(test_labels)

    model = models.Sequential()
    model.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(28,28,1)))   #添加卷积层
    model.add(layers.MaxPooling2D((2,2)))    #添加最大池化层
    model.add(layers.Conv2D(64,(3,3),activation='relu'))
    model.add(layers.MaxPooling2D((2,2)))      #卷积层:此时输出向量为3d,大小为:[3,3,64],将此向量输入到密集连接层,所以需要展平为1d向量:Flatten函数
    #卷积层到全连接层的过渡
    model.add(layers.Flatten())
    model.add(layers.Dense(64,activation='relu'))
    model.add(layers.Dense(10,activation='softmax'))    #输出层,mnist故为10个输出节点

    model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])    #优化器:rmsprop,多分类损失函数,指标函数:accuracy
    model.fit(train_images, train_labels, epochs = 5, batch_size=64)  #batch_size:小批量样本


    #准备自己的手写数据文件:
    image_array = np.array([])
    for i in range(1,51):   #测试50个样本
        image = scipy.misc.imread('Fliename{}.png'.format(i),flatten = True)
        image_data = 255.0 - image.reshape(784)    #灰度转换:符合mnist标准(一般0指黑色,255指白色,mnist相反)
        image_data = image_data / 255.0
        image_array = np.concatenate((image_array, image_data), axis=0)
    image_array = image_array.reshape(50,28,28,1)   #更改维度,适应卷积网络的输入
    image_label = np.array([4,0,7,2,3,1,6,9,8,5,7,3,9,7,0,1,2,3,4,5,6,7,8,9,1,2,8,0,3,6,4,6,2,7,0,5,1,3,8,0,1,2,4,4,9,5,9,8,6,5])          #人工标签
    image_label = to_one_hot(image_label)  #one_hot编码
    print(model.evaluate(image_array,image_label))

分析以上代码:

1.首先导入需要的库以及函数

2.准备数据:

一、导入数据:

    (train_images, train_labels),(test_images, test_labels) = mnist.load_data()

二、将数据转换成60000个图像高度和图像宽度为28,通道为1的张量,以适应卷积网络的输入:

    train_images = train_images.reshape((60000,28,28,1))

3.网络架构:

    model = models.Sequential()
    model.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(28,28,1)))   #添加卷积层
    model.add(layers.MaxPooling2D((2,2)))    #添加最大池化层
    model.add(layers.Conv2D(64,(3,3),activation='relu'))
    model.add(layers.MaxPooling2D((2,2)))

现在输出一下网络结构:

到最后一层,输出形状已变成(3,3,64)大小的张量

下一步是将最后的输出张量[大小为 (3, 3, 64)]输入到一个密集连接分类器网络中, 即 Dense 层的堆叠:

    model.add(layers.Dense(64,activation='relu'))
    model.add(layers.Dense(10,activation='softmax')) 

这些分类器可以处理 1D 向量,而当前的输出是 3D 张量。 所以我们需要将 3D 输出展平为 1D:

    model.add(layers.Flatten())

最后编译、训练:

    model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])    #优化器:rmsprop,多分类损失函数,指标函数:accuracy
    model.fit(train_images, train_labels, epochs = 5, batch_size=64)  #batch_size:小批量样本

4.训练好模型后,识别自己的数据集:

预处理自己的手写数据:

    image_array = np.array([])
    for i in range(1,51):   #测试50个样本
        image = scipy.misc.imread('Fliename{}.png'.format(i),flatten = True)
        image_data = 255.0 - image.reshape(784)    #灰度转换:符合mnist标准(一般0指黑色,255指白色,mnist相反)
        image_data = image_data / 255.0
        image_array = np.concatenate((image_array, image_data), axis=0)
    image_array = image_array.reshape(50,28,28,1)   #更改维度,适应卷积网络的输入

思路:

第一步:创建一个image_array行向量用来存放所有的数据
第二步:创建循环,读取数据(scipy.misc.imread),一股脑的存放在image_array中
第三步:使用reshape函数重组为50个图像高度,图像宽度为28,通道为1(灰度图像)的张量

Attention:

(1)scipy.misc.imread函数帮助我们处理图像,参数flatten = True将图像变成简单的浮点数数组,如果图像是彩色,那么颜色值将被转换为需要的灰度。

(2)使用下面这行代码的原因是,常规而言,0是指黑色,255指的是白色,但是mnist数据集使用相反的方式表示,因此不得不将值逆转过来一匹配mnist数据:

  image_data = 255.0 - image.reshape(784)

(3)下面这行代码将数据缩放,使得他们的范围变成0~1.0:

  image_data = image_data / 255.0

5.最后打印模型评估结果

    print(model.evaluate(image_array,image_label))

结果准确率达到了88%,其实结果并不是很好,但是对比第一个版本可以看出,卷积神经网络在应对图像识别方面比简单的神经网络的优势要大得多。

要优化这个网络,还可以从很多方面着手:
� 尝试不同的架构:增加或减少层数。
� 添加 L1 和 / 或 L2 正则化。
� 尝试不同的超参数(比如每层的单元个数或优化器的学习率),以找到最佳配置。

当然,你也可以为其添加可视化过程,完善你的程序。


如果你有一些什么好的想法或者想互相交流深度学习方面的知识
欢迎随时联系我
我是 阿J
一名在读大学生,爱好技术,滑板,拍摄
关注我,在学习的路上不孤单

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容