这篇教程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中对多张输入图片进行预测并返回预测结果 |