您当前的位置:首页 > IT编程 > cnn卷积神经网络
| C语言 | Java | VB | VC | python | Android | TensorFlow | C++ | oracle | 学术与代码 | cnn卷积神经网络 | gnn | 图像修复 | Keras | 数据集 | Neo4j | 自然语言处理 | 深度学习 | 医学CAD | 医学影像 | 超参数 | pointnet | pytorch |

自学教程:keras笔记(3)-猫狗数据集上的训练以及单张图片多张图片的测试

51自学网 2020-03-04 09:11:54
  cnn卷积神经网络
这篇教程keras笔记(3)-猫狗数据集上的训练以及单张图片多张图片的测试写得很实用,希望能帮到您。
数据集下载
猫狗数据集:https://pan.baidu.com/s/13hw4LK8ihR6-6-8mpjLKDA   密码:dmp4

代码
对于猫狗数据上的训练,存在一点问题在与不能够将所有的训练集读入到内存,这时候需要用到keras中的

model.fit_generator()
 接下来还是看代码吧

from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from keras.optimizers import RMSprop
 
from keras.preprocessing.image import ImageDataGenerator
 
 
 
#下面的一部分是进行数据预处理
import os
import shutil
 
dataset_dir = 'kaggle/train/'
train_cats_dir = 'kaggle/train/cats/'
train_dogs_dir = 'kaggle/train/dogs/'
validation_cats_dir = 'kaggle/validation/cats/'
validation_dogs_dir = 'kaggle/validation/dogs/'
 
if not os.path.exists(train_cats_dir):
    os.mkdir(train_cats_dir)
if not os.path.exists(train_dogs_dir):
    os.mkdir(train_dogs_dir)
if not os.path.exists(validation_cats_dir):
    os.mkdir('kaggle/validation/')
    os.mkdir(validation_cats_dir)
if not os.path.exists(validation_dogs_dir):
    os.mkdir(validation_dogs_dir)
 
cat_count = 0
dog_count = 0
 
image_list = os.listdir(dataset_dir)
for image in image_list:
    print(image)
    animal = image.split('.')[0]
    image_path = os.path.join(dataset_dir, image)
    if animal == 'cat':
        cat_count += 1
        if cat_count % 5 == 0:
            shutil.move(image_path, validation_cats_dir)
        else:
            shutil.move(image_path, train_cats_dir)
    if animal == 'dog':
        dog_count += 1
        if dog_count % 5 == 0:
            shutil.move(image_path, validation_dogs_dir)
        else:
            shutil.move(image_path, train_dogs_dir)
 
 
train_dir = 'kaggle/train/'
validation_dir = 'kaggle/validation/'
 
train_datagen = ImageDataGenerator(rescale=1. / 255)
validation_datagen = ImageDataGenerator(rescale=1. / 255)
 
 
train_generator = train_datagen.flow_from_directory(
    train_dir,  # target directory
    target_size=(150, 150),  # resize图片
    batch_size=20,
    class_mode='binary'
)
 
validation_generator = validation_datagen.flow_from_directory(
    validation_dir,
    target_size=(150, 150),
    batch_size=20,
    class_mode='binary'
)
 
for data_batch, labels_batch in train_generator:
    print('data batch shape:', data_batch.shape)
    print('labels batch shape:', labels_batch.shape)
    break
 
model = Sequential()
model.add(Conv2D(32, (3, 3), activation='relu',
                 input_shape=(150, 150, 3)))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D((2, 2)))
model.add(Flatten())
model.add(Dense(512, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
 
print(model.summary())
 
model.compile(loss='binary_crossentropy',
              optimizer=RMSprop(lr=1e-4),
              metrics=['acc'])
 
 
hist = model.fit_generator(
    train_generator,
    steps_per_epoch=100,
    epochs=30,
    validation_data=validation_generator,
    validation_steps=50)
 
model.save('cat_and_dog.h5')
上面的代码首先将kaggle/train/中的数据集分成两个部分,一部分是train的,一部分是validation的。因为model.fit_generator()函数的需求,还需要将train集中的猫狗数据分别放在kaggle/train/cats/和kaggle/train/dogs/;同理也需要将validation中的数据这样处理。然后就可以直接训练了。

注释:如果不成功的话,最好删除生成的kaggle文件,然后放上原始的kaggle文件。

解释
需要解释的估计就是model.fit_generator() 

还有关于ImageDataGenerator的使用方法

fit_generator
fit_generator(self, generator, steps_per_epoch=None, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, class_weight=None, max_queue_size=10, workers=1, use_multiprocessing=False, shuffle=True, initial_epoch=0)
使用 Python 生成器或 Sequence 实例逐批生成的数据,按批次训练模型。

生成器与模型并行运行,以提高效率。 例如,这可以让你在 CPU 上对图像进行实时数据增强,以在 GPU 上训练模型。

keras.utils.Sequence 的使用可以保证数据的顺序, 以及当 use_multiprocessing=True 时 ,保证每个输入在每个 epoch 只使用一次。

参数

generator: 一个生成器或 Sequence (keras.utils.Sequence)。 生成器的输出应该为以下之一:
一个 (inputs, targets) 元组
一个 (inputs, targets, sample_weights) 元组。 所有的数组都必须包含同样数量的样本。生成器将无限地在数据集上循环。当运行到第 steps_per_epoch 时,记一个 epoch 结束。
steps_per_epoch: 在声明一个 epoch 完成并开始下一个 epoch 之前从 generator 产生的总步数(批次样本)。它通常应该等于你的数据集的样本数量除以批量大小。可选参数 Sequence:如果未指定,将使用len(generator) 作为步数。
epochs: 整数,数据的迭代总轮数。请注意,与 initial_epoch 一起,参数 epochs 应被理解为 「最终轮数」。模型并不是训练了 epochs 轮,而是到第 epochs 轮停止训练。
verbose: 日志显示模式。0,1 或 2。
callbacks: 在训练时调用的一系列回调函数。
validation_data: 它可以是以下之一:
验证数据的生成器或 Sequence 实例
一个 (inputs, targets) 元组
一个 (inputs, targets, sample_weights) 元组。
validation_steps: 仅当 validation_data 是一个生成器时才可用。 每个 epoch 结束时验证集生成器产生的步数。它通常应该等于你的数据集的样本数量除以批量大小。可选参数 Sequence:如果未指定,将使用len(generator) 作为步数。
class_weight: 将类别映射为权重的字典。
max_queue_size: 生成器队列的最大尺寸。
workers: 使用的最大进程数量。
use_multiprocessing: 如果 True,则使用基于进程的多线程。 请注意,因为此实现依赖于多进程,所以不应将不可传递的参数传递给生成器,因为它们不能被轻易地传递给子进程。
shuffle: 是否在每轮迭代之前打乱 batch 的顺序。只能与 Sequence (keras.utils.Sequence) 实例同用。
initial_epoch: 开始训练的轮次(有助于恢复之前的训练)。
返回

一个 History 对象。

   

问题
使用这种方法进行训练,感觉标签就是文件夹的个数,对于大规模的数据训练还是不怎么好用,可以使用接下来的博客,可以将所有图片的地址保存到内存中,然后进行训练。这样就不会出现内存不足的情况了

 

单张图片多张图片的测试
直接代码吧

import os
from keras.models import load_model
from keras.preprocessing import image
import  matplotlib.pyplot as plt
import numpy as np
 
 
 
#单张图片的识别
model = load_model('cats_and_dogs_small_1.h5')
 
img = image.load_img('kaggle/test1/2.jpg', target_size=(150, 150))
# plt.imshow(img)
# plt.show()
 
#【3】将图片转化为4d tensor形式
x = image.img_to_array(img)
print(x.shape) #(224, 224, 3)
x = np.expand_dims(x, axis=0)
print(x.shape) #(1, 224, 224, 3)
 
pres = model.predict(x)
print(int(pres[0][0]))
if int(pres[0][0]) > 0.5:
    print('识别的结果是狗')
 
 
 
#多张图片的识别,这里买可以从kaggle/test1/中复制几张图片放到一个新建的文件夹test中,然后进行测试
#如果加载kaggle/test1/中的全部分会超出内存,当然也可以使用训练时候的策略进行测试
file_list = os.listdir('test_image/')
images = []
 
for file in file_list:
    # print(file)
    img = image.load_img(os.path.join('test_image/', file), target_size=(150, 150))
    img = image.img_to_array(img)
    img = np.expand_dims(img, axis=0)
    images.append(img)
 
x_train = np.array(images, dtype="float") / 255.0
x = np.concatenate([x for x in x_train])
 
#预测
y = model.predict(x)
 
 
#根据结果可以看出来,0代表的是猫,1代表的是狗。
# 同时也可以从训练cats_and_dogs_small/train/里面文件的顺序知道类别代表的信息
 
for i in range(len(file_list)):
    print(y[i][0])
    # print('image class:', int(y[i]))
    # print('image class:', round(y[i]))
    if y[i][0] > 0.5:
        print('image {} class:'.format(file_list[i]), 1)
    else:
        print('image {} class:'.format(file_list[i]), 0)
 

原文链接:https://blog.csdn.net/pursuit_zhangyu/article/details/85226734
利用ResNet50网络进行ImageNet分类
keras中对多张输入图片进行预测并返回预测结果
51自学网,即我要自学网,自学EXCEL、自学PS、自学CAD、自学C语言、自学css3实例,是一个通过网络自主学习工作技能的自学平台,网友喜欢的软件自学网站。
京ICP备13026421号-1