注:可参考实现的方法,但目前参数尚未调好,效果欠佳。
分图片预处理库和训练两个文件
1.ulibs.py
2.AlexNet.py
----------------------------------------------------------------
ulibs.py:
import cv2 import os import numpy as np import tensorflow as tf def resize_img(in_dir, out_dir=None, dim=(227, 227)): '''参考《TensorFlow深度学习应用实践》p171''' os.makedirs(out_dir, exist_ok=True) for file in os.listdir(in_dir): filepath = os.path.join(in_dir, file) print("HHHA:0====>", filepath) try: image = cv2.imread(filepath) resized = cv2.resize(image, dim) path = os.path.join(out_dir, file) cv2.imwrite(path, resized) except: print("【图片无法转换】:", filepath) #os.remove(filepath) cv2.waitKey(0) def resize_img_test(): resize_img("./data/cat_and_dog/train/dog/", "./data/cat_and_dog/train_r/dog/") def get_file(file_dir): images = [] temp = [] for root, sub_folders, files in os.walk(file_dir): print("HHHA:0====>root", root) print("HHHA:1====>sub_folders", sub_folders) #print("HHHA:2====>files", files) # image directories for name in files: images.append(os.path.join(root, name)) # get 10 sub-folder names for name in sub_folders: temp.append(os.path.join(root, name)) #print(files) # assign 10 labes based on the folder names labels = [] for one_folder in temp: print("HHHA:3====>", one_folder) n_img = len(os.listdir(one_folder)) letter = one_folder.split('\\')[-1] if letter == 'cat': labels = np.append(labels, n_img*[0]) else: labels = np.append(labels, n_img*[1]) # shuffle temp = np.array([images, labels]) temp = temp.transpose() np.random.shuffle(temp) image_list = list(temp[:, 0]) label_list = list(temp[:, 1]) label_list = [int(float(i)) for i in label_list] return image_list, label_list def get_file_test(): image_list, label_list = get_file("./data/cat_and_dog/train_r") def convert_to_tfrecord(images_list, labels_list, save_dir, name): filename = os.path.join(save_dir, name + '.tfrecodes') n_samples = len(labels_list) writer = tf.python_io.TFRecordWriter(filename) print("\nTransform start......(%d in total)", n_samples) for i in np.arange(0, n_samples): print("HHHA:====>", images_list[i]) try: image = cv2.imread(images_list[i]) # type(image) must be array! image_raw = image.tostring() label = int(labels_list[i]) example = tf.train.Example(features=tf.train.Features( feature={'' 'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[label])), 'image_aw': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image_raw])) })) writer.write(example.SerializeToString()) except IOError as e: print("Could not read:", images_list[i]) writer.close() print("Transform done!") def convert_to_tfrecord_test(): images_list, labels_list = get_file("./data/cat_and_dog/train_r") convert_to_tfrecord(images_list, labels_list, "./data/cat_and_dog/", "cat_and_dog_train_r") def read_and_decode(tfrecords_file, batch_size): filename_queue = tf.train.string_input_producer([tfrecords_file]) reader = tf.TFRecordReader() _, serialized_exampple = reader.read(filename_queue) img_features = tf.parse_single_example(serialized_exampple, features={ 'label': tf.FixedLenFeature([], tf.int64), 'image_raw': tf.FixedLenFeature([], tf.string), }) image = tf.decode_raw(img_features['image_raw'], tf.uint8) image = tf.reshape(image, [227, 227, 3]) label = tf.cast(img_features['label'], tf.int32) image_batch, label_batch = tf.train.shuffle_batch([image, label], batch_size=batch_size, min_after_dequeue=100, num_threads=64, capacity=200) return image_batch, tf.reshape(label_batch, [batch_size]) def read_and_decode_test(): image_batch, label_batch= read_and_decode("./data/cat_and_dog/cat_and_dog_train_r.tfrecodes", batch_size=100) def get_batch(image_list, label_list, img_width, img_height, batch_size, capacity): image = tf.cast(image_list, tf.string) label = tf.cast(label_list, tf.int32) input_queue = tf.train.slice_input_producer([image, label]) label = input_queue[1] image_contents = tf.read_file(input_queue[0]) image = tf.image.decode_jpeg(image_contents, channels=3) image = tf.image.resize_image_with_crop_or_pad(image, img_width, img_height) image = tf.image.per_image_standardization(image) image_batch, label_batch = tf.train.batch([image, label], batch_size=batch_size, num_threads=64, capacity=capacity) label_batch = tf.reshape(label_batch, [batch_size]) return image_batch, label_batch def get_batch_test(): images_list, labels_list = get_file("./data/cat_and_dog/train_r") image_batch, label_batch = get_batch(images_list, labels_list, 227, 227, 50, 200) def onehot(labels): """one-hot 编码""" n_sample = len(labels) n_class = max(labels) + 1 onehot_labels = np.zeros((n_sample, n_class)) onehot_labels[np.arange(n_sample), labels] = 1 return onehot_labels if __name__ == "__main__": #convert_to_tfrecord_test() read_and_decode_test()
AlexNet.py
import tensorflow as tf import numpy as np import matplotlib.pyplot as plt import time import ulibs import os from PIL import Image os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' X_train, y_train = ulibs.get_file("./data/cat_and_dog/train_r") image_batch, label_batch = ulibs.get_batch(X_train, y_train, 227, 227, 200, 2048) save_model = "./data/model/AlexNetModel.ckpt" def batch_norm(inputs, is_training, is_conv_out=True, decay=0.999): scale = tf.Variable(tf.ones([inputs.get_shape()[-1]])) beta = tf.Variable(tf.zeros([inputs.get_shape()[-1]])) pop_mean = tf.Variable(tf.zeros([inputs.get_shape()[-1]]), trainable=False) pop_var = tf.Variable(tf.ones([inputs.get_shape()[-1]]), trainable=False) if is_training: if is_conv_out: batch_mean, batch_var = tf.nn.moments(inputs, [0, 1, 2]) else: batch_mean, batch_var = tf.nn.moments(inputs, [0]) train_mean = tf.assign(pop_mean, pop_mean * decay + batch_mean * (1 - decay)) train_var = tf.assign(pop_var, pop_var * decay + batch_var * (1 - decay)) with tf.control_dependencies([train_mean, train_var]): return tf.nn.batch_normalization(inputs, batch_mean, batch_var, beta, scale, 0.001) else: return tf.nn.batch_normalization(inputs, pop_mean, pop_var, beta, scale, 0.001) with tf.device('/cpu:0'): #模型参数 learning_rate = 1e-4 training_iters = 200 batch_size = 200 display_step = 5 n_classes = 2 n_fc1 = 4096 n_fc2 = 2048 #构建模型 x = tf.placeholder(tf.float32, [None, 227, 227, 3]) y = tf.placeholder(tf.int32, [None, n_classes]) # # W_conv = { # 'conv1': tf.Variable(tf.truncated_normal([11, 11, 3, 96], stddev=0.1)), # 'conv2': tf.Variable(tf.truncated_normal([5, 5, 96, 256], stddev=0.01)), # 'conv3': tf.Variable(tf.truncated_normal([3, 3, 256, 384], stddev=0.01)), # 'conv4': tf.Variable(tf.truncated_normal([3, 3, 384, 384], stddev=0.01)), # 'conv5': tf.Variable(tf.truncated_normal([3, 3, 384, 256], stddev=0.01)), # 'fc1': tf.Variable(tf.truncated_normal([6 * 6 * 256, n_fc1], stddev=0.1)), # 'fc2': tf.Variable(tf.truncated_normal([n_fc1, n_fc2], stddev=0.1)), # 'fc3': tf.Variable(tf.truncated_normal([n_fc2, n_classes], stddev=0.1)), # } # b_conv = { # 'conv1': tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[96])), # 'conv2': tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[256])), # 'conv3': tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[384])), # 'conv4': tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[384])), # 'conv5': tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[256])), # 'fc1': tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[n_fc1])), # 'fc2': tf.Variable(tf.constant(0.1, dtype=tf.float32, shape=[n_fc2])), # 'fc3': tf.Variable(tf.constant(0.0, dtype=tf.float32, shape=[n_classes])), # } W_conv = { 'conv1': tf.get_variable('W_conv1', [11, 11, 3, 96], initializer=tf.truncated_normal_initializer(stddev=0.001)), 'conv2': tf.get_variable('W_conv2', [5, 5, 96, 256], initializer=tf.truncated_normal_initializer(stddev=0.01)), 'conv3': tf.get_variable('W_conv3', [3, 3, 256, 384], initializer=tf.truncated_normal_initializer(stddev=0.01)), 'conv4': tf.get_variable('W_conv4', [3, 3, 384, 384], initializer=tf.truncated_normal_initializer(stddev=0.01)), 'conv5': tf.get_variable('W_conv5', [3, 3, 384, 256], initializer=tf.truncated_normal_initializer(stddev=0.01)), 'fc1': tf.get_variable('W_fc1', [6 * 6 * 256, n_fc1], initializer=tf.truncated_normal_initializer(stddev=0.1)), 'fc2': tf.get_variable('W_fc2', [n_fc1, n_fc2], initializer=tf.truncated_normal_initializer(stddev=0.1)), 'fc3': tf.get_variable('W_fc3', [n_fc2, n_classes], initializer=tf.truncated_normal_initializer(stddev=0.1)), } b_conv = { 'conv1': tf.get_variable('b_conv1', [96], initializer=tf.constant_initializer(0.0)), 'conv2': tf.get_variable('b_conv2',[256], initializer=tf.constant_initializer(0.1)), 'conv3': tf.get_variable('b_conv3',[384], initializer=tf.constant_initializer(0.1)), 'conv4': tf.get_variable('b_conv4', [384], initializer=tf.constant_initializer(0.1)), 'conv5': tf.get_variable('b_conv5', [256], initializer=tf.constant_initializer(0.1)), 'fc1': tf.get_variable('b_fc1', [n_fc1], initializer=tf.constant_initializer(0.1)), 'fc2': tf.get_variable('b_fc2', [n_fc2], initializer=tf.constant_initializer(0.1)), 'fc3': tf.get_variable('b_fc3', [n_classes], initializer=tf.constant_initializer(0.0)), } x_image = tf.reshape(x, [-1, 227, 227, 3]) #卷积层 1 conv1 = tf.nn.conv2d(x_image, W_conv['conv1'], strides=[1, 4, 4, 1], padding='VALID') conv1 = tf.nn.bias_add(conv1, b_conv['conv1']) con1 = tf.nn.relu(conv1) #池化层 1 pool1 = tf.nn.avg_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID') #LRN层,Local Response Normalization norm1 = tf.nn.lrn(pool1, 5, bias=1.0, alpha=0.001/9.0, beta=0.75) #卷积层 2 conv2 = tf.nn.conv2d(norm1, W_conv['conv2'], strides=[1, 1, 1, 1], padding="SAME") conv2 = tf.nn.bias_add(conv2, b_conv['conv2']) conv2 = tf.nn.relu(conv2) #池化层 2 pool2 = tf.nn.avg_pool(conv2, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID') # LRN 层 Local Response Normalization norm2 = tf.nn.lrn(pool2, 5, bias=1.0, alpha=0.001/9.0, beta=0.75) #卷积层 3 conv3 = tf.nn.conv2d(norm2, W_conv['conv3'], strides=[1, 1, 1, 1], padding='SAME') conv3 = tf.nn.bias_add(conv3, b_conv['conv3']) conv3 = tf.nn.relu(conv3) #卷积层 4 conv4 = tf.nn.conv2d(conv3, W_conv['conv4'], strides=[1, 1, 1, 1], padding="SAME") conv4 = tf.nn.bias_add(conv4, b_conv['conv4']) conv4 = tf.nn.relu(conv4) #卷积层 5 conv5 = tf.nn.conv2d(conv4, W_conv['conv5'], strides=[1, 1, 1, 1], padding='SAME') conv5 = tf.nn.bias_add(conv5, b_conv['conv5']) conv5 = tf.nn.relu(conv5) #池化层 5 pool5 = tf.nn.avg_pool(conv5, ksize=[1, 3, 3, 1], strides=[1, 2, 2, 1], padding='VALID') #全连接层 1 reshape = tf.reshape(pool5, [-1, 6 * 6 * 256]) #全连接层 fc1 = tf.add(tf.matmul(reshape, W_conv['fc1']), b_conv['fc1']) fc1 = tf.nn.relu(fc1) fc1 = tf.nn.dropout(fc1, 0.5) #全连接层 2 fc2 = tf.add(tf.matmul(fc1, W_conv['fc2']), b_conv['fc2']) fc2 = tf.nn.relu(fc2) fc2 = tf.nn.dropout(fc2, 0.5) #全连接层 3,即分类层 fc3 = tf.add(tf.matmul(fc2, W_conv['fc3']), b_conv['fc3']) #定义损失 loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=fc3, labels=y)) optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate).minimize(loss) #评估模型 correct_pred = tf.equal(tf.argmax(fc3, 1), tf.argmax(y, 1)) accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32)) def train(epoch): with tf.Session() as sess: sess.run(tf.global_variables_initializer()) train_writer = tf.summary.FileWriter("./data/log", sess.graph) saver = tf.train.Saver() c = [] start_time = time.time() coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(coord=coord) step = 0 for i in range(epoch): step = i image, label = sess.run([image_batch, label_batch]) labels = ulibs.onehot(label) #labels = tf.one_hot(label, 2, 1, 0) sess.run(optimizer, feed_dict={x: image, y: labels}) loss_recode = sess.run(loss, feed_dict={x: image, y: labels}) print("now the loss is %f" % loss_recode) c.append(loss_recode) end_time = time.time() print("time: ", (end_time - start_time)) start_time = end_time print("-------------%d onpech is finished -------------" % i) print("Optimization Finished!") saver.save(sess, save_model) print("Model Save Finished!") coord.request_stop() coord.join(threads) plt.plot(c) plt.xlabel('Iter') plt.ylabel('loss') plt.title('lr=%f, ti=%d,bs=%d' % (learning_rate, training_iters, batch_size)) plt.tight_layout() plt.savefig("./data/cat_and_dog_AlexNet.jpg", dpi=200) def per_class(imagefile): image = Image.open(imagefile) image = image.resize([227, 227]) image_array = np.array(image) image = tf.cast(image_array, tf.float32) image = tf.image.per_image_standardization(image) image = tf.reshape(image, [1, 227, 227, 3]) saver = tf.train.Saver() with tf.Session() as sess: save_model = tf.train.latest_checkpoint("./data/model") saver.restore(sess, save_model) image = tf.reshape(image, [1, 227, 227, 3]) image = sess.run(image) prediction = sess.run(fc3, feed_dict={x: image}) max_index = np.argmax(prediction) if max_index == 0: return "cat" else: return "dog" imagefile = "./data/cat_and_dog/train" cat = dog = 0 train(100) for root, sub_folders, files in os.walk(imagefile): print("root=%s,sub_folders=%s, files=%s" % (root, sub_folders, files)) for name in files: imagefile = os.path.join(root, name) print(imagefile) if per_class(imagefile) == "cat": print("prediction:cat") cat += 1 else: print("prediction:dog") dog += 1 print("cat is :", cat, " |dog is : ", dog)