diff --git a/code/load_datas.py b/code/load_datas.py new file mode 100644 index 0000000..b099631 --- /dev/null +++ b/code/load_datas.py @@ -0,0 +1,112 @@ +############################################################################################################# +# 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 + +def load_one_label_seq(path): + npy = np.load(path) + return npy + + +def load_label_seqs(path, mode, index):#index are generated by gen_index + labels=[] + for i in range(len(index)): #eg index = [(lab,1),(lab,2),(lab,3),...] + loc = index[i][0] #eg lab office house + idx = index[i][1] #eg 1,2,3 + 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)) + 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 #left1~3 right1~3 + +def gen_index(setting_index): + train_index=[] + test_index =[] + if setting_index == 0: + #order: + #train : lab1~4 off1~3 house1~3 + #test : lab5~8 off4~6 house4~6 + for i in range(1,7): + if i <= 3: + train_index.append(('house',i)) + else: + test_index.append(('house',i)) + 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)) + + elif setting_index == 1: + for i in range(1,9): + train_index.append(('lab',i)) + for i in range(1,7): + train_index.append(('office',i)) + for i in range(1,7): + 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 = gen_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/code/test.py b/code/test.py new file mode 100644 index 0000000..a6a724a --- /dev/null +++ b/code/test.py @@ -0,0 +1,193 @@ +import argparse +import os +import numpy as np +import tensorflow as tf +import tensorflow.contrib.slim as slim +import tensorflow.contrib.slim.nets +from load_datas import * + +label_path='../labels' + +parser = argparse.ArgumentParser() +parser.add_argument('--train_dir', default='../frames/train') +parser.add_argument('--val_dir', default='../frames/test') +parser.add_argument('--model_path', default='./saved_model/model.ckpt.data-00000-of-00001', 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=15, type=int) +parser.add_argument('--num_epochs2', default=5, 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 list_images(directory): + scenes = os.listdir(directory) + filenames = [] + for scene in scenes: + scene_path = os.path.join(directory,scene) + videos = os.listdir(scene_path) + for video in videos: + video_path = os.path.join(scene_path, video) + left_path = os.path.join(video_path, 'Lhand') + fs = os.listdir(left_path) + for f in fs: + file_path = os.path.join(left_path, f) + filenames.append(file_path) + right_path = os.path.join(video_path, 'Rhand') + fs = os.listdir(right_path) + for f in fs: + file_path = os.path.join(right_path, f) + filenames.append(file_path) + filenames = list(filenames) + return filenames + + +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 list_flatten(label): + label_f = [] + for i in range(len(label)): + temp = label[i].tolist() + label_f = label_f + temp + return(label_f) + +def fit_batch(data,label,batch_size): + rm = len(data) % batch_size + if(rm!=0): + data = data[:-rm] + label = label[:-rm] + return(data,label) + +def label_to_int(labels): + unique_labels = list(set(labels)) + label_to_int = {} + for i, label in enumerate(unique_labels): + label_to_int[label] = i + labels = [label_to_int[l] for l in labels] + return labels + +def main(args): + # Get the list of filenames and corresponding list of labels for training et validation + train_filenames = list_images(args.train_dir) + val_filenames = list_images(args.val_dir) + train_labels, val_labels = load_all_labels(label_path, 'obj',0) + train_labels = list_flatten(train_labels) + val_labels = list_flatten(val_labels) + train_labels = label_to_int(train_labels) + val_labels = label_to_int(val_labels) + + train_filenames,train_labels = fit_batch(train_filenames,train_labels,args.batch_size) + val_filenames, val_labels = fit_batch(val_filenames,val_labels,args.batch_size) + num_classes = len(set(train_labels)) + + graph = tf.Graph() + with graph.as_default(): + # 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 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 + + # 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) + + iterator = tf.contrib.data.Iterator.from_structure(batched_val_dataset.output_types, + batched_val_dataset.output_shapes) + images, labels = iterator.get_next() + val_init_op = iterator.make_initializer(batched_val_dataset) + is_training = tf.placeholder(tf.bool) + 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) + + model_path = args.model_path + assert(os.path.isfile(model_path)) + + variables_to_restore = tf.contrib.framework.get_variables_to_restore() + init_fn = tf.contrib.framework.assign_from_checkpoint_fn(model_path, variables_to_restore) + + tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=logits) + loss = tf.losses.get_total_loss() + + 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() + + with tf.Session(graph=graph) as sess: + checkpoint_path = './saved_model' + ckpt = tf.train.get_checkpoint_state(checkpoint_dir = checkpoint_path) + saver.restore(sess,ckpt.model_checkpoint_path) + val_acc = check_accuracy(sess, correct_prediction, is_training, val_init_op) + print('Val accuracy: %f\n' % val_acc) + +if __name__ == '__main__': + args = parser.parse_args() + main(args) + + + + + + + + + + + + \ No newline at end of file diff --git a/code/test_load_datas.py b/code/test_load_datas.py new file mode 100644 index 0000000..698420f --- /dev/null +++ b/code/test_load_datas.py @@ -0,0 +1,36 @@ +import numpy as np +from load_datas import * +import pdb +import os + +label_path='../labels' + +# load all labels +train_labels0, test_labels0 = load_all_labels(label_path, 'obj',0) +#train_labels0:12array test_labels0:8array + +# load train/test labels automatically +train_labels = load_train_labels(label_path,'obj',setting_index=0) +test_labels = load_test_labels(label_path,'obj',setting_index=0) + +# load particular index +# You can load only part of the directories, the index of directories should be a list. +# Such like [(location1, id), (location2, id) ...], ex. [('lab',1), ('lab',2), ('office',1)] +# No setting_index required now. + +#train_labels = load_train_labels(label_path,'FA',index=[['lab',1],['lab',2],['office',3]]) +#test_labels = load_test_labels(label_path,'FA',index=[['lab',1],['lab',2],['office',3]]) + +#print(train_labels0) +#print(len(train_labels)) +print(type(train_labels[0])) + +for i in range(len(train_labels)): + if np.count_nonzero(train_labels0[i] == train_labels[i]) != len(train_labels0[i]): + print ('train_labels : i=%d error' % i) + +for i in range(len(test_labels)): + if np.count_nonzero(test_labels0[i] == test_labels[i]) != len(test_labels[i]): + print ('test_labels: i=%d error' % i) + + diff --git a/code/train_vgg.py b/code/train_vgg.py new file mode 100644 index 0000000..9f630ab --- /dev/null +++ b/code/train_vgg.py @@ -0,0 +1,320 @@ +import argparse +import os +import numpy as np +import tensorflow as tf +import tensorflow.contrib.slim as slim +import tensorflow.contrib.slim.nets +from load_datas import * + +label_path='../labels' + +parser = argparse.ArgumentParser() +parser.add_argument('--train_dir', default='../frames/train') +parser.add_argument('--val_dir', default='../frames/test') +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=15, type=int) +parser.add_argument('--num_epochs2', default=5, 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] + +#modify this function to get frames +def list_images(directory): + #load training/testing labels + scenes = os.listdir(directory) + filenames = [] + for scene in scenes: + scene_path = os.path.join(directory,scene) + videos = os.listdir(scene_path) + for video in videos: + video_path = os.path.join(scene_path, video) + left_path = os.path.join(video_path, 'Lhand') + fs = os.listdir(left_path) + for f in fs: + file_path = os.path.join(left_path, f) + filenames.append(file_path) + right_path = os.path.join(video_path, 'Rhand') + fs = os.listdir(right_path) + for f in fs: + file_path = os.path.join(right_path, f) + filenames.append(file_path) + filenames = list(filenames) + return filenames + + +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 list_flatten(label): + label_f = [] + for i in range(len(label)): + temp = label[i].tolist() + label_f = label_f + temp + return(label_f) + +def fit_batch(data,label,batch_size): + rm = len(data) % batch_size + if(rm!=0): + data = data[:-rm] + label = label[:-rm] + return(data,label) + +def label_to_int(labels): + unique_labels = list(set(labels)) + label_to_int = {} + for i, label in enumerate(unique_labels): + label_to_int[label] = i + labels = [label_to_int[l] for l in labels] + return labels + +def main(args): + # Get the list of filenames and corresponding list of labels for training et validation + train_filenames = list_images(args.train_dir) + train_labels, val_labels = load_all_labels(label_path, 'obj',0) + train_labels = list_flatten(train_labels) + train_labels = label_to_int(train_labels) + train_filenames,train_labels = fit_batch(train_filenames,train_labels,args.batch_size) + num_classes = len(set(train_labels)) + + + # -------------------------------------------------------------------------- + # 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)) + #!!!!!!!!!!!save + #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) + #counter=0 + while True: + try: + _ = sess.run(fc8_train_op, {is_training: True}) + #counter = counter+ 1 + #print("batch%d in done" % counter) + except tf.errors.OutOfRangeError: + break + #!!!!!!!!!!!save + #saver.save(sess , './saved_model/model.ckpt') + 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) + + + # 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_epochs2)) + sess.run(train_init_op) + while True: + try: + _ = sess.run(full_train_op, {is_training: True}) + except tf.errors.OutOfRangeError: + break + #!!!!!!!!!!!save + #saver.save(sess,'./saved_model/model.ckpt') + # 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) + + +if __name__ == '__main__': + args = parser.parse_args() + main(args) \ No newline at end of file diff --git a/results/index.md b/results/index.md index 96ce61c..7cb72b5 100644 --- a/results/index.md +++ b/results/index.md @@ -1,27 +1,33 @@ -# Your Name (id) +# 王智寬 (106062601) #Project 5: Deep Classification ## Overview -The project is related to +The project is heavily reference the code : https://gist.github.com/omoindrot/dedc857cdc0e680dfb1be99762990c9c +omoindrot teaches us how to fine-tune a vgg model. +Due to the time limits, I only train 5 epochs and then early stop it. > quote ## Implementation -1. One - * item - * item -2. Two - -``` -Code highlights -``` +1. Fine-tune a vgg-16 + * restore a pretrained weight (exclude fc8) + * train a new fc8 + * train the whole model + * save the trained weight +2. test.py + * load testing data + * calculate accuracy ## Installation -* Other required packages. -* How to compile from source? +* tensorflow +* download VGG pretrained weight, "vgg_16.ckpt", put it in "code" file. +* download trained weight, "model.ckpt.data-00000-of-00001", put it in the "saved_model" file +* download url : https://drive.google.com/open?id=0B3vEmk5Bd7lNRmhPSDcxbjhqMFE ### Results +Training accuracy : 0.482 +Testing accuracy : 0.433