1.tf.train.batch(image, batch_size=batch_size, num_threads=1) # 获取一个batch的数据
参数说明:image表示输入图片,batch_size表示一个batch的大小,num_threads表示使用几个线程进行执行
import tensorflow as tf import numpy as np def generate_data(): num = 25 label = np.asarray(range(0, num)) image = np.random.random([num, 1, 1, 1]) return label, image def get_batch_data(): labels, images = generate_data() images = tf.cast(images, 'float32') labels = tf.cast(labels, 'int32') input_queue = tf.train.slice_input_producer([images, labels], shuffle=False) image_batch, label_batch = tf.train.batch(input_queue, batch_size=10, num_threads=1, capacity=64) return image_batch, label_batch image_batch, label_batch = get_batch_data() with tf.Session() as sess: coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=sess, coord=coord) i = 0 for i in range(10): image_batch_v, label_batch_v = sess.run([image_batch, label_batch]) print(image_batch_v, label_batch_v) coord.request_stop() coord.join(threads) sess.close()
实例说明
2.tf.image.resize_image_with_crop_or_pad(image, IMAGE_SIZE, IMAGE_SIZE) # 表示对图片进行压缩,即变化维度, 相当于tf.resize(操作)
参数说明:image表示输入图片,IMAGE_SIZE表示变化后的维度
3.tf.train.per_image_standardization(image) 对图片进行标准化操作
参数说明:image表示输入的图片
4.tf.train.string_input_producer(filenames) # 将字符串放入到队列中
参数说明:filename表示输入的字符串集合
5. tf.TFRecordReader() # 构建tfr读取器,使用.read() 对文件进行读取
6. tf.parse_single_example(serialized_exmaple, features={}) 解析example数据字符串
7.tf.train.start_queue_runner(coord=coord, sess=sess) 用来启动线程,进行多线程操作
参数说明:coord表示线程协调器,sess执行函数支持多线程
8.tf.train.Coordinator() 用于建立线程协调器, coord.join(threads) 将多线程放入到线程协调器中
数据说明:使用的数据是Tfrecord数据集,一共3670个数据,每次迭代选取16张图片,输出的结果类别数是5
文中的代码主要是分为两个部分:
第一部分构造flower_input, 读取batch_image, batch_label
第二部分:构造image_tensor_input和label_tensor_input, 输入到构造的flower_inference模型中进行训练,输出结果为softmax概率值,构造loss和train_op,sess.run进行模型的训练操作
第一部分:
第一步:构造flower_input函数,输入为if_random, if_train
第二步:根据是否训练,使用[os.path.join(path_data + ''%i) for i in range(0, 2)] 来获得文件的路径filenames
第三步:使用tf.train.string_input_producer(filenames) , # 输出字符变成一个输入队列中
第四步:将filename_queue输入到read_and_decode(filename_queue) 输出image_object实例化对象,包含image, label, filename等属性
第一步:使用tf.TFRecordReader() 构造reader的读写器
第二步:使用_, serialized_example = reader.read(filenames) 获得存储好的example
第三步:使用tf.parse_single_example(features={}) 获得属性值
第四步:实例化_image_object(), 用于储存image,label, filename,width和height
第五步:使用image_raw = tf.image.decode_jpeg(feature[image/encoded]) # 对图片进行解码操作
第六步:使用tf.image.resize_image_with_crop_or_pad(image_raw) 对图像进行维度的压缩变换
第七步:将其他属性label,filename, height,width,使用image_object.label = features['image/labels'] 进行添加, 返回image_object
第五步:使用image_object.image 获得image, 使用tf.train.per_image_standardization对image进行标准化操作
第六步:使用image_object.label获得label属性
第七步:使用image_object.filename获得filename属性
第八步:判断是否是随机的batch,如果是随机的使用tf.train.shuffle_batch,如果不是随机的batch,使用tf.train.batch([image, label, filename]) 获得随机的batch,返回image_batch, label_batch, filename_batch
第二部分:第一部分,获得了一个batch的数据, 第二部分,建立网络模型
第一步:使用tf.placeholder()构建image_tensor_input, 同时对image_batch_out 进行维度的变化,确认其维度为[BATCH_SIZE, 224, 224, 3]
第二步:使用tf.placeholder()构建label_tensor_input,同时构造label_offset = -tf.ones([batch_size]) ,然后使用tf.add(label_batch_out, label_offset) 将标签值从1变为0。
第三步:构造flower_inference(image_tensor_input)获得logits_batch_out, 对logists_batch 进行维度变化,确认其维度为[BATCH_SIZE, 5]
flower_inference是用于构造卷积的模型,网络的结构是卷积层5层,全连接层4层,输出层为[BATCH_SIZE, 5], 结果使用tf.nn.softmax()
第四步: 使用tf.nn.softmax_entropy_logits(logits=logits_out, labels=tf.one_hots(label_tensor_input, depth=5)) 构造loss损失函数
第五步:使用tf.train.GradientDescentOptimizer().minimize(loss) 构造train_op,降低损失值
第六步:使用with tf.Session() as sess 构造sess执行函数
第七步:使用sess.run, 进行变量的初始化操作
第八步:使用tf.train.Coordinator() 构造coord通道,使用tf.train.start_queue_runners(coord=coord, sess=sess) 构造threads多线程
第九步:进行循环,使用sess.run([image_batch, label_batch]) 获得实际的image_batch 和 label_batch
第十步:使用sess.run([train_op, logits_out, loss]) 进行训练操作
第十一步:coord.request_stop() 将coord进行关闭
第十二步:coord.join(threads) 将多线程添加到通道数,sess.close() 关闭sess
import tensorflow as tf import numpy as np import os data_path = './data/' TRAINING_SET_SIZE = 3670 BATCH_SIZE = 16 IMAGE_SIZE = 224 def create_Weight(shape): return tf.Variable(tf.truncated_normal(shape=shape, stddev=0.05)) def creat_biases(shape): return tf.Variable(tf.constant(0.1, shape=shape)) def conv2d(x, w): return tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') def maxpool(x): return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') def flower_inference(image_tensor_input): # 确认输入的图片的维度为[batchsize, 224, 224, 5] x_image = tf.reshape(image_tensor_input, [BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 3]) # 创建第一层卷积的w w_conv1 = create_Weight([5, 5, 3, 32]) # 第一层卷积的b b_conv1 = creat_biases([32]) # 进行卷积和激活操作 h_conv1 = tf.nn.relu(conv2d(x_image, w_conv1) + b_conv1) # 进行池化操作 h_pool1 = maxpool(h_conv1) # 第二层卷积的w w_conv2 = create_Weight([5, 5, 32, 64]) # 第二层卷积的b b_conv2 = creat_biases([64]) # 卷积和激活操作 h_conv2 = tf.nn.relu(conv2d(h_pool1, w_conv2) + b_conv2) # 池化操作 h_pool2 = maxpool(h_conv2) # 第三层卷积的w w_conv3 = create_Weight([5, 5, 64, 128]) # 第三层卷积的b b_conv3 = creat_biases([128]) # 卷积和激活操作 h_conv3 = tf.nn.relu(conv2d(h_pool2, w_conv3) + b_conv3) # 池化操作 h_pool3 = maxpool(h_conv3) # 第四层卷积的w w_conv4 = create_Weight([5, 5, 128, 256]) # 第四层卷积的b b_conv4 = creat_biases([256]) # 进行卷积和激活操作 h_conv4 = tf.nn.relu(conv2d(h_pool3, w_conv4) + b_conv4) # 进行池化操作 h_pool4 = maxpool(h_conv4) # 第五层卷积的w w_conv5 = create_Weight([5, 5, 256, 256]) # 第五层卷积的b b_conv5 = creat_biases([256]) # 进行卷积和激活操作 h_conv5 = tf.nn.relu(conv2d(h_pool4, w_conv5) + b_conv5) # 池化操作 h_pool5 = maxpool(h_conv5) # 将卷积后的结果进行维度的变换,以便后续进行全连接操作 fcIn = tf.reshape(h_pool5, [-1, 7*7*256]) # 第一层全连接的w w_fc1 = create_Weight([7*7*256, 2048]) # 第一层全连接的b b_fc1 = creat_biases([2048]) # 点乘和激活操作 h_fc1 = tf.nn.relu(tf.matmul(fcIn, w_fc1) + b_fc1) # dropout操作 h_fc1_dropout = tf.nn.dropout(h_fc1, 1.0) # 第二层全连接的w w_fc2 = create_Weight([2048, 256]) # 第二层全连接的b b_fc2 = creat_biases([256]) # 点乘和激活操作 h_fc2 = tf.nn.relu(tf.matmul(h_fc1_dropout, w_fc2) + b_fc2) # 第三层全连接层 w_fc3 = create_Weight([256, 64]) b_fc3 = creat_biases([64]) h_fc3 = tf.nn.relu(tf.matmul(h_fc2, w_fc3) +b_fc3) # 第四层全连接输出层 w_fc4 = create_Weight([64, 5]) b_fc4 = creat_biases([5]) # 对输出的结果使用softmax获得概率值 y_prob = tf.nn.softmax(tf.matmul(h_fc3, w_fc4) + b_fc4) return y_prob class _image_object: # 构造实例化属性 def __init__(self): # 存放图片,高度,宽度,名字和标签属性 self.image = tf.Variable([], dtype=tf.string) self.height = tf.Variable([], dtype=tf.int64) self.width = tf.Variable([], dtype=tf.int64) self.filename = tf.Variable([], dtype=tf.string) self.label = tf.Variable([], dtype=tf.int32) def read_and_decode(filename_queue): # 构造TFR的读写器 reader = tf.TFRecordReader() # 使用reader.read(filename_queue)读出存入的exmaple数据 _, serialized_exmaple = reader.read(filename_queue) # 使用tf.parse_single_example, 获得数据中属性对应的数据 features = tf.parse_single_example(serialized_exmaple, features={ 'image/encoded':tf.FixedLenFeature([], tf.string), 'image/height': tf.FixedLenFeature([], tf.int64), 'image/width': tf.FixedLenFeature([], tf.int64), 'image/filename': tf.FixedLenFeature([], tf.string), 'image/class/label': tf.FixedLenFeature([], tf.int64) }) # 获得编码的图片数据 image_decode = features['image/encoded'] # 使用tf.image.decode_jpeg 对图片进行解码操作 image_raw = tf.image.decode_jpeg(image_decode, channels=3) # 实例化函数,用于进行数据集合的存储 image_object = _image_object() # 使用tf.image.resize_image_with_crop_or_pad进行维度的变换和压缩,并存储到image.object image_object.image = tf.image.resize_image_with_crop_or_pad(image_raw,IMAGE_SIZE, IMAGE_SIZE) # 将label属性存储到image_object.label中 image_object.label = features['image/class/label'] # 将filename属性存储到image_object.filename中 image_object.filename = features['image/filename'] # 将height属性存储到image_object.height中 image_object.height = features['image/height'] # 将width属性存储到image_object.width中 image_object.width = features['image/width'] # 返回数据集合image_object return image_object # 第一步:创建flower_input,用于进行数据的创建,输入为是否训练和是否获得随机的batch值 def flower_input(if_train=True, if_random=True): # 第二步:如果是进行训练,获得训练集的文件地址 if if_train: filenames = [os.path.join(data_path, 'train-0000%d-of-00002.tfrecord'%i) for i in range(0, 2)] else: filenames = [os.path.join(data_path, 'eval-0000%d-of-00002.tfrecord'%i) for i in range(0, 2)] # 判断文件是否存在,如果不存在返回错误提醒 for f in filenames: if not tf.gfile.Exists(f): raise ValueError('the file is not exits', f) # 第三步:使用tf.train.string_input_producer()将数据输入到队列中 filename_queue = tf.train.string_input_producer(filenames) # 第四步:构造函数获得数据集合 image_object = read_and_decode(filename_queue) # 使用tf.image.per_image_standardization对图片进行标准化 image = tf.image.per_image_standardization(image_object.image) # 获得图片的标签 label = image_object.label # 获得图片的文件名 filename = image_object.filename # 如果是随机获得标签,使用tf.train.shuffle_batch if if_random: min_fraction_of_example_in_queue = 0.4 min_queue_examples = int(min_fraction_of_example_in_queue * TRAINING_SET_SIZE) num_preprocess_threads = 1 image_batch, label_batch, filename_batch = tf.train.shuffle_batch( [image, label, filename], batch_size = BATCH_SIZE, num_threads = num_preprocess_threads, capacity = min_queue_examples + 3 * BATCH_SIZE, min_after_dequeue = min_queue_examples ) # 返回batch的image,label,filename return image_batch, label_batch, filename_batch else: # 如果不是随机获得数据,使用tf.train.batch image_batch, label_batch, filename_batch = tf.train.batch( [image, label, filename], batch_size = BATCH_SIZE, num_threads = 1 ) #返回batch的image,label,filename return image_batch, label_batch, filename_batch def flower_trian(): # 第一部分:使用tf.train.batch获得一个batch的数据 image_batch_out, label_batch_out, filename_batch = flower_input(if_train=True, if_random=False) # 第二部分:构造模型,进行模型的训练,使用sess.run()获得上述的实际数据 # 第一步:使用tf.placeholder初始化输入图像,并对image_batch_out确认维度 image_tensor_input = tf.placeholder(tf.float32, [BATCH_SIZE, 224, 224, 3]) image_batch = tf.reshape(image_batch_out, [BATCH_SIZE, IMAGE_SIZE, IMAGE_SIZE, 3]) # 第二步:使用tf.placeholder初始化标签值,并构造-1的[batch_size]大小,与标签进行加和,使得标签值变成从0开始 label_tensor_input = tf.placeholder(tf.int64, [BATCH_SIZE]) label_offset = -tf.ones([BATCH_SIZE], dtype=tf.int64, name='label_offset') label_batch = tf.add(label_batch_out, label_offset) # 第三步:构造模型,带入image_tensor_input获得5个类别的概率值,维度为[BATCHSIZE, 5] logits_batch_out = flower_inference(image_tensor_input) logits_batch = tf.reshape(logits_batch_out, [BATCH_SIZE, 5]) # 第四步:使用tf.nn.sotfmax_cross(logist=logits_batch, labels=tf.one_hot() 进行对标签进行one_hot编码 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=tf.one_hot(label_tensor_input, depth=5), logits=logits_batch)) # 第五步:使用tf.train.Gradient降低损失值loss train_op = tf.train.GradientDescentOptimizer(0.0001).minimize(loss) saver = tf.train.Saver() # 第六步:使用tf.Session() 构造sess执行函数 with tf.Session() as sess: # 第七步:对参数进行初始化操作 sess.run(tf.global_variables_initializer()) # 第八步:使用tf.train.Coordinator构造通道数 coord = tf.train.Coordinator() # 第九步:使用tf.train.start_queue_runners构造sess的多线程threads threads = tf.train.start_queue_runners(coord=coord, sess=sess) for i in range(TRAINING_SET_SIZE * 10): # 第十步:使用sess.run获得实际的batch的label,image image_batch_v, label_batch_v, filename_batch_v = sess.run([image_batch, label_batch, filename_batch]) # 第十一步:进行实际的train_op, loss, logits的执行 _, infer_out, loss_out = sess.run([train_op, logits_batch, loss], feed_dict={image_tensor_input:image_batch_v, label_tensor_input:label_batch_v}) # 打印结果 if (i % 10 == 0): print('infer_out') print(infer_out) print('loss_out') print(loss_out) # 第十一步:关闭线程 coord.request_stop() # 第十二步:将线程进行添加,和关闭sess coord.join(threads) sess.close() flower_trian()