diff --git a/load_datas.py b/load_datas.py
new file mode 100644
index 0000000..c533edf
--- /dev/null
+++ b/load_datas.py
@@ -0,0 +1,95 @@
+#############################################################################################################
+# load features and labels #
+# feature dimension : (N,d), (i.e., N*4096), label dimension : (N,) #
+# type of all the output will be "list" #
+#############################################################################################################
+# There are two different setting of training and testing : #
+# The default setting (setting-0) is splitting the dataset into two parts, half for training, half for #
+# testing. Training index: lab-1234, office-123, house-123. Testing index: lab-5678, office-456, house-456 #
+#############################################################################################################
+
+import sys, os
+import numpy as np
+import pdb
+import warnings
+import re
+
+def load_one_label_seq(path):
+ npy = np.load(path)
+ return npy
+
+
+def load_label_seqs(path, mode, index):
+ labels=[]
+ for i in range(len(index)):
+ loc = index[i][0]
+ idx = index[i][1]
+ labelnpy = os.path.join(path,loc,mode+"_left"+str(idx)+'.npy')
+ labels.append(load_one_label_seq(labelnpy))
+ labelnpy = os.path.join(path,loc,mode+"_right"+str(idx)+'.npy')
+ labels.append(load_one_label_seq(labelnpy))
+
+ return labels
+
+def gen_index(setting_index):
+ train_index=[]
+ test_index =[]
+ if setting_index == 0:
+ for i in range(1,9):
+ if i <= 4:
+ train_index.append(('lab',i))
+ else:
+ test_index.append(('lab',i))
+ for i in range(1,7):
+ if i <= 3:
+ train_index.append(('office',i))
+ else:
+ test_index.append(('office',i))
+ for i in range(1,7):
+ if i <= 3:
+ train_index.append(('house',i))
+ else:
+ test_index.append(('house',i))
+ else:
+ raise ValueError ('error setting index')
+
+ return train_index, test_index
+
+
+
+def gen_index_process(index=None, setting_index=None):
+ if index == None:
+ if setting_index==None:
+ raise ValueError('Setting index can not be none')
+ else:
+ train_index, test_index = gen_index(setting_index)
+ return train_index, test_index
+
+
+def load_train_labels(path, mode, index=None, setting_index=None):
+ if index == None:
+ index,_ = gen_index_process(index,setting_index)
+ else:
+ if setting_index != None:
+ warnings.warn('setting_index has no effect when given particular index')
+ labels = load_label_seqs(path, mode, index)
+ return labels
+
+def load_test_labels(path, mode, index=None, setting_index=None):
+ if index == None:
+ _,index = gen_index_process(index,setting_index)
+ else:
+ if setting_index != None:
+ warnings.warn('setting_index has no effect when given particular index')
+ labels = load_label_seqs(path, mode, index)
+ return labels
+
+
+def load_all_labels(path, mode, setting_index):
+ train_index, test_index = (setting_index)
+ train_labels = load_train_labels(path, mode,train_index)
+ test_labels = load_train_labels(path, mode,test_index)
+ return train_labels, test_labels
+
+
+
diff --git a/results/index.md b/results/index.md
index 96ce61c..690b17e 100644
--- a/results/index.md
+++ b/results/index.md
@@ -1,25 +1,26 @@
-# Your Name (id)
+# 高穎 106062525 (id)
#Project 5: Deep Classification
## Overview
The project is related to
-> quote
+ >tensorflow
+ >vgg16
+>model和權重如下
+https://drive.google.com/drive/folders/0B4i3Xp6AJX7YSExOMEMxYTBxWnM?usp=sharing
## Implementation
-1. One
- * item
- * item
-2. Two
+1. tensorflow_finetune
+ 用ImageNet pretrain好的vgg16參數,前七層不改,最後一層fc重新train.每train一個epoch就把train好的權重記下來
+2. load_datas
+ load training和test的label
+3.tensorflow_test
+ 用記下來的權重加上test的檔案計算準確度,因為時間不夠所以沒有test完全部資料夾,只test了lab資料夾 準確度0.41
-```
-Code highlights
-```
## Installation
-* Other required packages.
-* How to compile from source?
+* 用anaconda建一個有tensorflow的虛擬環境,利用spyder編譯
### Results
diff --git a/tensorflow_finetune.py b/tensorflow_finetune.py
new file mode 100644
index 0000000..d6793db
--- /dev/null
+++ b/tensorflow_finetune.py
@@ -0,0 +1,323 @@
+
+
+import argparse
+import os
+
+import tensorflow as tf
+import tensorflow.contrib.slim as slim
+import tensorflow.contrib.slim.nets
+from load_datas import *
+
+#path_data= os.environ.get("GRAPE_DATASET_DIR")
+#frames_path=os.path.join(path_data,'frames/train')
+frames_path='./train'
+#labels_path=os.path.join(path_data,'labels')
+labels_path='./labels'
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--train_dir', default=frames_path)
+parser.add_argument('--label_dir', default=labels_path)
+parser.add_argument('--model_path', default='vgg_16.ckpt', type=str)
+parser.add_argument('--batch_size', default=32, type=int)
+parser.add_argument('--num_workers', default=4, type=int)
+parser.add_argument('--num_epochs1', default=1, type=int)
+parser.add_argument('--num_epochs2', default=1, type=int)
+parser.add_argument('--learning_rate1', default=1e-3, type=float)
+parser.add_argument('--learning_rate2', default=1e-5, type=float)
+parser.add_argument('--dropout_keep_prob', default=0.5, type=float)
+parser.add_argument('--weight_decay', default=5e-4, type=float)
+
+VGG_MEAN = [123.68, 116.78, 103.94]
+
+def load_file_seqs(path,index):
+ file_name=[]
+
+ for i in range(len(index)):
+ file_name_L=[]
+ file_name_R=[]
+ loc = index[i][0]
+ idx = str(index[i][1])
+ for i in os.listdir(os.path.join(path,loc,idx,"Lhand")):
+ file_name_L.append(os.path.join(path,loc,idx,"Lhand", i))
+ file_name_L = sorted(file_name_L, key=lambda x: int(re.sub('\D', '', x)))
+
+ for i in os.listdir(os.path.join(path,loc,idx,"Rhand")):
+ file_name_R.append(os.path.join(path,loc,idx,"Rhand", i))
+ file_name_R = sorted(file_name_R, key=lambda x: int(re.sub('\D', '', x)))
+
+ file_name+=file_name_L
+ file_name+=file_name_R
+ return file_name
+
+def load_files(path):
+ file_index=[]
+ for i in range(1,5):
+ file_index.append(('lab',i))
+ for i in range(1,4):
+ file_index.append(('office',i))
+ for i in range(1,4):
+ file_index.append(('house',i))
+ file_names=load_file_seqs(path,file_index)
+ return file_names
+
+def check_accuracy(sess, correct_prediction, is_training, dataset_init_op):
+ """
+ Check the accuracy of the model on either train or val (depending on dataset_init_op).
+ """
+ # Initialize the correct dataset
+ sess.run(dataset_init_op)
+ num_correct, num_samples = 0, 0
+ while True:
+ try:
+ correct_pred = sess.run(correct_prediction, {is_training: False})
+ num_correct += correct_pred.sum()
+ num_samples += correct_pred.shape[0]
+ except tf.errors.OutOfRangeError:
+ break
+
+ # Return the fraction of datapoints that were correctly classified
+ acc = float(num_correct) / num_samples
+ return acc
+
+
+def main(args):
+ # Get the list of filenames and corresponding list of labels for training et validation
+ train_filenames = load_files(args.train_dir)
+ labels=load_train_labels(args.label_dir,'obj',setting_index=0)
+ unique_labels={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}
+
+ label_to_int = {}
+ for i, label in enumerate(unique_labels):
+ label_to_int[label] = i
+
+ train_labels=[]
+ for i in range(len(labels)):
+ labels[i] = [label_to_int[l] for l in labels[i]]
+ train_labels+= labels[i]
+ print(type(train_labels))
+ print(type(train_filenames))
+
+
+
+ num_classes=24
+ # --------------------------------------------------------------------------
+ # In TensorFlow, you first want to define the computation graph with all the
+ # necessary operations: loss, training op, accuracy...
+ # Any tensor created in the `graph.as_default()` scope will be part of `graph`
+ graph = tf.Graph()
+ with graph.as_default():
+ # Standard preprocessing for VGG on ImageNet taken from here:
+ # https://github.com/tensorflow/models/blob/master/slim/preprocessing/vgg_preprocessing.py
+ # Also see the VGG paper for more details: https://arxiv.org/pdf/1409.1556.pdf
+
+ # Preprocessing (for both training and validation):
+ # (1) Decode the image from jpg format
+ # (2) Resize the image so its smaller side is 256 pixels long
+ def _parse_function(filename, label):
+ image_string = tf.read_file(filename)
+ image_decoded = tf.image.decode_png(image_string, channels=3) # (1)
+ image = tf.cast(image_decoded, tf.float32)
+
+ smallest_side = 256.0
+ height, width = tf.shape(image)[0], tf.shape(image)[1]
+ height = tf.to_float(height)
+ width = tf.to_float(width)
+
+ scale = tf.cond(tf.greater(height, width),
+ lambda: smallest_side / width,
+ lambda: smallest_side / height)
+ new_height = tf.to_int32(height * scale)
+ new_width = tf.to_int32(width * scale)
+
+ resized_image = tf.image.resize_images(image, [new_height, new_width]) # (2)
+ return resized_image, label
+
+ # Preprocessing (for training)
+ # (3) Take a random 224x224 crop to the scaled image
+ # (4) Horizontally flip the image with probability 1/2
+ # (5) Substract the per color mean `VGG_MEAN`
+ # Note: we don't normalize the data here, as VGG was trained without normalization
+ def training_preprocess(image, label):
+ crop_image = tf.random_crop(image, [224, 224, 3]) # (3)
+ flip_image = tf.image.random_flip_left_right(crop_image) # (4)
+
+ means = tf.reshape(tf.constant(VGG_MEAN), [1, 1, 3])
+ centered_image = flip_image - means # (5)
+
+ return centered_image, label
+
+ # Preprocessing (for validation)
+ # (3) Take a central 224x224 crop to the scaled image
+ # (4) Substract the per color mean `VGG_MEAN`
+ # Note: we don't normalize the data here, as VGG was trained without normalization
+# def val_preprocess(image, label):
+ # crop_image = tf.image.resize_image_with_crop_or_pad(image, 224, 224) # (3)
+#
+ # means = tf.reshape(tf.constant(VGG_MEAN), [1, 1, 3])
+ # centered_image = crop_image - means # (4)
+#
+ # return centered_image, label
+
+ # ----------------------------------------------------------------------
+ # DATASET CREATION using tf.contrib.data.Dataset
+ # https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/data
+
+ # The tf.contrib.data.Dataset framework uses queues in the background to feed in
+ # data to the model.
+ # We initialize the dataset with a list of filenames and labels, and then apply
+ # the preprocessing functions described above.
+ # Behind the scenes, queues will load the filenames, preprocess them with multiple
+ # threads and apply the preprocessing in parallel, and then batch the data
+ # Training dataset
+ train_filenames = tf.constant(train_filenames)
+ train_labels = tf.constant(train_labels)
+ train_dataset = tf.contrib.data.Dataset.from_tensor_slices((train_filenames, train_labels))
+ train_dataset = train_dataset.map(_parse_function,
+ num_threads=args.num_workers, output_buffer_size=args.batch_size)
+ train_dataset = train_dataset.map(training_preprocess,
+ num_threads=args.num_workers, output_buffer_size=args.batch_size)
+ train_dataset = train_dataset.shuffle(buffer_size=10000) # don't forget to shuffle
+ batched_train_dataset = train_dataset.batch(args.batch_size)
+
+ # Validation dataset
+ # val_filenames = tf.constant(val_filenames)
+ # val_labels = tf.constant(val_labels)
+ # val_dataset = tf.contrib.data.Dataset.from_tensor_slices((val_filenames, val_labels))
+ # val_dataset = val_dataset.map(_parse_function,
+ # num_threads=args.num_workers, output_buffer_size=args.batch_size)
+ # val_dataset = val_dataset.map(val_preprocess,
+ # num_threads=args.num_workers, output_buffer_size=args.batch_size)
+ #batched_val_dataset = val_dataset.batch(args.batch_size)
+
+
+ # Now we define an iterator that can operator on either dataset.
+ # The iterator can be reinitialized by calling:
+ # - sess.run(train_init_op) for 1 epoch on the training set
+ # - sess.run(val_init_op) for 1 epoch on the valiation set
+ # Once this is done, we don't need to feed any value for images and labels
+ # as they are automatically pulled out from the iterator queues.
+
+ # A reinitializable iterator is defined by its structure. We could use the
+ # `output_types` and `output_shapes` properties of either `train_dataset`
+ # or `validation_dataset` here, because they are compatible.
+ iterator = tf.contrib.data.Iterator.from_structure(batched_train_dataset.output_types,
+ batched_train_dataset.output_shapes)
+ images, labels = iterator.get_next()
+
+ train_init_op = iterator.make_initializer(batched_train_dataset)
+# val_init_op = iterator.make_initializer(batched_val_dataset)
+
+ # Indicates whether we are in training or in test mode
+ is_training = tf.placeholder(tf.bool)
+
+
+ # ---------------------------------------------------------------------
+ # Now that we have set up the data, it's time to set up the model.
+ # For this example, we'll use VGG-16 pretrained on ImageNet. We will remove the
+ # last fully connected layer (fc8) and replace it with our own, with an
+ # output size num_classes=8
+ # We will first train the last layer for a few epochs.
+ # Then we will train the entire model on our dataset for a few epochs.
+
+ # Get the pretrained model, specifying the num_classes argument to create a new
+ # fully connected replacing the last one, called "vgg_16/fc8"
+ # Each model has a different architecture, so "vgg_16/fc8" will change in another model.
+ # Here, logits gives us directly the predicted scores we wanted from the images.
+ # We pass a scope to initialize "vgg_16/fc8" weights with he_initializer
+ vgg = tf.contrib.slim.nets.vgg
+ with slim.arg_scope(vgg.vgg_arg_scope(weight_decay=args.weight_decay)):
+ logits, _ = vgg.vgg_16(images, num_classes=num_classes, is_training=is_training,
+ dropout_keep_prob=args.dropout_keep_prob)
+
+ # Specify where the model checkpoint is (pretrained weights).
+ model_path = args.model_path
+ assert(os.path.isfile(model_path))
+
+ # Restore only the layers up to fc7 (included)
+ # Calling function `init_fn(sess)` will load all the pretrained weights.
+ variables_to_restore = tf.contrib.framework.get_variables_to_restore(exclude=['vgg_16/fc8'])
+ init_fn = tf.contrib.framework.assign_from_checkpoint_fn(model_path, variables_to_restore)
+
+ # Initialization operation from scratch for the new "fc8" layers
+ # `get_variables` will only return the variables whose name starts with the given pattern
+ fc8_variables = tf.contrib.framework.get_variables('vgg_16/fc8')
+ fc8_init = tf.variables_initializer(fc8_variables)
+
+
+ # ---------------------------------------------------------------------
+ # Using tf.losses, any loss is added to the tf.GraphKeys.LOSSES collection
+ # We can then call the total loss easily
+ tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
+ loss = tf.losses.get_total_loss()
+
+ # First we want to train only the reinitialized last layer fc8 for a few epochs.
+ # We run minimize the loss only with respect to the fc8 variables (weight and bias).
+ fc8_optimizer = tf.train.GradientDescentOptimizer(args.learning_rate1)
+ fc8_train_op = fc8_optimizer.minimize(loss, var_list=fc8_variables)
+
+ # Then we want to finetune the entire model for a few epochs.
+ # We run minimize the loss only with respect to all the variables.
+ full_optimizer = tf.train.GradientDescentOptimizer(args.learning_rate2)
+ full_train_op = full_optimizer.minimize(loss)
+
+ # Evaluation metrics
+ prediction = tf.to_int32(tf.argmax(logits, 1))
+ correct_prediction = tf.equal(prediction, labels)
+ accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
+ saver=tf.train.Saver()
+ tf.get_default_graph().finalize()
+
+ # --------------------------------------------------------------------------
+ # Now that we have built the graph and finalized it, we define the session.
+ # The session is the interface to *run* the computational graph.
+ # We can call our training operations with `sess.run(train_op)` for instance
+
+ with tf.Session(graph=graph) as sess:
+ init_fn(sess) # load the pretrained weights
+ sess.run(fc8_init) # initialize the new fc8 layer
+
+ # Update only the last layer for a few epochs.
+ for epoch in range(args.num_epochs1):
+ # Run an epoch over the training data.
+ print('Starting epoch %d / %d' % (epoch + 1, args.num_epochs1))
+ # Here we initialize the iterator with the training set.
+ # This means that we can go through an entire epoch until the iterator becomes empty.
+ sess.run(train_init_op)
+ while True:
+ try:
+ _ = sess.run(fc8_train_op, {is_training: True})
+ except tf.errors.OutOfRangeError:
+ break
+
+ # Check accuracy on the train and val sets every epoch.
+ train_acc = check_accuracy(sess, correct_prediction, is_training, train_init_op)
+# val_acc = check_accuracy(sess, correct_prediction, is_training, val_init_op)
+ print('Train accuracy: %f' % train_acc)
+# print('Val accuracy: %f\n' % val_acc)
+ saver.save(sess,'model.ckpt')
+
+
+ # Train the entire model for a few more epochs, continuing with the *same* weights.
+ for epoch in range(args.num_epochs2):
+ print('Starting epoch %d / %d' % (epoch + 1, args.num_epochs1))
+ sess.run(train_init_op)
+ while True:
+ try:
+ _ = sess.run(full_train_op, {is_training: True})
+ except tf.errors.OutOfRangeError:
+ break
+
+ # Check accuracy on the train and val sets every epoch
+ train_acc = check_accuracy(sess, correct_prediction, is_training, train_init_op)
+# val_acc = check_accuracy(sess, correct_prediction, is_training, val_init_op)
+ print('Train accuracy: %f' % train_acc)
+ # print('Val accuracy: %f\n' % val_acc)
+
+ saver.save(sess,'model.ckpt')
+
+
+
+
+if __name__ == '__main__':
+ args = parser.parse_args()
+ main(args)
\ No newline at end of file
diff --git a/tensorflow_test.py b/tensorflow_test.py
new file mode 100644
index 0000000..954b455
--- /dev/null
+++ b/tensorflow_test.py
@@ -0,0 +1,295 @@
+
+
+import argparse
+import os
+
+import tensorflow as tf
+import tensorflow.contrib.slim as slim
+import tensorflow.contrib.slim.nets
+from load_datas import *
+
+#path_data= os.environ.get("GRAPE_DATASET_DIR")
+#frames_path=os.path.join(path_data,'frames/train')
+frames_path='./test'
+#labels_path=os.path.join(path_data,'labels')
+labels_path='./labels'
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--train_dir', default=frames_path)
+parser.add_argument('--label_dir', default=labels_path)
+parser.add_argument('--model_path', default='vgg_16.ckpt', type=str)
+parser.add_argument('--batch_size', default=4, type=int)
+parser.add_argument('--num_workers', default=1, type=int)
+parser.add_argument('--num_epochs1', default=1, type=int)
+parser.add_argument('--num_epochs2', default=1, type=int)
+parser.add_argument('--learning_rate1', default=1e-3, type=float)
+parser.add_argument('--learning_rate2', default=1e-5, type=float)
+parser.add_argument('--dropout_keep_prob', default=0.5, type=float)
+parser.add_argument('--weight_decay', default=5e-4, type=float)
+
+VGG_MEAN = [123.68, 116.78, 103.94]
+
+def load_file_seqs(path,index):
+ file_name=[]
+
+ for i in range(len(index)):
+ file_name_L=[]
+ file_name_R=[]
+ loc = index[i][0]
+ idx = str(index[i][1])
+ for i in os.listdir(os.path.join(path,loc,idx,"Lhand")):
+ file_name_L.append(os.path.join(path,loc,idx,"Lhand", i))
+ file_name_L = sorted(file_name_L, key=lambda x: int(re.sub('\D', '', x)))
+
+ for i in os.listdir(os.path.join(path,loc,idx,"Rhand")):
+ file_name_R.append(os.path.join(path,loc,idx,"Rhand", i))
+ file_name_R = sorted(file_name_R, key=lambda x: int(re.sub('\D', '', x)))
+
+ file_name+=file_name_L
+ file_name+=file_name_R
+ return file_name
+
+def load_files(path):
+ file_index=[]
+ for i in range(1,5):
+ file_index.append(('lab',i))
+ for i in range(1,4):
+ file_index.append(('office',i))
+ for i in range(1,4):
+ file_index.append(('house',i))
+ file_names=load_file_seqs(path,file_index)
+ return file_names
+
+def check_accuracy(sess, correct_prediction, is_training,dataset_init_op):
+ """
+ Check the accuracy of the model on either train or val (depending on dataset_init_op).
+ """
+ # Initialize the correct dataset
+ sess.run(dataset_init_op)
+
+ num_correct, num_samples = 0, 0
+ while True:
+ try:
+ correct_pred = sess.run(correct_prediction, {is_training: False})
+ num_correct += correct_pred.sum()
+ num_samples += correct_pred.shape[0]
+ except tf.errors.OutOfRangeError:
+ break
+
+ # Return the fraction of datapoints that were correctly classified
+ acc = float(num_correct) / num_samples
+ return acc
+
+
+def main(args):
+ # Get the list of filenames and corresponding list of labels for training et validation
+ train_filenames = load_files(args.train_dir)
+ labels=load_train_labels(args.label_dir,'obj',setting_index=0)
+ unique_labels={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}
+
+ label_to_int = {}
+ for i, label in enumerate(unique_labels):
+ label_to_int[label] = i
+
+ train_labels=[]
+ for i in range(len(labels)):
+ labels[i] = [label_to_int[l] for l in labels[i]]
+ train_labels+= labels[i]
+
+ train_filenames=train_filenames[200:300]
+ train_labels=train_labels[200:300]
+ print(train_labels)
+ num_classes=24
+ # --------------------------------------------------------------------------
+ # In TensorFlow, you first want to define the computation graph with all the
+ # necessary operations: loss, training op, accuracy...
+ # Any tensor created in the `graph.as_default()` scope will be part of `graph`
+ graph = tf.Graph()
+ with graph.as_default():
+ # Standard preprocessing for VGG on ImageNet taken from here:
+ # https://github.com/tensorflow/models/blob/master/slim/preprocessing/vgg_preprocessing.py
+ # Also see the VGG paper for more details: https://arxiv.org/pdf/1409.1556.pdf
+
+ # Preprocessing (for both training and validation):
+ # (1) Decode the image from jpg format
+ # (2) Resize the image so its smaller side is 256 pixels long
+ def _parse_function(filename, label):
+ image_string = tf.read_file(filename)
+ image_decoded = tf.image.decode_png(image_string, channels=3) # (1)
+ image = tf.cast(image_decoded, tf.float32)
+
+ smallest_side = 256.0
+ height, width = tf.shape(image)[0], tf.shape(image)[1]
+ height = tf.to_float(height)
+ width = tf.to_float(width)
+
+ scale = tf.cond(tf.greater(height, width),
+ lambda: smallest_side / width,
+ lambda: smallest_side / height)
+ new_height = tf.to_int32(height * scale)
+ new_width = tf.to_int32(width * scale)
+
+ resized_image = tf.image.resize_images(image, [new_height, new_width]) # (2)
+ return resized_image, label
+
+ # Preprocessing (for training)
+ # (3) Take a random 224x224 crop to the scaled image
+ # (4) Horizontally flip the image with probability 1/2
+ # (5) Substract the per color mean `VGG_MEAN`
+ # Note: we don't normalize the data here, as VGG was trained without normalization
+ def training_preprocess(image, label):
+ crop_image = tf.random_crop(image, [224, 224, 3]) # (3)
+ flip_image = tf.image.random_flip_left_right(crop_image) # (4)
+
+ means = tf.reshape(tf.constant(VGG_MEAN), [1, 1, 3])
+ centered_image = flip_image - means # (5)
+
+ return centered_image, label
+
+ # Preprocessing (for validation)
+ # (3) Take a central 224x224 crop to the scaled image
+ # (4) Substract the per color mean `VGG_MEAN`
+ # Note: we don't normalize the data here, as VGG was trained without normalization
+# def val_preprocess(image, label):
+ # crop_image = tf.image.resize_image_with_crop_or_pad(image, 224, 224) # (3)
+#
+ # means = tf.reshape(tf.constant(VGG_MEAN), [1, 1, 3])
+ # centered_image = crop_image - means # (4)
+#
+ # return centered_image, label
+
+ # ----------------------------------------------------------------------
+ # DATASET CREATION using tf.contrib.data.Dataset
+ # https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/data
+
+ # The tf.contrib.data.Dataset framework uses queues in the background to feed in
+ # data to the model.
+ # We initialize the dataset with a list of filenames and labels, and then apply
+ # the preprocessing functions described above.
+ # Behind the scenes, queues will load the filenames, preprocess them with multiple
+ # threads and apply the preprocessing in parallel, and then batch the data
+ # Training dataset
+ train_filenames = tf.constant(train_filenames)
+ train_labels = tf.constant(train_labels)
+ train_dataset = tf.contrib.data.Dataset.from_tensor_slices((train_filenames, train_labels))
+ train_dataset = train_dataset.map(_parse_function,
+ num_threads=args.num_workers, output_buffer_size=args.batch_size)
+ train_dataset = train_dataset.map(training_preprocess,
+ num_threads=args.num_workers, output_buffer_size=args.batch_size)
+ train_dataset = train_dataset.shuffle(buffer_size=10000) # don't forget to shuffle
+ batched_train_dataset = train_dataset.batch(args.batch_size)
+
+ # Validation dataset
+ # val_filenames = tf.constant(val_filenames)
+ # val_labels = tf.constant(val_labels)
+ # val_dataset = tf.contrib.data.Dataset.from_tensor_slices((val_filenames, val_labels))
+ # val_dataset = val_dataset.map(_parse_function,
+ # num_threads=args.num_workers, output_buffer_size=args.batch_size)
+ # val_dataset = val_dataset.map(val_preprocess,
+ # num_threads=args.num_workers, output_buffer_size=args.batch_size)
+ #batched_val_dataset = val_dataset.batch(args.batch_size)
+
+
+ # Now we define an iterator that can operator on either dataset.
+ # The iterator can be reinitialized by calling:
+ # - sess.run(train_init_op) for 1 epoch on the training set
+ # - sess.run(val_init_op) for 1 epoch on the valiation set
+ # Once this is done, we don't need to feed any value for images and labels
+ # as they are automatically pulled out from the iterator queues.
+
+ # A reinitializable iterator is defined by its structure. We could use the
+ # `output_types` and `output_shapes` properties of either `train_dataset`
+ # or `validation_dataset` here, because they are compatible.
+ iterator = tf.contrib.data.Iterator.from_structure(batched_train_dataset.output_types,
+ batched_train_dataset.output_shapes)
+ images, labels = iterator.get_next()
+
+ train_init_op = iterator.make_initializer(batched_train_dataset)
+# val_init_op = iterator.make_initializer(batched_val_dataset)
+
+ # Indicates whether we are in training or in test mode
+ is_training = tf.placeholder(tf.bool)
+
+
+ # ---------------------------------------------------------------------
+ # Now that we have set up the data, it's time to set up the model.
+ # For this example, we'll use VGG-16 pretrained on ImageNet. We will remove the
+ # last fully connected layer (fc8) and replace it with our own, with an
+ # output size num_classes=8
+ # We will first train the last layer for a few epochs.
+ # Then we will train the entire model on our dataset for a few epochs.
+
+ # Get the pretrained model, specifying the num_classes argument to create a new
+ # fully connected replacing the last one, called "vgg_16/fc8"
+ # Each model has a different architecture, so "vgg_16/fc8" will change in another model.
+ # Here, logits gives us directly the predicted scores we wanted from the images.
+ # We pass a scope to initialize "vgg_16/fc8" weights with he_initializer
+ vgg = tf.contrib.slim.nets.vgg
+ with slim.arg_scope(vgg.vgg_arg_scope(weight_decay=args.weight_decay)):
+ logits, _ = vgg.vgg_16(images, num_classes=num_classes, is_training=is_training,
+ dropout_keep_prob=args.dropout_keep_prob)
+
+ # Specify where the model checkpoint is (pretrained weights).
+ model_path = args.model_path
+ assert(os.path.isfile(model_path))
+
+ # Restore only the layers up to fc7 (included)
+ # Calling function `init_fn(sess)` will load all the pretrained weights.
+ variables_to_restore = tf.contrib.framework.get_variables_to_restore()
+ init_fn = tf.contrib.framework.assign_from_checkpoint_fn(model_path, variables_to_restore)
+
+ # Initialization operation from scratch for the new "fc8" layers
+ # `get_variables` will only return the variables whose name starts with the given pattern
+# fc8_variables = tf.contrib.framework.get_variables('vgg_16/fc8')
+# fc8_init = tf.variables_initializer(fc8_variables)
+
+
+ # ---------------------------------------------------------------------
+ # Using tf.losses, any loss is added to the tf.GraphKeys.LOSSES collection
+ # We can then call the total loss easily
+# tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits)
+# loss = tf.losses.get_total_loss()
+
+ # First we want to train only the reinitialized last layer fc8 for a few epochs.
+ # We run minimize the loss only with respect to the fc8 variables (weight and bias).
+# fc8_optimizer = tf.train.GradientDescentOptimizer(args.learning_rate1)
+# fc8_train_op = fc8_optimizer.minimize(loss, var_list=fc8_variables)
+
+ # Then we want to finetune the entire model for a few epochs.
+ # We run minimize the loss only with respect to all the variables.
+# full_optimizer = tf.train.GradientDescentOptimizer(args.learning_rate2)
+# full_train_op = full_optimizer.minimize(loss)
+
+ # Evaluation metrics
+ prediction = tf.to_int32(tf.argmax(logits, 1))
+ correct_prediction = tf.equal(prediction, labels)
+ accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
+ saver=tf.train.Saver()
+
+ tf.get_default_graph().finalize()
+
+ # --------------------------------------------------------------------------
+ # Now that we have built the graph and finalized it, we define the session.
+ # The session is the interface to *run* the computational graph.
+ # We can call our training operations with `sess.run(train_op)` for instance
+ with tf.Session(graph=graph) as sess:
+
+ check_point_path = 'saved_model/' # 保存好模型的文件路径
+ ckpt = tf.train.get_checkpoint_state(checkpoint_dir=check_point_path)
+
+# 从模型中恢复参数
+ saver.restore(sess,ckpt.model_checkpoint_path) # 讀取成功,然后就可以使用模型参数进行预测,或者测试了。
+
+ train_acc = check_accuracy(sess, correct_prediction, is_training,train_init_op)
+# val_acc = check_accuracy(sess, correct_prediction, is_training, val_init_op)
+ print(type(correct_prediction))
+ print('Train accuracy: %f' % train_acc)
+# print('Val accuracy: %f\n' % val_acc)
+
+
+
+
+
+if __name__ == '__main__':
+ args = parser.parse_args()
+ main(args)
\ No newline at end of file