• 李宏毅 Keras手写数字集识别(优化篇)


      在之前的一章中我们讲到的keras手写数字集的识别中,所使用的loss function为‘mse’,即均方差。那我们如何才能知道所得出的结果是不是overfitting?我们通过运行结果中的training和testing即可得知。

    源代码与运行截图如下:

    #!/usr/bin/env python 
    # -*- coding: utf-8 -*- 
    # @Time : 2019/9/9 13:23 
    # @Author : BaoBao
    # @Mail : baobaotql@163.com 
    # @File : test5.py 
    # @Software: PyCharm
    
    import numpy as np
    from keras.models import Sequential     #序贯模型
    from keras.layers.core import Dense,Dropout,Activation
    from keras.optimizers import SGD,Adam
    from keras.utils import np_utils
    from keras.datasets import mnist
    
    def load_data():
        (x_train,y_train),(x_test,y_test)=mnist.load_data()     #载入数据
        number=10000
        x_train=x_train[0:number]
        y_train=y_train[0:number]
    
        x_train=x_train.reshape(number,28*28)
        x_test=x_test.reshape(x_test.shape[0],28*28)
    
        x_train=x_train.astype('float32')       #astype转换数据类型
        x_test=x_test.astype('float32')
    
        y_train=np_utils.to_categorical(y_train,10)
        y_test=np_utils.to_categorical(y_test,10)
    
        x_train=x_train
        x_test=x_test
    
        x_train=x_train/255     #归一化到0-1区间  变为只有0 1的矩阵
        x_test=x_test/255
        return (x_train,y_train),(x_test,y_test)
    
    (x_train,y_train),(x_test,y_test)=load_data()
    
    model=Sequential()
    model.add(Dense(input_dim=28*28,units=689,activation='sigmoid'))
    model.add(Dense(units=689,activation='sigmoid'))
    model.add(Dense(units=689,activation='sigmoid'))
    model.add(Dense(units=10,activation='softmax'))
    model.compile(loss='mse',optimizer=SGD(lr=0.1),metrics=['accuracy'])
    #
    #model.compile(loss='categorical_crossentropy',optimizer=SGD(lr=0.1),metrics=['accuracy'])
    
    #train 模型
    model.fit(x_train,y_train,batch_size=100,epochs=20)
    
    #测试结果 并打印accuary
    result= model.evaluate(x_train,y_train,batch_size=10000)
    print('
    TRAIN ACC :',result[1])
    
    result= model.evaluate(x_test,y_test,batch_size=10000)
    
    # print('
    Test loss:', result[0])
    # print('
    Accuracy:', result[1])
    
    print('
    TEST ACC :',result[1])

    运行截图:

    通过图片中的运行结果我们可以发现。训练结果中在training data上的准确率为0.1127,在testing data上的准确率为0.1134

    虽然准确率不够高,但是这其中的train和test的准确率相差无几,所以这并不是overfitting问题。这其实就是模型的建立问题。

    考虑更换loss function。原loss function 为 mse 更换为'categorical_crossentropy'然后观察训练结果。

    源代码(只修改了loss):

    #!/usr/bin/env python 
    # -*- coding: utf-8 -*- 
    # @Time : 2019/9/9 13:23 
    # @Author : BaoBao
    # @Mail : baobaotql@163.com 
    # @File : test5.py 
    # @Software: PyCharm
    
    import numpy as np
    from keras.models import Sequential     #序贯模型
    from keras.layers.core import Dense,Dropout,Activation
    from keras.optimizers import SGD,Adam
    from keras.utils import np_utils
    from keras.datasets import mnist
    
    def load_data():
        (x_train,y_train),(x_test,y_test)=mnist.load_data()     #载入数据
        number=10000
        x_train=x_train[0:number]
        y_train=y_train[0:number]
    
        x_train=x_train.reshape(number,28*28)
        x_test=x_test.reshape(x_test.shape[0],28*28)
    
        x_train=x_train.astype('float32')       #astype转换数据类型
        x_test=x_test.astype('float32')
    
        y_train=np_utils.to_categorical(y_train,10)
        y_test=np_utils.to_categorical(y_test,10)
    
        x_train=x_train
        x_test=x_test
    
        x_train=x_train/255     #归一化到0-1区间  变为只有0 1的矩阵
        x_test=x_test/255
        return (x_train,y_train),(x_test,y_test)
    
    (x_train,y_train),(x_test,y_test)=load_data()
    
    model=Sequential()
    model.add(Dense(input_dim=28*28,units=689,activation='sigmoid'))
    model.add(Dense(units=689,activation='sigmoid'))
    model.add(Dense(units=689,activation='sigmoid'))
    model.add(Dense(units=10,activation='softmax'))
    #model.compile(loss='mse',optimizer=SGD(lr=0.1),metrics=['accuracy'])
    #
    model.compile(loss='categorical_crossentropy',optimizer=SGD(lr=0.1),metrics=['accuracy'])
    
    #train 模型
    model.fit(x_train,y_train,batch_size=100,epochs=20)
    
    #测试结果 并打印accuary
    result= model.evaluate(x_train,y_train,batch_size=10000)
    print('
    TRAIN ACC :',result[1])
    
    result= model.evaluate(x_test,y_test,batch_size=10000)
    
    # print('
    Test loss:', result[0])
    # print('
    Accuracy:', result[1])
    
    print('
    TEST ACC :',result[1])

    运行截图:

    deep layer

    考虑使hidden layer更深一些

    for _ in range(10):
        model.add(Dense(units=689,activation='sigmoid'))

     结果不是很理想呢.....

     

    normalize

    现在的图片是有进行normalize,每个pixel我们用一个0-1之间的值进行表示,那么我们不进行normalize,把255拿掉会怎样呢?

        #注释掉    
        # x_train=x_train/255
        # x_test=x_test/255

     你会发现你又做不起来了,所以这种小小的地方,只是有没有做normalizion,其实对你的结果会有关键性影响。

     optimizer

    修改优化器optimizer,将SGD修改为Adam,然后再去跑一次,你会发现,用adam的时候最后不收敛的地方查不到,但是上升的速度变快。

    源代码不贴了,就是修改了optimizer

    model.compile(loss='categorical_crossentropy',optimizer='adam',metrics=['accuracy'])

    你会惊奇的发现!wow!train accuracy居然达到100%!而且test accuracy也表现的不错~

    运行截图:

    Random noise 

    添加噪声数据,看看结果会掉多少?完整代码不贴了QAQ

        x_test = np.random.normal(x_test)

    可以看出train的结果是ok的  但是test不太行,出现了overfitting!

    运行截图:

    dropout

    #dropout 就是在每一个隐藏层后面都dropout一下
    model.add(Dense(input_dim=28*28,units=689,activation='relu'))
    model.add(Dropout(0.7))
    model.add(Dense(units=689,activation='relu'))
    model.add(Dropout(0.7))
    model.add(Dense(units=689,activation='relu'))
    model.add(Dropout(0.7))
    model.add(Dense(units=10,activation='softmax'))

    要知道dropout加入之后,train的效果会变差,然而test的正确率提升了

  • 相关阅读:
    MongoDB 学习笔记之 MongoDB导入导出
    快学Scala 第十四课 (读取行,读取字符, 控制台读取)
    MongoDB 学习笔记之 权限管理基础
    MongoDB 学习笔记之 索引
    MongoDB 学习笔记之 游标
    MongoDB 学习笔记之 查询表达式
    MongoDB 学习笔记之 基本CRUD
    MongoDB 学习笔记之 入门安装和配置
    Eclipse设置JVM的内存参数
    cron表达式详解
  • 原文地址:https://www.cnblogs.com/baobaotql/p/11512921.html
Copyright © 2020-2023  润新知