zoukankan      html  css  js  c++  java
  • 猫狗识别训练

    下载数据集

    下载地址:https://www.kaggle.com/c/dogs-vs-cats/data

    下载的训练集中有2.5W张猫猫狗狗的图片,我这里只用训练集压缩包就行了,验证集和测试集都可以从中切分。

    观察图片可得知命名方式,猫图片为cat.数字.jpg,狗图片为dog.数字.jpg,各有12500张。

    规划数据

    数据需要分成三份:训练集、验证集和测试集。

    我打算使用1.9W张图片作为训练集,4000张图片作为验证集,2000张图片作为测试集。

    import os,shutil
    from tensorflow import keras
    import matplotlib.pyplot as plt
    
    
    #原始图片存放目录
    origin_dir = './origin/train'
    
    #训练数据集存储位置
    base_dir = './data'
    
    #训练集 验证集 测试集
    train_dir = base_dir + '/train'
    validation_dir = base_dir + '/validation'
    test_dir = base_dir + '/test'
    
    #如果目录存在先删掉
    if True == os.path.exists(base_dir) :
        shutil.rmtree(base_dir)
    os.makedirs(base_dir)
    
    #创建子目录
    validation_dog_dir = validation_dir + '/dog'
    validation_cat_dir = validation_dir + '/cat'
    test_dog_dir = test_dir + '/dog'
    test_cat_dir = test_dir + '/cat'
    train_dog_dir = train_dir + '/dog'
    train_cat_dir = train_dir + '/cat'
    
    #创建目录
    os.makedirs(validation_dog_dir)
    os.makedirs(validation_cat_dir)
    os.makedirs(test_dog_dir)
    os.makedirs(test_cat_dir)
    os.makedirs(train_dog_dir)
    os.makedirs(train_cat_dir)
    
    
    #复制2000张狗图片到验证数据集狗目录
    files = ['dog.{}.jpg'.format(i) for i in range(2000)]
    for file in files :
        src = os.path.join(origin_dir,file)
        dst = os.path.join(validation_dog_dir,file)
        shutil.copy(src,dst)
    
    #复制2000张猫图片到验证数据集猫目录
    files = ['cat.{}.jpg'.format(i) for i in range(2000)]
    for file in files :
        src = os.path.join(origin_dir,file)
        dst = os.path.join(validation_cat_dir,file)
        shutil.copy(src,dst)
    
    
    #复制1000张狗图片到测试数据集狗目录
    files = ['dog.{}.jpg'.format(i) for i in range(2000,3000)]
    for file in files :
        src = os.path.join(origin_dir,file)
        dst = os.path.join(test_dog_dir,file)
        shutil.copy(src,dst)
    
    #复制1000张猫图片到测试数据集狗目录
    files = ['cat.{}.jpg'.format(i) for i in range(2000,3000)]
    for file in files :
        src = os.path.join(origin_dir,file)
        dst = os.path.join(test_cat_dir,file)
        shutil.copy(src,dst)
    
    #复制9500张狗图片到训练数据集狗目录
    files = ['dog.{}.jpg'.format(i) for i in range(3000,12500)]
    for file in files :
        src = os.path.join(origin_dir,file)
        dst = os.path.join(train_dog_dir,file)
        shutil.copy(src,dst)
    
    #复制9500张猫图片到训练数据集猫目录
    files = ['cat.{}.jpg'.format(i) for i in range(3000,12500)]
    for file in files :
        src = os.path.join(origin_dir,file)
        dst = os.path.join(train_cat_dir,file)
        shutil.copy(src,dst)

    搭建网络结构

    img_width=350
    img_height=350
    img_channel = 3
    
    model = keras.models.Sequential([
        keras.layers.Conv2D(32,(3,3),activation='relu',input_shape=(img_width,img_height,img_channel)),
        keras.layers.MaxPool2D((2,2)),
        keras.layers.Conv2D(64,(3,3),activation='relu'),
        keras.layers.MaxPool2D((2,2)),
        keras.layers.Conv2D(128,(3,3),activation='relu'),
        keras.layers.MaxPool2D((2,2)),
        keras.layers.Conv2D(128,(3,3),activation='relu'),
        keras.layers.MaxPool2D((2,2)),
        keras.layers.Flatten(),
        keras.layers.Dropout(0.3),
        keras.layers.Dense(512,activation='relu',kernel_regularizer=keras.regularizers.l2()),
        keras.layers.Dropout(0.3),
        keras.layers.Dense(1,activation='sigmoid')
    ])

    四层卷积+两层全连接,上了Dropout和正则化抑制过拟合。

    模型编译

    优化器使用adam,损失函数使用二元交叉熵。

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

    数据生成器

    由于数据量过大,先读取后训练会导致内存溢出,因此使用生成器的方式去训练。

    batch_size=32
    epochs = 25
    
    train_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1. / 255)
    validation_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1. / 255)
    test_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1. / 255)
    
    train_generator = train_datagen.flow_from_directory(
        train_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode='binary')
    
    validation_generator = validation_datagen.flow_from_directory(
        validation_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode='binary')
    
    test_generator = test_datagen.flow_from_directory(
        test_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode='binary')

    执行训练

    history = model.fit(
        train_generator,
        steps_per_epoch=train_generator.n // batch_size,
        epochs=epochs,
        validation_data=validation_generator,
        validation_steps=validation_generator.n // batch_size,
        verbose=1)

    模型评估

    score = model.evaluate(test_generator, steps=test_generator.n // batch_size)
    print('测试准确率:{}, 测试loss值: {}'.format(score[1], score[0]))

    可视化acc和loss曲线

    plt.rcParams['font.sans-serif']=['SimHei']
    acc = history.history['accuracy']
    val_acc = history.history['val_accuracy']
    loss = history.history['loss']
    val_loss = history.history['val_loss']
    
    plt.subplot(1, 2, 1)
    plt.plot(acc, label='训练Acc')
    plt.plot(val_acc, label='测试Acc')
    plt.title('Acc曲线')
    plt.legend()
    
    plt.subplot(1, 2, 2)
    plt.plot(loss, label='训练Loss')
    plt.plot(val_loss, label='测试Loss')
    plt.title('Loss曲线')
    plt.legend()
    plt.show()

    由于海量数据导致训练的速度超慢,我跑一次程序大概要花费近两小时,可想而知调参的过程会有多恶心,调了三天把准确率怼到90%左右,不想再怼了。

  • 相关阅读:
    【转】CNN卷积神经网络_ GoogLeNet 之 Inception(V1-V4)
    【转】Caffe的solver文件配置
    python 从filelist.txt中拷贝文件到另一文件夹中
    【转】fscanf 跳过空格,读取一行
    caffe配置NCCL
    caffe实现多任务学习
    mysql 2
    mysql 1
    mysql
    jQuery
  • 原文地址:https://www.cnblogs.com/fengyumeng/p/14066836.html
Copyright © 2011-2022 走看看