当前位置:   article > 正文

14.tensorflow:搭建分类网络并训练自己的数据_tensorflow1.x训练自己的数据集resnet图像分类

tensorflow1.x训练自己的数据集resnet图像分类

本示例可以实现的功能:

1,用tf.contrib.layers搭建分类网络(自己也可以用tf.nn搭建);2,直接通过数据的路径读取批量数据(或者直接给个包含图像路径及标签的txt,在用caffe时经常这样搞),不用转换文件格式;3,学习率衰减;4,用tensorboard观察模型的结构及训练过程中的loss, accuracy, learning rate变化情况,有助于调参;5,保存模型;6,加载训练好的模型,并对图像进行预测。

这里使用flower data数据集http://download.tensorflow.org/example_images/flower_photos.tgz

该数据分为5类。

主函数:train.py

其中get_batch用于加载批量数据。get_files返回图像路径及标签

  1. #coding:utf-8
  2. import os
  3. import numpy as np
  4. import tensorflow as tf
  5. import glob
  6. import model
  7. init_lr = 0.001
  8. decay_steps = 10000
  9. MAX_STEP = 200000
  10. N_CLASSES = 5
  11. IMG_W = 224
  12. IMG_H = 224
  13. BATCH_SIZE = 32
  14. CAPACITY = 2000
  15. os.environ["CUDA_VISIBLE_DEVICES"] = "0" # gpu编号
  16. label_dict = {'daisy':0, 'dandelion':1, 'roses':2, 'sunflowers':3, 'tulips':4} # 手动指定一个名字到label的映射关系,必须从0开始
  17. train_dir = 'flowers/flower_photos' # 该文件下放着各类图像的子文件夹这里有5个
  18. logs_train_dir = './model_save'
  19. config = tf.ConfigProto()
  20. config.gpu_options.allow_growth = True # 设置最小gpu使用量
  21. def get_batch(image, label, image_W, image_H, batch_size, capacity):
  22. image = tf.cast(image, tf.string)
  23. label = tf.cast(label, tf.int32)
  24. # make an input queue
  25. input_queue = tf.train.slice_input_producer([image, label], shuffle=False)
  26. label = input_queue[1]
  27. image_contents = tf.read_file(input_queue[0])
  28. image = tf.image.decode_jpeg(image_contents, channels=3)
  29. # 数据增强
  30. #image = tf.image.resize_image_with_pad(image, target_height=image_W, target_width=image_H)
  31. image = tf.image.resize_images(image, (image_W, image_H))
  32. # 随机左右翻转
  33. image = tf.image.random_flip_left_right(image)
  34. # 随机上下翻转
  35. image = tf.image.random_flip_up_down(image)
  36. # 随机设置图片的亮度
  37. image = tf.image.random_brightness(image, max_delta=32/255.0)
  38. # 随机设置图片的对比度
  39. image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
  40. # 随机设置图片的色度
  41. image = tf.image.random_hue(image, max_delta=0.3)
  42. # 随机设置图片的饱和度
  43. image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
  44. # 标准化,使图片的均值为0,方差为1
  45. image = tf.image.per_image_standardization(image)
  46. image_batch, label_batch = tf.train.batch([image, label],
  47. batch_size= batch_size,
  48. num_threads= 64,
  49. capacity = capacity)
  50. label_batch = tf.reshape(label_batch, [batch_size])
  51. image_batch = tf.cast(image_batch, tf.float32)
  52. return image_batch, label_batch
  53. def get_files(file_dir):
  54. image_list, label_list = [], []
  55. for label in os.listdir(file_dir):
  56. for img in glob.glob(os.path.join(file_dir, label, "*.jpg")):
  57. image_list.append(img)
  58. label_list.append(label_dict[label])
  59. print('There are %d data' %(len(image_list)))
  60. temp = np.array([image_list, label_list])
  61. temp = temp.transpose()
  62. np.random.shuffle(temp)
  63. image_list = list(temp[:, 0])
  64. label_list = list(temp[:, 1])
  65. label_list = [int(i) for i in label_list]
  66. return image_list, label_list
  67. def main():
  68. global_step = tf.Variable(0, name='global_step', trainable=False)
  69. # dataset
  70. train, train_label = get_files(train_dir)
  71. # label without one-hot
  72. batch_train, batch_labels = get_batch(train,
  73. train_label,
  74. IMG_W,
  75. IMG_H,
  76. BATCH_SIZE,
  77. CAPACITY)
  78. # network
  79. #logits = model.model2(batch_train, BATCH_SIZE, N_CLASSES)
  80. logits = model.model4(batch_train, N_CLASSES, is_trian=True)
  81. # loss
  82. cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits, labels=batch_labels)
  83. loss = tf.reduce_mean(cross_entropy, name='loss')
  84. tf.summary.scalar('train_loss', loss)
  85. # optimizer
  86. lr = tf.train.exponential_decay(learning_rate=init_lr, global_step=global_step, decay_steps=decay_steps, decay_rate=0.1)
  87. tf.summary.scalar('learning_rate', lr)
  88. optimizer = tf.train.AdamOptimizer(learning_rate=lr).minimize(loss, global_step=global_step)
  89. # accuracy
  90. correct = tf.nn.in_top_k(logits, batch_labels, 1)
  91. correct = tf.cast(correct, tf.float16)
  92. accuracy = tf.reduce_mean(correct)
  93. tf.summary.scalar('train_acc', accuracy)
  94. summary_op = tf.summary.merge_all()
  95. sess = tf.Session(config=config)
  96. train_writer = tf.summary.FileWriter(logs_train_dir, sess.graph)
  97. saver = tf.train.Saver()
  98. sess.run(tf.global_variables_initializer())
  99. coord = tf.train.Coordinator()
  100. threads = tf.train.start_queue_runners(sess=sess, coord=coord)
  101. #saver.restore(sess, logs_train_dir+'/model.ckpt-174000')
  102. try:
  103. for step in range(MAX_STEP):
  104. if coord.should_stop():
  105. break
  106. _, learning_rate, tra_loss, tra_acc = sess.run([optimizer, lr, loss, accuracy])
  107. if step % 50 == 0:
  108. print('Step %4d, lr %f, train loss = %.2f, train accuracy = %.2f%%' %(step, learning_rate, tra_loss, tra_acc*100.0))
  109. summary_str = sess.run(summary_op)
  110. train_writer.add_summary(summary_str, step)
  111. if step % 2000 == 0 or (step + 1) == MAX_STEP:
  112. checkpoint_path = os.path.join(logs_train_dir, 'model.ckpt')
  113. saver.save(sess, checkpoint_path, global_step=step)
  114. except tf.errors.OutOfRangeError:
  115. print('Done training -- epoch limit reached')
  116. finally:
  117. coord.request_stop()
  118. coord.join(threads)
  119. sess.close()
  120. if __name__ == '__main__':
  121. main()

 

模型定义:model.py

  1. #coding:utf-8
  2. from tensorflow.contrib.layers.python.layers import batch_norm
  3. import tensorflow as tf
  4. import inspect
  5. import os
  6. import numpy as np
  7. import time
  8. def model4(x, N_CLASSES, is_trian = False):
  9. x = tf.contrib.layers.conv2d(x, 64, [5, 5], 1, 'SAME', activation_fn=tf.nn.relu)
  10. x = batch_norm(x, decay=0.9, updates_collections=None, is_training=is_trian) # 训练阶段is_trainging设置为true,训练完毕后使用模型时设置为false
  11. x = tf.contrib.layers.max_pool2d(x, [2, 2], stride=2, padding='SAME')
  12. x1_1 = tf.contrib.layers.conv2d(x, 64, [1, 1], 1, 'SAME', activation_fn=tf.nn.relu) # 1X1 核
  13. x1_1 = batch_norm(x1_1, decay=0.9, updates_collections=None, is_training=is_trian)
  14. x3_3 = tf.contrib.layers.conv2d(x, 64, [3, 3], 1, 'SAME', activation_fn=tf.nn.relu) # 3x3 核
  15. x3_3 = batch_norm(x3_3, decay=0.9, updates_collections=None, is_training=is_trian)
  16. x5_5 = tf.contrib.layers.conv2d(x, 64, [5, 5], 1, 'SAME', activation_fn=tf.nn.relu) # 5x5 核
  17. x5_5 = batch_norm(x5_5, decay=0.9, updates_collections=None, is_training=is_trian)
  18. x = tf.concat([x1_1, x3_3, x5_5], axis=-1) # 连接在一起,得到64*3=192个通道
  19. x = tf.contrib.layers.max_pool2d(x, [2, 2], stride=2, padding='SAME')
  20. x1_1 = tf.contrib.layers.conv2d(x, 128, [1, 1], 1, 'SAME', activation_fn=tf.nn.relu)
  21. x1_1 = batch_norm(x1_1, decay=0.9, updates_collections=None, is_training=is_trian)
  22. x3_3 = tf.contrib.layers.conv2d(x, 128, [3, 3], 1, 'SAME', activation_fn=tf.nn.relu)
  23. x3_3 = batch_norm(x3_3, decay=0.9, updates_collections=None, is_training=is_trian)
  24. x5_5 = tf.contrib.layers.conv2d(x, 128, [5, 5], 1, 'SAME', activation_fn=tf.nn.relu)
  25. x5_5 = batch_norm(x5_5, decay=0.9, updates_collections=None, is_training=is_trian)
  26. x = tf.concat([x1_1, x3_3, x5_5], axis=-1)
  27. x = tf.contrib.layers.max_pool2d(x, [2, 2], stride=2, padding='SAME')
  28. shp = x.get_shape()
  29. x = tf.reshape(x, [-1, shp[1]*shp[2]*shp[3]]) # flatten
  30. x = tf.contrib.layers.fully_connected(x, N_CLASSES, activation_fn=None) # output logist without softmax
  31. return x
  32. def model2(images, batch_size, n_classes):
  33. '''Build the model
  34. Args:
  35. images: image batch, 4D tensor, tf.float32, [batch_size, width, height, channels]
  36. Returns:
  37. output tensor with the computed logits, float, [batch_size, n_classes]
  38. '''
  39. #conv1, shape = [kernel size, kernel size, channels, kernel numbers]
  40. with tf.variable_scope('conv1') as scope:
  41. weights = tf.get_variable('weights',
  42. shape = [3,3,3, 16],
  43. dtype = tf.float32,
  44. initializer=tf.truncated_normal_initializer(stddev=0.1,dtype=tf.float32))
  45. biases = tf.get_variable('biases',
  46. shape=[16],
  47. dtype=tf.float32,
  48. initializer=tf.constant_initializer(0.1))
  49. conv = tf.nn.conv2d(images, weights, strides=[1,1,1,1], padding='SAME')
  50. pre_activation = tf.nn.bias_add(conv, biases)
  51. conv1 = tf.nn.relu(pre_activation, name= scope.name)
  52. #pool1 and norm1
  53. with tf.variable_scope('pooling1_lrn') as scope:
  54. pool1 = tf.nn.max_pool(conv1, ksize=[1,3,3,1],strides=[1,2,2,1],
  55. padding='SAME', name='pooling1')
  56. norm1 = tf.nn.lrn(pool1, depth_radius=4, bias=1.0, alpha=0.001/9.0,
  57. beta=0.75,name='norm1')
  58. #conv2
  59. with tf.variable_scope('conv2') as scope:
  60. weights = tf.get_variable('weights',
  61. shape=[3,3,16,16],
  62. dtype=tf.float32,
  63. initializer=tf.truncated_normal_initializer(stddev=0.1,dtype=tf.float32))
  64. biases = tf.get_variable('biases',
  65. shape=[16],
  66. dtype=tf.float32,
  67. initializer=tf.constant_initializer(0.1))
  68. conv = tf.nn.conv2d(norm1, weights, strides=[1,1,1,1],padding='SAME')
  69. pre_activation = tf.nn.bias_add(conv, biases)
  70. conv2 = tf.nn.relu(pre_activation, name='conv2')
  71. #pool2 and norm2
  72. with tf.variable_scope('pooling2_lrn') as scope:
  73. norm2 = tf.nn.lrn(conv2, depth_radius=4, bias=1.0, alpha=0.001/9.0,
  74. beta=0.75,name='norm2')
  75. pool2 = tf.nn.max_pool(norm2, ksize=[1,3,3,1], strides=[1,1,1,1],
  76. padding='SAME',name='pooling2')
  77. #local3
  78. with tf.variable_scope('local3') as scope:
  79. reshape = tf.reshape(pool2, shape=[batch_size, -1])
  80. dim = reshape.get_shape()[1].value
  81. weights = tf.get_variable('weights',
  82. shape=[dim,128],
  83. dtype=tf.float32,
  84. initializer=tf.truncated_normal_initializer(stddev=0.005,dtype=tf.float32))
  85. biases = tf.get_variable('biases',
  86. shape=[128],
  87. dtype=tf.float32,
  88. initializer=tf.constant_initializer(0.1))
  89. local3 = tf.nn.relu(tf.matmul(reshape, weights) + biases, name=scope.name)
  90. #local4
  91. with tf.variable_scope('local4') as scope:
  92. weights = tf.get_variable('weights',
  93. shape=[128,128],
  94. dtype=tf.float32,
  95. initializer=tf.truncated_normal_initializer(stddev=0.005,dtype=tf.float32))
  96. biases = tf.get_variable('biases',
  97. shape=[128],
  98. dtype=tf.float32,
  99. initializer=tf.constant_initializer(0.1))
  100. local4 = tf.nn.relu(tf.matmul(local3, weights) + biases, name='local4')
  101. # full connect
  102. with tf.variable_scope('softmax_linear') as scope:
  103. weights = tf.get_variable('softmax_linear',
  104. shape=[128, n_classes],
  105. dtype=tf.float32,
  106. initializer=tf.truncated_normal_initializer(stddev=0.005,dtype=tf.float32))
  107. biases = tf.get_variable('biases',
  108. shape=[n_classes],
  109. dtype=tf.float32,
  110. initializer=tf.constant_initializer(0.1))
  111. logits = tf.add(tf.matmul(local4, weights), biases, name='softmax_linear')
  112. return logits

 

加载训练好的模型并进行预测,predict.py:

  1. #coding:utf-8
  2. import os, cv2
  3. #os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # use cpu
  4. import numpy as np
  5. import tensorflow as tf
  6. from PIL import Image
  7. import matplotlib.pyplot as plt
  8. import glob
  9. import model
  10. N_CLASSES = 5
  11. IMG_W = 224
  12. IMG_H = IMG_W
  13. os.environ["CUDA_VISIBLE_DEVICES"] = "0" # use gpu 0
  14. label_dict = {'daisy':0, 'dandelion':1, 'roses':2, 'sunflowers':3, 'tulips':4}
  15. label_dict_res = {v:k for k,v in label_dict.items()}
  16. config = tf.ConfigProto()
  17. config.gpu_options.allow_growth = True
  18. def init_tf(logs_train_dir = './model_save/model.ckpt-174000'):
  19. global sess, pred, x
  20. # process image
  21. x = tf.placeholder(tf.float32, shape=[IMG_W, IMG_W, 3])
  22. x_norm = tf.image.per_image_standardization(x)
  23. x_4d = tf.reshape(x_norm, [1, IMG_W, IMG_W, 3])
  24. # predict
  25. logit = model.model4(x_4d, N_CLASSES, is_trian=False)
  26. #logit = model.model2(x_4d, batch_size=1, n_classes=N_CLASSES)
  27. pred = tf.nn.softmax(logit)
  28. saver = tf.train.Saver()
  29. sess = tf.Session(config=config)
  30. saver.restore(sess, logs_train_dir)
  31. print('load model done...')
  32. def evaluate_image(img_dir):
  33. # read image
  34. im = cv2.imread(img_dir)
  35. im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
  36. im = cv2.resize(im, (IMG_W, IMG_W))
  37. image_array = np.array(im)
  38. prediction = sess.run(pred, feed_dict={x: image_array})
  39. max_index = np.argmax(prediction)
  40. print("%s, predict: %s, prob: %f" %(os.path.basename(img_dir), label_dict_res[max_index], prediction[0][max_index]))
  41. if __name__ == '__main__':
  42. init_tf()
  43. # data_path = 'flowers/flower_photos'
  44. # label = os.listdir(data_path)
  45. # for l in label:
  46. # if os.path.isfile(os.path.join(data_path, l)):
  47. # continue
  48. # for img in glob.glob(os.path.join(data_path, l, "*.jpg")):
  49. # print(img)
  50. # evaluate_image(img_dir=img)
  51. for img in glob.glob("./*.jpg"):
  52. evaluate_image(img)
  53. sess.close()

实现批量预测,同时预测多张图像,节约时间, predict_batch.py:

  1. #coding:utf-8
  2. import os, cv2, time
  3. #os.environ["CUDA_VISIBLE_DEVICES"] = "-1" # use cpu
  4. import numpy as np
  5. import tensorflow as tf
  6. from PIL import Image
  7. import matplotlib.pyplot as plt
  8. import glob
  9. import model
  10. N_CLASSES = 5
  11. IMG_W = 224
  12. IMG_H = IMG_W
  13. batch_size = 32
  14. os.environ["CUDA_VISIBLE_DEVICES"] = "0" # use gpu 0
  15. label_dict = {'daisy':0, 'dandelion':1, 'roses':2, 'sunflowers':3, 'tulips':4}
  16. label_dict_res = {v:k for k,v in label_dict.items()}
  17. config = tf.ConfigProto()
  18. config.gpu_options.allow_growth = True
  19. def get_imgpath(path):
  20. img_list = []
  21. for fpath , dirs , fs in os.walk(path):
  22. for f in fs:
  23. img_path = os.path.join(fpath , f)
  24. if os.path.dirname(img_path) == os.getcwd():
  25. continue
  26. if not os.path.isfile(img_path):
  27. continue
  28. if os.path.basename(img_path)[-3:] == "jpg":
  29. img_list.append(img_path)
  30. return img_list
  31. def init_tf(logs_train_dir = './model_save/model.ckpt-174000'):
  32. global sess, pred, x
  33. # process image
  34. x = tf.placeholder(tf.float32, shape=[None, IMG_W, IMG_W, 3])
  35. # predict
  36. logit = model.model4(x, N_CLASSES, is_trian=False)
  37. #logit = model.model2(x_4d, batch_size=1, n_classes=N_CLASSES)
  38. pred = tf.nn.softmax(logit)
  39. saver = tf.train.Saver()
  40. sess = tf.Session(config=config)
  41. saver.restore(sess, logs_train_dir)
  42. print('load model done...')
  43. def evaluate_image(img_dir):
  44. # read and process image
  45. batch_img = []
  46. for img in img_dir:
  47. im = cv2.imread(img)
  48. im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
  49. im = cv2.resize(im, (IMG_W, IMG_W))
  50. im_mean = np.mean(im)
  51. stddev = max(np.std(im), 1.0/np.sqrt(IMG_W*IMG_H*3))
  52. im = (im - im_mean) / stddev
  53. image_array = np.array(im)
  54. batch_img.append(image_array)
  55. # output sotfmax
  56. prediction = sess.run(pred, feed_dict={x: batch_img})
  57. for i in range(len(img_dir)):
  58. img = img_dir[i]
  59. max_index = np.argmax(prediction[i])
  60. print("img:%s, predict: %s, prob: %f" % (img, label_dict_res[max_index], prediction[i][max_index]))
  61. if __name__ == '__main__':
  62. init_tf()
  63. data_path = 'flowers/flower_photos'
  64. img_list = get_imgpath(data_path)
  65. total_batch = len(img_list)/batch_size
  66. start = time.time()
  67. for i in range(total_batch):
  68. print(str(i) + "-"*50)
  69. batch_img = img_list[i*batch_size: (i+1)*batch_size]
  70. evaluate_image(batch_img)
  71. print("time cost:", time.time()-start)
  72. sess.close()

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/92760
推荐阅读
相关标签
  

闽ICP备14008679号