Created
July 13, 2018 13:54
-
-
Save datduyng/99897f6154eeff0ee28b7118c0058cc1 to your computer and use it in GitHub Desktop.
cnn model - tutorial 2 - cv trick
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| classes = ['dogs','cats'] | |
| num_classes = len(classes) | |
| # refer to this link for why need this complicated path declaration | |
| # https://stackoverflow.com/questions/37619246/python-glob-glob-always-returns-empty-list | |
| train_path = '/home/*datduyn/*Documents/*dataset/*dog-cat/*training_set/' | |
| #validation split | |
| validation_size = 0.2 | |
| #batch size | |
| batch_size = 32 | |
| #image size | |
| img_size = 128 | |
| num_channels = 3 | |
| #TODO: download the class from the link procide above. | |
| data = read_train_sets(train_path,img_size,classes,validation_size=validation_size) | |
| print(data) | |
| #start the session | |
| session = tf.Session() | |
| #place holder and input(x) | |
| x = tf.placeholder(tf.float32,shape=[None,img_size,img_size,num_channels],name='x') | |
| y_true = tf.placeholder(tf.float32, shape=[None, num_classes], name='y_true') | |
| y_true_cls = tf.argmax(y_true,dimension=1) | |
| ##Network graph params | |
| filter_size_conv1 = 3 | |
| num_filters_conv1 = 32 | |
| filter_size_conv2 = 3 | |
| num_filters_conv2 = 32 | |
| filter_size_conv3 = 3 | |
| num_filters_conv3 = 64 | |
| fc_layer_size = 128 | |
| # create the weight quickly | |
| def create_weights(shape): | |
| return tf.Variable(tf.truncated_normal(shape,stddev=0.05)) | |
| #create bias quickly | |
| def create_bias(size): | |
| return tf.Variable(tf.constant(0.05,shape=[size])) | |
| # create convolutional layer | |
| def create_convolutional_layer(input, | |
| num_input_channels, | |
| conv_filter_size, | |
| num_filters): | |
| # define weight that will be train | |
| weights = create_weights(shape=[conv_filter_size,conv_filter_size,num_input_channels,num_filters]) | |
| #create trained bias | |
| biases = create_bias(num_filters) | |
| # creating convolutional layer | |
| layer = tf.nn.conv2d(input=input, | |
| filter=weights, | |
| strides=[1,1,1,1], | |
| padding='SAME') | |
| #update bias | |
| layer+= biases | |
| # max pool to reduce size | |
| layer = tf.nn.max_pool(value=layer, | |
| ksize=[1,2,2,1], | |
| strides=[1,2,2,1],# move 2 pixel x,y dir | |
| padding='SAME') | |
| #output of pooling is fed to RELU(activation function) | |
| layer=tf.nn.relu(layer) | |
| return layer | |
| ''' | |
| The output of a convolution layer is multi-dimensional tensor. | |
| we want to convert this into a 1-D tensor. called flattening layer | |
| ''' | |
| def create_flatten_layer(layer): | |
| layer_shape=layer.get_shape() | |
| num_features=layer_shape[1:4].num_elements()# TODO: figure out what this line mean | |
| layer = tf.reshape(layer,[-1,num_features])# 1d array with num_features elements | |
| return layer | |
| ''' | |
| create fully connected layer | |
| ''' | |
| def create_fc_layer(input, | |
| num_inputs, | |
| num_outputs, | |
| use_relu=True): | |
| #define trainable weight and biases | |
| weights=create_weights(shape=[num_inputs,num_outputs]) | |
| biases=create_bias(num_outputs) | |
| layer = tf.matmul(input,weights) + biases | |
| if use_relu: | |
| layer = tf.nn.relu(layer) | |
| return layer | |
| ''' | |
| network design | |
| note: | |
| filter_size_conv* : global variable from lib | |
| num_filters_conv*: global variable from lib | |
| ''' | |
| # create 3 layer for the network | |
| layer_conv1 = create_convolutional_layer(input=x, | |
| num_input_channels=num_channels, | |
| conv_filter_size=filter_size_conv1, | |
| num_filters=num_filters_conv1) | |
| layer_conv2 = create_convolutional_layer(input=layer_conv1, | |
| num_input_channels=num_filters_conv1, | |
| conv_filter_size=filter_size_conv2, | |
| num_filters=num_filters_conv2) | |
| layer_conv3 = create_convolutional_layer(input=layer_conv2, | |
| num_input_channels=num_filters_conv2, | |
| conv_filter_size=filter_size_conv3, | |
| num_filters=num_filters_conv3) | |
| # flatten the layer(convert to 1d array) | |
| layer_flat = create_flatten_layer(layer_conv3) | |
| # create connected layer | |
| layer_fc1 = create_fc_layer(input=layer_flat, | |
| num_inputs=layer_flat.get_shape()[1:4].num_elements(), | |
| num_outputs=fc_layer_size, | |
| use_relu=True) | |
| layer_fc2 = create_fc_layer(input=layer_fc1, | |
| num_inputs=fc_layer_size, | |
| num_outputs=num_classes, | |
| use_relu=False) | |
| ''' | |
| Prediction: | |
| ''' | |
| #get the probability of each class to output the fully connected layer(use softmax) | |
| #y_pred contains the predicted probability of each class for each input image. | |
| y_pred = tf.nn.softmax(layer_fc2,name="y_pred") | |
| #pick the highest probability of the all probability | |
| y_pred_cls = tf.argmax(y_pred,dimension=1) | |
| #init global variable from session | |
| session.run(tf.global_variables_initializer()) | |
| # minimize cost(by weight) using cross entropy | |
| cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=layer_fc2, | |
| labels=y_true) | |
| #minimize cost by finding mean of cross entropy function area. | |
| cost = tf.reduce_mean(cross_entropy) | |
| # Optimization:Adamoptimizer | |
| optimizer = tf.train.AdamOptimizer(learning_rate=1e-4).minimize(cost) | |
| #check for accuracy | |
| correct_prediction = tf.equal(y_pred_cls, y_true_cls) | |
| accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) | |
| session.run(tf.global_variables_initializer()) | |
| ''' | |
| show the progress | |
| ''' | |
| def show_progress(epoch, feed_dict_train, feed_dict_validate, val_loss): | |
| #report the validation accuracy | |
| acc = session.run(accuracy, feed_dict=feed_dict_train) | |
| #report the accuracy for the train image | |
| val_acc = session.run(accuracy, feed_dict=feed_dict_validate) | |
| #print out to console(report result) | |
| msg = "Training Epoch {0} --- Training Accuracy: {1:>6.1%}, Validation Accuracy: {2:>6.1%}, Validation Loss: {3:.3f}" | |
| print(msg.format(epoch + 1, acc, val_acc, val_loss)) | |
| # create a saver to save model | |
| saver = tf.train.Saver() | |
| # global total_iterations | |
| total_iterations = 0 | |
| # train the model | |
| def train(num_iteration): | |
| global total_iterations | |
| for i in range(total_iterations, | |
| total_iterations + num_iteration): | |
| #use function from dataset class(.train.next_batch() return # of next batch) | |
| x_batch, y_true_batch, _, cls_batch = data.train.next_batch(batch_size) | |
| x_valid_batch, y_valid_batch, _, valid_cls_batch = data.valid.next_batch(batch_size) | |
| # train dict | |
| feed_dict_tr = {x: x_batch, | |
| y_true: y_true_batch} | |
| # validation dict | |
| feed_dict_val = {x: x_valid_batch, | |
| y_true: y_valid_batch} | |
| #report result | |
| session.run(optimizer, feed_dict=feed_dict_tr) | |
| if i % int(data.train.num_examples/batch_size) == 0: | |
| val_loss = session.run(cost, feed_dict=feed_dict_val) | |
| epoch = int(i / int(data.train.num_examples/batch_size)) | |
| show_progress(epoch, feed_dict_tr, feed_dict_val, val_loss) | |
| saver.save(session, './dogs-cats-model') | |
| total_iteration += num_iteration | |
| train(num_iteration=3000) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment