![]()
import tensorflow as tf
import numpy as np
import os
#%% fileos
def get_files(file_dir):
cats =[]
label_cats = []
dogs = []
label_dogs =[]
for file in os.listdir(file_dir):
name =file.split(sep='.')
if name[0]=='cat':
cats.append(file_dir+file)
label_cats.append(0)
else:
dogs.append(file_dir+file)
label_dogs.append(1)
print('There are %d cats\nThere are %d dogs' ,(len(cats)),len(dogs))
image_list = np.hstack((cats,dogs))
label_list = np.hstack((label_cats,label_dogs))
temp = np.array([image_list,label_list])
temp = temp.transpose()
np.random.shuffle(temp)
image_list = list(temp[:,0])
label_list = list(temp[:,1])
print(image_list)
label_list = [int(i) for i in label_list]
print(label_list)
return image_list,label_list
#%%
def get_batch(image,label,image_W,image_H,batch_size,capacity):
'''
image : list type
label : list type
'''
image = tf.cast(image,tf.string)
label = tf.cast(label,tf.int32)
'''tf.train.slice_input_producer是一个tensor生成器,作用是按照设定,每次从一个tensor列表中按顺序或者随机抽取出一个tensor放入文件名队列。
slice_input_producer(tensor_list, num_epochs=None, shuffle=True, seed=None,
capacity=32, shared_name=None, name=None)
第一个参数 tensor_list:包含一系列tensor的列表,表中tensor的第一维度的值必须相等,即个数必须相等,有多少个图像,就应该有多少个对应的标签。
第二个参数num_epochs: 可选参数,是一个整数值,代表迭代的次数,如果设置 num_epochs=None,生成器可以无限次遍历tensor列表,如果设置为 num_epochs=N,生成器只能遍历tensor列表N次。
第三个参数shuffle: bool类型,设置是否打乱样本的顺序。一般情况下,如果shuffle=True,生成的样本顺序就被打乱了,在批处理的时候不需要再次打乱样本,使用 tf.train.batch函数就可以了;如果shuffle=False,就需要在批处理时候使用 tf.train.shuffle_batch函数打乱样本。
第四个参数seed: 可选的整数,是生成随机数的种子,在第三个参数设置为shuffle=True的情况下才有用。
第五个参数capacity:设置tensor列表的容量。
第六个参数shared_name:可选参数,如果设置一个‘shared_name’,则在不同的上下文环境(Session)中可以通过这个名字共享生成的tensor。
第七个参数name:可选,设置操作的名称。
'''
# make an input queue
# tensorflow 1版本 (2.0 以后放弃使用)
print(image)
print(label)
input_queue = tf.compat.v1.train.slice_input_producer([image,label])
# input_queue = tf.data.Dataset.0([image,label])
label = input_queue[1]
image_contents = tf.read_file(input_queue[0])
image = tf.compat.v1.image.decode_jpeg(image_contents,channels=3) #图片解码
'''图像尺寸调整
图像尺寸调整属于基础的图像几何变换,TensorFlow提供了几种尺寸调整的函数:
tf.image.resize_images:将原始图像缩放成指定的图像大小,其中的参数method(默认值为ResizeMethod.BILINEAR)提供了四种插值算法,具体解释可以参考图像几何变换(缩放、旋转)中的常用的插值算法
tf.image.resize_image_with_crop_or_pad:剪裁或填充处理,会根据原图像的尺寸和指定的目标图像的尺寸选择剪裁还是填充,如果原图像尺寸大于目标图像尺寸,则在中心位置剪裁,反之则用黑色像素填充。
tf.image.central_crop:比例调整,central_fraction决定了要指定的比例,取值范围为(0,1],该函数会以中心点作为基准,选择整幅图中的指定比例的图像作为新的图像。
'''
image = tf.compat.v1.image.resize_image_with_crop_or_pad(image,image_W,image_H)
''' 图像标准化 与 图像归一化'''
'''图像标准化是将数据通过去均值实现中心化的处理,根据凸优化理论与数据概率分布相关知识,数据中心化符合数据分布规律,更容易取得训练之后的泛化效果, 数据标准化是数据预处理的常见方法之一'''
'''原图与归一化之后的运行结果完全一致,说明归一化不会改变图像本身的信息存储,但是通过打印出来的像素值可以发现,取值范围从0~255已经转化为0~1之间了,这个对于后续的神经网络或者卷积神经网络处理有很大的好处,
tensorflow官方给出mnist数据集,全部采用了归一化之后的结果作为输入图像数据来演示神经网络与卷积神经网络。'''
image = tf.compat.v1.image.per_image_standardization(image)
'''tf.train.batch是一个tensor队列生成器,作用是按照给定的tensor顺序,把batch_size个tensor推送到文件队列,作为训练一个batch的数据,等待tensor出队执行计算。
batch(tensors, batch_size, num_threads=1, capacity=32,
enqueue_many=False, shapes=None, dynamic_pad=False,
allow_smaller_final_batch=False, shared_name=None, name=None)
第一个参数tensors:tensor序列或tensor字典,可以是含有单个样本的序列;
第二个参数batch_size: 生成的batch的大小;
第三个参数num_threads:执行tensor入队操作的线程数量,可以设置使用多个线程同时并行执行,提高运行效率,但也不是数量越多越好;
第四个参数capacity: 定义生成的tensor序列的最大容量;
第五个参数enqueue_many: 定义第一个传入参数tensors是多个tensor组成的序列,还是单个tensor;
第六个参数shapes: 可选参数,默认是推测出的传入的tensor的形状;
第七个参数dynamic_pad: 定义是否允许输入的tensors具有不同的形状,设置为True,会把输入的具有不同形状的tensor归一化到相同的形状;
第八个参数allow_smaller_final_batch: 设置为True,表示在tensor队列中剩下的tensor数量不够一个batch_size的情况下,允许最后一个batch的数量少于batch_size, 设置为False,则不管什么情况下,生成的batch都拥有batch_size个样本;
第九个参数shared_name: 可选参数,设置生成的tensor序列在不同的Session中的共享名称;
第十个参数name: 操作的名称;
如果tf.train.batch的第一个参数 tensors 传入的是tenor列表或者字典,返回的是tensor列表或字典,如果传入的是只含有一个元素的列表,返回的是单个的tensor,而不是一个列表。'''
'''tf.train.batch与tf.train.shuffle_batch的作用都是从队列中读取数据,它们的区别是是否随机打乱数据来读取。'''
image_batch,label_batch = tf.compat.v1.train.batch([image,label],batch_size=batch_size,num_threads = 64,capacity = capacity)
# image_batch,label_batch = tf.compat.v1.train.shuffle_batch([image,label],batch_size=batch_size,num_threads = 64,capacity = capacity,min_after_dequeue = capacity-1)
label_batch = tf.reshape(label_batch,[batch_size])
return image_batch,label_batch
#%% test
import matplotlib.pyplot as plt
BATCH_SIZE = 8
CAPACITY = 512
IMG_W = 208
IMG_H = 208
train_dir = 'D:/deeplearning/train/'
image_list,label_list = get_files(train_dir)
image_batch,label_batch = get_batch(image_list,label_list,IMG_W,IMG_H,BATCH_SIZE,CAPACITY)
#设置显存使用量
# gpu_options = tf.compat.v1.GPUOptions(per_process_gpu_memory_fraction=0.333)
# sess = tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(gpu_options=gpu_options))
with tf.Session() as sess:
i = 0
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord = coord)
try:
while not coord.should_stop() and i<5:
img,label = sess.run([image_batch,label_batch])
for j in np.arange(BATCH_SIZE):
print('label:%d'%label[j])
plt.imshow(img[j,:,:,:])
plt.show()
i+=1
except tf.compat.v1.errors.OutOfRangeError:
print('done!')
finally:
coord.request_stop()
coord.join(threads)
#%%