CNN实战

需求:判断手写ld的指令

训练模型:

from keras.models import Sequential
from keras import layers
from keras.layers import Dense, Dropout, Conv2D, MaxPooling2D, Flatten
import numpy
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
from keras.callbacks import ModelCheckpoint

#image->convolution->pooling->convolution->pooling->full connected->full connected(hidden layer) ->classifier

def defineModelAndGenerateModel():
    model = Sequential()  ## 定义cnn模型
    model.add(Conv2D(32, (3,3), activation='relu',input_shape=(100,200,1))) ## 添加2D卷积层,32个过滤器,用3乘3过滤器,使用relu激活函数,指定输入图片尺寸
    ## ken 这里应该添加更多的层
    model.add(MaxPooling2D(2,2)) ## 添加最大池化层
    model.add(Conv2D(32, (3,3), activation='relu')) ## 添加2D卷积层,32个过滤器,用3乘3过滤器,使用relu激活函数,指定输入图片尺寸
    model.add(MaxPooling2D(2,2)) ## 添加最大池化层
    model.add(Conv2D(64, (3,3), activation='relu')) ## 添加2D卷积层,32个过滤器,用3乘3过滤器,使用relu激活函数,指定输入图片尺寸
    model.add(MaxPooling2D(2,2)) ## 添加最大池化层

    # drop out of max-pooling layer , drop out rate is 0.25 (0.5??) 
    #model.add(Dropout(0.25))
    model.add(Dropout(0.5))
    # flatten inputs from 2d to 1d
    model.add(Flatten())
    model.add(Dense(8, activation='softmax'))  ## 添加全连结层,使用softmax激活函数,输出8种分类的可能性

    model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy']) ## 编译模型,rmsprop优化函数,分类交叉熵损失函数
    train_datagen = ImageDataGenerator(rescale=1./255) ## 从目录里提取图片

    train_generator = train_datagen.flow_from_directory(
        'C:/hand-imgs', target_size=(100,200),  #(120,205)
        batch_size=10,
        color_mode='grayscale',
        class_mode='categorical'
    )


    #todo:训练之前应该将一部分训练中的数据挑选为validation用,用keras的split方法。
    validation_generator= train_datagen.flow_from_directory(
        'c:/hand-imgs-validate', target_size=(100,200),
        batch_size=10,
        color_mode='grayscale',
        class_mode='categorical'
    )

    checkpoint = ModelCheckpoint('model-{epoch:03d}-{acc:03f}-{val_acc:03f}.h5', verbose=1, monitor='val_loss',save_best_only=True, mode='auto')  

    #调整参数
    history = model.fit_generator(  #开始训练模型
        train_generator,
        steps_per_epoch=100,
        epochs=10,
        validation_data= validation_generator,
        callbacks=[checkpoint],
        validation_steps=2)
    model.save('hand_ld')  ## 保存训练的模型(*以后做预测会用到)
    return history

def showresult(history):  ## 生成模型衡量的结果
    plt.figure()
    acc = history.history['acc']
    val_acc = history.history['val_acc']
    loss = history.history['loss']
    val_loss = history.history['val_loss']
    epochs = range(1,len(acc)+1)
    plt.plot(epochs, acc, 'bo', label='Training acc')
    plt.plot(epochs, val_acc, 'b', label='Validation acc')
    plt.title('Training and validation accuracy')
    #plt.legend()
    plt.show()

if __name__ == "__main__":
    history= defineModelAndGenerateModel()
    #showresult(history)
    

注意点:

  • 多个池化层
  • Dropout 0.2太小会产生过拟合,一般采用0.5
  • 增加了checkpoint, 由于梯度下降的参数不同,顺着step增加,acc_val会变小。用checkpoint保存最高的acc_val
import os
import numpy as np
import cv2
from keras.models import Model
from keras.preprocessing import image as kimage
from keras.models import load_model
from procImg import procImage, drawImageResult 

#const
#predictFile = "C:/hand-test/20200102170013216-2.jpg"
#predictFile = "C:/hand-backup/training/20191230165257965-6.jpg"
predictFile = "C:/hand-backup/validate/20200102101640083-28.jpg"
modlepath = 'model-008-0.966599-0.950000.h5'

def predict(image, model):
    cv2.imwrite('cv2.jpeg', image)  ##保存当前视频(图片)画面
    kimg = kimage.load_img('cv2.jpeg', target_size=([100,200]), color_mode='grayscale')  ## 转化为Keras能读取的数据格式
    img_tensor = kimage.img_to_array(kimg)
    img_tensor = np.expand_dims(img_tensor, axis=0)
    predict = np.argmax(model.predict(img_tensor))  ## 使用模型预测,结果取8个分类结果中可能性最大的
    return predict
    

def run():
    model = load_model(modlepath)  ## 读取保存的模型
    image = cv2.imread(predictFile)
    images = procImage(image)
    predicts = []
    for img in images:
        ret = predict(img, model)
        print(ret)
        predicts.append(ret)
    drawImageResult(image, predicts)

    

if __name__ == '__main__':
    run()
    cv2.waitKey()

创建模型的时候,前两位是训练产生的loss和acc,后两位是验证产生的val_loss和val_acc。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值