原数据集:包含 25000张猫狗图像,两个类别各有12500

新数据集:猫、狗 (照片大小不一样)

  • 训练集:各1000个样本
  • 验证集:各500个样本
  • 测试集:各500个样本

1= 狗,0= 猫

  1. # 将图像复制到训练、验证和测试的目录
  2.  
  3. import os,shutil
  4.  
  5. orginal_dataset_dir = 'kaggle_original_data/train'
  6. base_dir = 'cats_and_dogs_small'
  7. os.mkdir(base_dir)#保存新数据集的目录
  8.  
  9. train_dir = os.path.join(base_dir,'train')
  10. os.mkdir(train_dir)
  11. validation_dir = os.path.join(base_dir,'validation')
  12. os.mkdir(validation_dir)
  13. test_dir = os.path.join(base_dir,'test')
  14. os.mkdir(test_dir)
  15.  
  16. #猫、狗的训练图像目录
  17. train_cats_dir = os.path.join(train_dir,'cats')
  18. os.mkdir(train_cats_dir)
  19. train_dogs_dir = os.path.join(train_dir,'dogs')
  20. os.mkdir(train_dogs_dir)
  21.  
  22. #猫、狗的验证图像目录
  23. validation_cats_dir = os.path.join(validation_dir,'cats')
  24. os.mkdir(validation_cats_dir)
  25. validation_dogs_dir = os.path.join(validation_dir,'dogs')
  26. os.mkdir(validation_dogs_dir)
  27.  
  28. #猫、狗的测试图像目录
  29. test_cats_dir = os.path.join(test_dir,'cats')
  30. os.mkdir(test_cats_dir)
  31. test_dogs_dir = os.path.join(test_dir,'dogs')
  32. os.mkdir(test_dogs_dir)
  33.  
  34. #将前1000张猫的图像复制到train_cats_dir
  35. fnames = ['cat.{}.jpg'.format(i) for i in range(1000)]
  36. for fname in fnames:
  37. src = os.path.join(orginal_dataset_dir,fname)
  38. dst = os.path.join(train_cats_dir,fname)
  39. shutil.copyfile(src,dst)
  40.  
  41. #将接下来500张猫的图像复制到validation_cats_dir
  42. fnames = ['cat.{}.jpg'.format(i) for i in range(1000,1500)]
  43. for fname in fnames:
  44. src = os.path.join(orginal_dataset_dir,fname)
  45. dst = os.path.join(validation_cats_dir,fname)
  46. shutil.copyfile(src,dst)
  47.  
  48. #将接下来的500张猫的图像复制到test_cats_dir
  49. fnames = ['cat.{}.jpg'.format(i) for i in range(1500,2000)]
  50. for fname in fnames:
  51. src = os.path.join(orginal_dataset_dir,fname)
  52. dst = os.path.join(test_cats_dir,fname)
  53. shutil.copyfile(src,dst)
  54.  
  55. #将前1000张狗的图像复制到train_dogs_dir
  56. fnames = ['dog.{}.jpg'.format(i) for i in range(1000)]
  57. for fname in fnames:
  58. src = os.path.join(orginal_dataset_dir,fname)
  59. dst = os.path.join(train_dogs_dir,fname)
  60. shutil.copyfile(src,dst)
  61.  
  62. #将接下来500张狗的图像复制到validation_dogs_dir
  63. fnames = ['dog.{}.jpg'.format(i) for i in range(1000,1500)]
  64. for fname in fnames:
  65. src = os.path.join(orginal_dataset_dir,fname)
  66. dst = os.path.join(validation_dogs_dir,fname)
  67. shutil.copyfile(src,dst)
  68.  
  69. #将接下来的500张狗的图像复制到test_cats_dir
  70. fnames = ['dog.{}.jpg'.format(i) for i in range(1500,2000)]
  71. for fname in fnames:
  72. src = os.path.join(orginal_dataset_dir,fname)
  73. dst = os.path.join(test_dogs_dir,fname)
  74. shutil.copyfile(src,dst)
 

  1. #将猫狗分类的小型卷积神经网络实例化
  2. from keras import layers
  3. from keras import models
  4.  
  5. model = models.Sequential()
  6. model.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(150,150,3)))
  7. model.add(layers.MaxPool2D((2,2)))
  8.  
  9. model.add(layers.Conv2D(64,(3,3),activation='relu'))
  10. model.add(layers.MaxPool2D((2,2)))
  11.  
  12. model.add(layers.Conv2D(128,(3,3),activation='relu'))
  13. model.add(layers.MaxPool2D((2,2)))
  14.  
  15. model.add(layers.Conv2D(128,(3,3),activation='relu'))
  16. model.add(layers.MaxPool2D((2,2)))
  17.  
  18. model.add(layers.Flatten())
  19. model.add(layers.Dense(512,activation='relu'))
  20. model.add(layers.Dense(1,activation='sigmoid'))

该问题为二分类问题,所以网咯最后一层是使用sigmoid激活的

单一单元,大小为1的Dense层。

  1. from keras import optimizers
  2.  
  3. model.compile(loss='binary_crossentropy',
  4. optimizer = optimizers.RMSprop(lr=1e-4),
  5. metrics = ['acc'])

loss: binary_crossentropy

优化器: RMSprop

度量:acc精度

  1. #使用ImageDataGenerator从目录中读取图像
  2. #ImageDataGenerator可以快速创建Python生成器,能够将硬盘上的图像文件自动转换为预处理好的张量批量
  3. from keras.preprocessing.image import ImageDataGenerator
  4.  
  5. #将所有图像乘以1/255缩放
  6. train_datagen = ImageDataGenerator(rescale = 1./255)
  7. test_datagen = ImageDataGenerator(rescale = 1./255)
  8.  
  9. train_generator = train_datagen.flow_from_directory(
  10. train_dir,
  11. target_size = (150,150),
  12. batch_size = 20,
  13. class_mode = 'binary' #因为使用了binary_crossentropy损失,所以需要用二进制标签
  14. )
  15.  
  16. validation_generator = test_datagen.flow_from_directory(
  17. validation_dir,
  18. target_size = (150,150),
  19. batch_size = 20,
  20. class_mode = 'binary'
  21. )
 

 用flow_from_directory最值得注意的是directory这个参数:
它的目录格式一定要注意是包含一个子目录下的所有图片这种格式,
driectoty路径只要写到标签路径上面的那个路径即可。 

  1. for data_batch,labels_batch in train_generator:
  2. print('data batch shape:',data_batch.shape)
  3. print('labels batch shape:',labels_batch.shape)
  4. break
  1. data batch shape: (20, 150, 150, 3)
  2. labels batch shape: (20,)
  1. #利用批量生成器拟合模型
  2. history = model.fit_generator(
  3. train_generator,
  4. steps_per_epoch = 50,
  5. epochs = 30,
  6. validation_data = validation_generator,
  7. validation_steps = 50#需要从验证生成器中抽取50个批次用于评估
  8. )

#保存模型
  model.save('cats_and_dogs_small_1.h5')

 
  1.  

from keras.models import load_model
  model = load_model('cats_and_dogs_small_1.h5')

  1.  
 手残,误操作,还好我已经保存了模型,用这句话就可以载入模型
  1. #绘制损失曲线和精度曲线
  2. import matplotlib.pyplot as plt
  3.  
  4. acc = history.history['acc']
  5. val_acc = history.history['val_acc']
  6. loss = history.history['loss']
  7. val_loss = history.history['val_loss']
  8.  
  9. epochs = range(1,len(acc)+1)
  10.  
  11. plt.plot(epochs,acc,'bo',label='Training_acc')
  12. plt.plot(epochs,val_acc,'b',label='Validation_acc')
  13. plt.title('Traing and validation accuracy')
  14. plt.legend()
  15.  
  16. plt.figure()
  17.  
  18. plt.plot(epochs,loss,'bo',label='Training loss')
  19. plt.plot(epochs,val_loss,'b',label='Validation_loss')
  20. plt.title('Traing and validation loss')
  21. plt.legend()
  22.  
  23. plt.show()
 

过拟合太严重了,原因可能是训练样本较少

  1. #因为数据样本较少,容易过拟合,因此我们使用数据增强来减少过拟合
  2.  
  3. #利用ImageDataGenerator来设置数据增强
  4. datagen = ImageDataGenerator(
  5. rotation_range = 40,
  6. width_shift_range = 0.2,
  7. height_shift_range=0.2,
  8. shear_range=0.2,
  9. zoom_range = 0.2,
  10. horizontal_flip = True,
  11. fill_mode = 'nearest'
  12. )

数据增强是从现有的训练样本中生成更多的训练数据,其方法是

利用多种能够生成可信图像的随机变换来增加样本。其目标是,

模型在训练时不会两次查看完全相同的图像。这让模型能够观察

到数据的更多内容,从而具有更好的泛化能力。

  1. #显示几个随机增强后的训练图像
  2. from keras.preprocessing import image
  3.  
  4. fnames = [os.path.join(train_cats_dir,fname) for fname in os.listdir(train_cats_dir)]
  5. # ['cats_and_dogs_small\\train\\cats\\cat.0.jpg','cats_and_dogs_small\\train\\cats\\cat.1.jpg',...]
  6.  
  7. img_path = fnames[3]#选择一张图像进行增强
  8. # 'cats_and_dogs_small\\train\\cats\\cat.3.jpg'
  9.  
  10. img = image.load_img(img_path,target_size=(150,150))#读取图像并调整大小
  11.  
  12. x = image.img_to_array(img) # ==> array(150,150,3)
  13.  
  14. x = x.reshape((1,)+x.shape) # ==> array(1,150,150,3)
    #x的秩必须为4,不够需要加一维
  15.  
  16. i = 0
  17. for batch in datagen.flow(x,batch_size=1):
  18. plt.figure(i)
  19. implot = plt.imshow(image.array_to_img(batch[0]))
  20. i += 1
  21. if i % 4 == 0: #生成随机变换后的图像批量。循环是无限的,因此你需要在某个时刻终止循环
  22. break #生成4张图之后就终止
  23.  
  24. plt.show()

  1. #向模型中添加一个Dropout层,添加到密集连接分类器之前
  2. model = models.Sequential()
  3. model.add(layers.Conv2D(32,(3,3),activation='relu',input_shape=(150,150,3)))
  4. model.add(layers.MaxPool2D((2,2)))
  5.  
  6. model.add(layers.Conv2D(64,(3,3),activation='relu'))
  7. model.add(layers.MaxPool2D((2,2)))
  8.  
  9. model.add(layers.Conv2D(128,(3,3),activation='relu'))
  10. model.add(layers.MaxPool2D((2,2)))
  11.  
  12. model.add(layers.Conv2D(128,(3,3),activation='relu'))
  13. model.add(layers.MaxPool2D((2,2)))
  14.  
  15. model.add(layers.Flatten())
  16. model.add(layers.Dropout(0.5))
  17. model.add(layers.Dense(512,activation='relu'))
  18. model.add(layers.Dense(1,activation='sigmoid'))
  19.  
  20. model.compile(loss='binary_crossentropy',
  21. optimizer = optimizers.RMSprop(lr=1e-4),
  22. metrics = ['acc'])
 
  1. #利用数据增强生成器训练卷积神经网络
  2. train_datagen = ImageDataGenerator(
  3. rescale = 1./255,
  4. rotation_range = 40,
  5. width_shift_range = 0.2,
  6. height_shift_range = 0.2,
  7. shear_range = 0.2,
  8. zoom_range = 0.2,
  9. horizontal_flip = True,
  10. )
  11.  
  12. test_datagen = ImageDataGenerator(rescale = 1./255)
  13.  
  14. train_generator = train_datagen.flow_from_directory(
  15. train_dir,
  16. target_size = (150,150),
  17. batch_size = 20,
  18. class_mode = 'binary' #因为使用了binary_crossentropy损失,所以需要用二进制标签
  19. )
  20.  
  21. validation_generator = test_datagen.flow_from_directory(
  22. validation_dir,
  23. target_size = (150,150),
  24. batch_size = 20,
  25. class_mode = 'binary'
  26. )
  27.  
  28. history = model.fit_generator(
  29. train_generator,
  30. steps_per_epoch = 50,
  31. epochs = 30,
  32. validation_data = validation_generator,
  33. validation_steps = 50#需要从验证生成器中抽取50个批次用于评估
  34. )
  35.  
  36. model.save('cats_and_dogs_small_2.h5')
 

  1. #绘制损失曲线和精度曲线
  2. import matplotlib.pyplot as plt
  3.  
  4. acc = history.history['acc']
  5. val_acc = history.history['val_acc']
  6. loss = history.history['loss']
  7. val_loss = history.history['val_loss']
  8.  
  9. epochs = range(1,len(acc)+1)
  10.  
  11. plt.plot(epochs,acc,'bo',label='Training_acc')
  12. plt.plot(epochs,val_acc,'b',label='Validation_acc')
  13. plt.title('Traing and validation accuracy')
  14. plt.legend()
  15.  
  16. plt.figure()
  17.  
  18. plt.plot(epochs,loss,'bo',label='Training loss')
  19. plt.plot(epochs,val_loss,'b',label='Validation_loss')
  20. plt.title('Traing and validation loss')
  21. plt.legend()
  22.  
  23. plt.show()
 

使用了数据增强和dropout之后,模型不再过拟合,训练曲线紧紧跟着验证曲线

但只靠从头开始训练自己的卷积神经网络,再想提高精度就十分困难,因为可用的数据太少。想要在这个问题上进一步提高精度,下一步需要使用预训练的模型。

1.keras实现-->自己训练卷积模型实现猫狗二分类(CNN)的更多相关文章

  1. Kaggle系列1:手把手教你用tensorflow建立卷积神经网络实现猫狗图像分类

    去年研一的时候想做kaggle上的一道题目:猫狗分类,但是苦于对卷积神经网络一直没有很好的认识,现在把这篇文章的内容补上去.(部分代码参考网上的,我改变了卷积神经网络的网络结构,其实主要部分我加了一层 ...

  2. 深度学习原理与框架-猫狗图像识别-卷积神经网络(代码) 1.cv2.resize(图片压缩) 2..get_shape()[1:4].num_elements(获得最后三维度之和) 3.saver.save(训练参数的保存) 4.tf.train.import_meta_graph(加载模型结构) 5.saver.restore(训练参数载入)

    1.cv2.resize(image, (image_size, image_size), 0, 0, cv2.INTER_LINEAR) 参数说明:image表示输入图片,image_size表示变 ...

  3. keras系列︱Sequential与Model模型、keras基本结构功能(一)

    引自:http://blog.csdn.net/sinat_26917383/article/details/72857454 中文文档:http://keras-cn.readthedocs.io/ ...

  4. 使用 keras 和 tfjs 构建血细胞分类模型

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识!

  5. Deep Learning模型之:CNN卷积神经网络(一)深度解析CNN

    http://m.blog.csdn.net/blog/wu010555688/24487301 本文整理了网上几位大牛的博客,详细地讲解了CNN的基础结构与核心思想,欢迎交流. [1]Deep le ...

  6. Keras 如何利用训练好的神经网络进行预测

    分成两种情况,一种是公开的训练好的模型,下载后可以使用的,一类是自己训练的模型,需要保存下来,以备今后使用. 如果是第一种情况,则参考    http://keras-cn.readthedocs.i ...

  7. 使用GPU训练TensorFlow模型

    查看GPU-ID CMD输入: nvidia-smi 观察到存在序号为0的GPU ID 观察到存在序号为0.1.2.3的GPU ID 在终端运行代码时指定GPU 如果电脑有多个GPU,Tensorfl ...

  8. Keras框架下的保存模型和加载模型

    在Keras框架下训练深度学习模型时,一般思路是在训练环境下训练出模型,然后拿训练好的模型(即保存模型相应信息的文件)到生产环境下去部署.在训练过程中我们可能会遇到以下情况: 需要运行很长时间的程序在 ...

  9. 【猫狗数据集】使用预训练的resnet18模型

    数据集下载地址: 链接:https://pan.baidu.com/s/1l1AnBgkAAEhh0vI5_loWKw提取码:2xq4 创建数据集:https://www.cnblogs.com/xi ...

随机推荐

  1. Android 框架

    1. https://github.com/wyouflf/xUtils xUtils简介 xUtils 包含了很多实用的android工具. xUtils 最初源于Afinal框架,进行了大量重构, ...

  2. oracle数据库用户加锁和解锁

    oracle数据库安装好之后,scott之类的用户默认情况下是被锁住的,无法使用scott用户登录数据库.使用有alter user数据库权限的用户登陆,角色选sysdba,执行以下命令: 解锁命令: ...

  3. NET中的设计模式---单件模式

    如众所知,单件模式做为<Gof 23中设计模式>之一,其意图仅允许单件类的一个实例存在(扩展单件模式不在此文范围内),并提供全局的访问方法.UML类图如下. http://csharpin ...

  4. CentOS6 防火墙配置

    清空现有的规则 iptables -F iptables -P INPUT DROP iptables -I INPUT -m state --state RELATED , ESTABLISHED ...

  5. Logstash自带正则表达式

    USERNAME [a-zA-Z0-._-]+ USER %{USERNAME} INT (?:[+-]?(?:[-]+)) BASE10NUM (?<![-.+-])(?>[+-]?(? ...

  6. nginx 二级域名跳转

    server { listen ; server_name m.aaoo.cn; #charset koi8-r; #access_log logs/host.access.log main; rew ...

  7. UPUPW本地环境配置thinkphp5的问题

    问题解决参考: https://blog.csdn.net/lengyue1084/article/details/80001625 看httpd-vhosts.conf的配置: <Virtua ...

  8. python开发环境搭建(python3.3.2+wing IDE4.1)

    1.下载python http://www.wingide.com/downloads下载最新版python 2.下载Wing IDE http://wingware.com/downloads/wi ...

  9. logstash实战tcp插件

    vim /etc/logstash/conf.d/tcp.conf input{ tcp{ type => "tcp" port => "6666" ...

  10. POJ3268 Silver Cow Party【最短路】

    One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big co ...