赞
踩
通过tf.io.file读取图像文件,然后用tf.image.decode_jpeg转文件格式,保存为np.array(list(float,int))格式
这样子的话,图像数据集就是全部被读取到内存中,这是非常占内存的!!!
接下来可以有两种方法训练keras模型:
- np.array(list(float,int))直接用model.fit
- np.array(list(float,int))转ImageDataGenerator,然后用model.fit_generator
这里面的区别就在于:
第1种方法则只能在保存为np.array(list(float,int))之前做一些数据增强或者图像处理,处理完之后就会固定下来不变,不能在训练过程中处理图像数据。
第2种方法中ImageDataGenerator可以在训练过程随机的进行数据增强或者图像处理。
训练过程如下:
- 通过tf.io.file读取图像文件,然后用tf.image.decode_jpeg转文件格式,保存为np.array(list(float,int))格式
- np.array(list(float,int))转ImageDataGenerator(或者不转也可以)
- 构建keras网络模型(MobileNet):from tensorflow_core.python.keras.applications.mobilenet import MobileNet
- keras训练:model.fit或者model.fit_generator
完整代码:
train_keras_from_nparraydata.py
- import tensorflow as tf
- import random
- import pathlib
- from tensorflow import keras
- import os
- import numpy as np
- from my_input_data import input_data_list
- import gc
-
-
-
- im_w=128
- im_h=128
- # im_channels=3
-
- train_image_list,train_label_list,test_image_list,test_label_list,label_names=input_data_list('../database1/')
-
- classes=len(label_names)
- nums_for_training=len(train_image_list)
- batch_size=32
- steps_per_epoch=int(nums_for_training/batch_size)
- epochs=10
- print(nums_for_training)
- print(steps_per_epoch)
-
-
- def train_preprocess_image(path):
- image = tf.io.read_file(path) # 读取图片
- image = tf.image.decode_jpeg(image, channels=3)
- # image = tf.image.grayscale_to_rgb(image)
-
- image = tf.image.resize(image, [im_w, im_h]) # 原始图片大小为(100, 100, 3),重设为(192, 192)
-
- #随机调整图像的亮度
- image = tf.image.random_brightness(image,max_delta=30)
-
- #随机设置图片的对比度
- image = tf.image.random_contrast(image,lower=0.2,upper=1.8)
-
- #随机设置图片的色度
- image = tf.image.random_hue(image,max_delta=0.3)
-
- #随机设置图片的饱和度
- image = tf.image.random_saturation(image,lower=0.2,upper=1.8)
-
- image = tf.cast(image, dtype=tf.float32) / 255.0
- return image
-
- def test_preprocess_image(path):
- image = tf.io.read_file(path) # 读取图片
- image = tf.image.decode_jpeg(image, channels=3)
- # image = tf.image.grayscale_to_rgb(image)
- image = tf.image.resize(image, [im_w, im_h]) # 原始图片大小为(100, 100, 3),重设为(192, 192)
- image = tf.cast(image, dtype=tf.float32) / 255.0
- return image
-
- def preprocess_label(label):
- label = tf.cast(label, dtype=tf.int32)
- label = tf.one_hot(label, depth=classes)
- return label
-
- train_image = []
- train_label = []
- for image, label in zip(train_image_list, train_label_list):
- r_image = train_preprocess_image(image)
- r_label = preprocess_label(label)
- train_image.append(r_image)
- train_label.append(r_label)
-
- train_images = np.array(train_image)
- train_labels = np.array(train_label)
- print(train_images.shape)
-
-
- test_image = []
- test_label = []
- for image, label in zip(test_image_list, test_label_list):
- r_image = train_preprocess_image(image)
- r_label = preprocess_label(label)
- test_image.append(r_image)
- test_label.append(r_label)
-
- test_images = np.array(test_image)
- test_labels = np.array(test_label)
-
-
-
-
- from tensorflow_core.python.keras.applications.mobilenet import MobileNet
- model=MobileNet(input_shape=(im_w, im_h,3),weights=None,include_top=True,classes=classes)
- model.compile(loss='categorical_crossentropy',optimizer='sgd',metrics=['accuracy'])
-
-
- model.fit(train_images, train_labels,batch_size=batch_size,steps_per_epoch=steps_per_epoch, epochs=epochs)
-
- cost = model.evaluate(test_images, test_labels)
- print('test loss: ', cost)
-
-
- del train_image,train_label,test_images,test_labels
- gc.collect()
这里补充一下tensorflow-V1和tensorflow-V2的区别:(简单做了验证实验)
在tensorflow-V1中,tf.image的方法返回的变量类型都是<class 'tensorflow.python.framework.ops.Tensor'>也就是tf.Tensor,直接用print打印的话会得到:Tensor("resize_910/Squeeze:0", shape=(128, 128, 3), dtype=float32)
在tensorflow-V2中,tf.image的方法返回的变量类型是<class 'tensorflow.python.framework.ops.EagerTensor'>也就是tf.EagerTensor,直接用print打印的话会得到:tf.Tensor(arraydata, shape=(128, 128, 3), dtype=float32),其中arraydata是指矩阵的原始数据
对比之后可以发现,tf.EagerTensor中是带有arraydata数据的,因此可以通过np.array或者list,转为可以使用的原始float数据,而tf.Tensor只能是用sess.run之后才能得到原始float数据,这也是为什么tensoflow-V1难调试的原因。
以博主的水平难说好坏,就这样用着先吧~
完整代码:
train_keras_from_kerasgenerator.py
- # -*- coding: utf-8 -*-
- """
- Created on Fri Jan 29 20:36:16 2021
- @author: Leon_PC
- """
-
- import tensorflow as tf
- import random
- import pathlib
- from tensorflow import keras
- import os
- import numpy as np
- from my_input_data import input_data_list
- import gc
-
-
-
- im_w=128
- im_h=128
- # im_channels=3
-
- train_image_list,train_label_list,test_image_list,test_label_list,label_names=input_data_list('../database1/')
-
- classes=len(label_names)
- nums_for_training=len(train_image_list)
- batch_size=32
- steps_per_epoch=int(nums_for_training/batch_size)
- epochs=10
- print(nums_for_training)
- print(steps_per_epoch)
-
-
- def train_preprocess_image(path):
- image = tf.io.read_file(path) # 读取图片
- image = tf.image.decode_jpeg(image, channels=3)
- # image = tf.image.grayscale_to_rgb(image)
-
- image = tf.image.resize(image, [im_w, im_h]) # 原始图片大小为(100, 100, 3),重设为(192, 192)
-
- # #随机调整图像的亮度
- # image = tf.image.random_brightness(image,max_delta=30)
-
- # #随机设置图片的对比度
- # image = tf.image.random_contrast(image,lower=0.2,upper=1.8)
-
- # #随机设置图片的色度
- # image = tf.image.random_hue(image,max_delta=0.3)
-
- # #随机设置图片的饱和度
- # image = tf.image.random_saturation(image,lower=0.2,upper=1.8)
-
- # image = tf.cast(image, dtype=tf.float32) / 255.0
- return image
-
- def test_preprocess_image(path):
- image = tf.io.read_file(path) # 读取图片
- image = tf.image.decode_jpeg(image, channels=3)
- # image = tf.image.grayscale_to_rgb(image)
- image = tf.image.resize(image, [im_w, im_h]) # 原始图片大小为(100, 100, 3),重设为(192, 192)
- # image = tf.cast(image, dtype=tf.float32) / 255.0
- return image
-
- def preprocess_label(label):
- label = tf.cast(label, dtype=tf.int32)
- label = tf.one_hot(label, depth=classes)
- return label
-
- train_image = []
- train_label = []
- for image, label in zip(train_image_list, train_label_list):
- r_image = train_preprocess_image(image)
- r_label = preprocess_label(label)
- train_image.append(r_image)
- train_label.append(r_label)
-
- train_images = np.array(train_image)
- train_labels = np.array(train_label)
- print(train_images.shape)
-
-
- test_image = []
- test_label = []
- for image, label in zip(test_image_list, test_label_list):
- r_image = train_preprocess_image(image)
- r_label = preprocess_label(label)
- test_image.append(r_image)
- test_label.append(r_label)
-
- test_images = np.array(test_image)
- test_labels = np.array(test_label)
-
-
-
- # from keras.utils import np_utils
- # y_train = np_utils.to_categorical(train_labels, classes)
- # y_test = np_utils.to_categorical(test_labels, classes)
-
- # train_datagen = keras.preprocessing.image.ImageDataGenerator()
- train_datagen = keras.preprocessing.image.ImageDataGenerator(
- rescale=1./255,
- shear_range=0.2,
- zoom_range=0.2,
- horizontal_flip=True)
- test_datagen = keras.preprocessing.image.ImageDataGenerator(rescale=1./255)
-
-
-
- train_datagen.fit(train_images)
- test_datagen.fit(test_images)
-
-
-
- from tensorflow_core.python.keras.applications.mobilenet import MobileNet
- model=MobileNet(input_shape=(im_w, im_h,3),weights=None,include_top=True,classes=classes)
- model.compile(loss='categorical_crossentropy',optimizer='sgd',metrics=['accuracy'])
-
-
- model.fit_generator(train_datagen.flow(train_images, train_labels, batch_size=batch_size),steps_per_epoch=steps_per_epoch, epochs=epochs)
-
- cost = model.evaluate(test_datagen.flow(test_images, test_labels))
- print('test loss: ', cost)
-
-
- del train_image,train_label,test_images,test_labels
- gc.collect()
-
my_input_data.py
- # -*- coding: utf-8 -*-
- """
- Created on Sat Jan 30 15:08:38 2021
- @author: Leon_PC
- """
- import random
- import pathlib
- import os
- def input_data_list(file_dir,train_ratio=4/5):
- # data_path = pathlib.Path('./database1/')
- data_path = pathlib.Path(file_dir)
- print(type(data_path))#<class 'pathlib.WindowsPath'>
- all_image_paths = list(data_path.glob('*/*'))
- print(type(data_path.glob('*/*')))#<class 'generator'>
- # print(all_image_paths)
-
- # all_image_paths = [str(path) for path in all_image_paths] # 所有图片的相对路径的列表
- all_image_paths = [os.path.abspath(path) for path in all_image_paths] # 所有图片的绝对路径的列表
- random.shuffle(all_image_paths) # 打散
- # print(all_image_paths[0:3])
-
- image_count = len(all_image_paths)
- print('image_count: ',image_count)
-
-
- label_names = sorted(item.name for item in data_path.glob('*/') if item.is_dir())
- # print('label_names: ',label_names)
- label_to_index = dict((name, index) for index, name in enumerate(label_names))
- # print('label_to_index: ',label_to_index)
- all_image_labels = [label_to_index[pathlib.Path(path).parent.name] for path in all_image_paths]
-
- # classes=len(label_names)
- print(label_names)
-
- # train_ratio=4/5
- nums_for_training=int(len(all_image_paths)*train_ratio)
-
- train_image_list = list(all_image_paths[0:nums_for_training])
- train_label_list = list(all_image_labels[0:nums_for_training])
- test_image_list = list(all_image_paths[nums_for_training:len(all_image_paths)])
- test_label_list = list(all_image_labels[nums_for_training:len(all_image_paths)])
- return train_image_list,train_label_list,test_image_list,test_label_list,label_names
-
-
-
- if __name__=='__main__':
- input_data('../database1/')
ImageDataGenerator.flow_from_directory方法,可以直接用分好train和test的文件夹读取数据,转化为ImageDataGenerator
所以还是:database1这个数据集了,博主没有分为train和test,直接将‘../database/’输出flow_from_directory
这个方法适合于提前做好train和test的数据集,但是一般来说应该都是train和test放在一起的然后按比例随机分配吧,不过还是蛮适合新手去用的,前提是用python写好批处理程序自动分好train和test文件夹。
完整代码:
train_keras_from_kerasgenerator_fromdirectory.py
- # -*- coding: utf-8 -*-
- """
- Created on Fri Jan 29 20:36:16 2021
- @author: Leon_PC
- """
-
- import tensorflow as tf
- from tensorflow import keras
-
- im_w=128
- im_h=128
- # im_channels=3
- batch_size=32
- classes=10
-
- train_datagen = keras.preprocessing.image.ImageDataGenerator(
- rescale=1./255,
- shear_range=0.2,
- zoom_range=0.2,
- horizontal_flip=True)
-
- image_path='../database1/'
- train_data_gen = train_datagen.flow_from_directory(directory=image_path,
- batch_size=batch_size,
- shuffle=True, #打乱数据
- target_size=(im_h, im_w),
- class_mode='categorical')
- print(train_data_gen)#<keras_preprocessing.image.directory_iterator.DirectoryIterator object at 0x00000204624B8550>
-
- nums_for_training=train_data_gen.n
-
- steps_per_epoch=int(nums_for_training/batch_size)
- epochs=10
- print(nums_for_training)
- print(steps_per_epoch)
-
-
- from tensorflow_core.python.keras.applications.mobilenet import MobileNet
- model=MobileNet(input_shape=(im_w, im_h,3),weights=None,include_top=True,classes=classes)
- model.compile(loss='categorical_crossentropy',optimizer='sgd',metrics=['accuracy'])
-
-
- model.fit_generator(train_data_gen,steps_per_epoch=steps_per_epoch, epochs=epochs,max_queue_size=1,workers=1)
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。