forked from ton4eg/coursera_pa
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request ton4eg#1 from egorlitvinenko/master
Update vgg16.py
- Loading branch information
Showing
2 changed files
with
317 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,316 @@ | ||
# insprired by | ||
# http://www.cs.toronto.edu/~frossard/post/vgg16/ | ||
# Model from https://gist.github.com/ksimonyan/211839e770f7b538e2d8#file-readme-md # | ||
# Weights from Caffe converted using https://github.com/ethereon/caffe-tensorflow # | ||
|
||
import glob | ||
import os | ||
import tensorflow as tf | ||
import numpy as np | ||
from scipy.misc import imread, imresize | ||
from imagenet_classes import class_names | ||
import sys | ||
from sklearn.svm import SVC | ||
|
||
class vgg16: | ||
def __init__(self, imgs, weights=None, sess=None): | ||
self.imgs = imgs | ||
self.convlayers() | ||
self.fc_layers() | ||
self.probs = tf.nn.softmax(self.fc3l) | ||
if weights is not None and sess is not None: | ||
self.load_weights(weights, sess) | ||
|
||
|
||
def convlayers(self): | ||
self.parameters = [] | ||
|
||
# zero-mean input | ||
with tf.name_scope('preprocess') as scope: | ||
mean = tf.constant([123.68, 116.779, 103.939], dtype=tf.float32, shape=[1, 1, 1, 3], name='img_mean') | ||
images = self.imgs-mean | ||
|
||
# conv1_1 | ||
with tf.name_scope('conv1_1') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 3, 64], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(images, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv1_1 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# conv1_2 | ||
with tf.name_scope('conv1_2') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 64], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.conv1_1, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[64], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv1_2 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# pool1 | ||
self.pool1 = tf.nn.max_pool(self.conv1_2, | ||
ksize=[1, 2, 2, 1], | ||
strides=[1, 2, 2, 1], | ||
padding='SAME', | ||
name='pool1') | ||
|
||
# conv2_1 | ||
with tf.name_scope('conv2_1') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 128], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.pool1, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv2_1 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# conv2_2 | ||
with tf.name_scope('conv2_2') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 128, 128], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.conv2_1, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv2_2 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# pool2 | ||
self.pool2 = tf.nn.max_pool(self.conv2_2, | ||
ksize=[1, 2, 2, 1], | ||
strides=[1, 2, 2, 1], | ||
padding='SAME', | ||
name='pool2') | ||
|
||
# conv3_1 | ||
with tf.name_scope('conv3_1') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 128, 256], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.pool2, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv3_1 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# conv3_2 | ||
with tf.name_scope('conv3_2') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 256], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.conv3_1, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv3_2 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# conv3_3 | ||
with tf.name_scope('conv3_3') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 256], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.conv3_2, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[256], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv3_3 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# pool3 | ||
self.pool3 = tf.nn.max_pool(self.conv3_3, | ||
ksize=[1, 2, 2, 1], | ||
strides=[1, 2, 2, 1], | ||
padding='SAME', | ||
name='pool3') | ||
|
||
# conv4_1 | ||
with tf.name_scope('conv4_1') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 256, 512], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.pool3, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv4_1 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# conv4_2 | ||
with tf.name_scope('conv4_2') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.conv4_1, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv4_2 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# conv4_3 | ||
with tf.name_scope('conv4_3') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.conv4_2, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv4_3 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# pool4 | ||
self.pool4 = tf.nn.max_pool(self.conv4_3, | ||
ksize=[1, 2, 2, 1], | ||
strides=[1, 2, 2, 1], | ||
padding='SAME', | ||
name='pool4') | ||
|
||
# conv5_1 | ||
with tf.name_scope('conv5_1') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.pool4, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv5_1 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# conv5_2 | ||
with tf.name_scope('conv5_2') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.conv5_1, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv5_2 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# conv5_3 | ||
with tf.name_scope('conv5_3') as scope: | ||
kernel = tf.Variable(tf.truncated_normal([3, 3, 512, 512], dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
conv = tf.nn.conv2d(self.conv5_2, kernel, [1, 1, 1, 1], padding='SAME') | ||
biases = tf.Variable(tf.constant(0.0, shape=[512], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
out = tf.nn.bias_add(conv, biases) | ||
self.conv5_3 = tf.nn.relu(out, name=scope) | ||
self.parameters += [kernel, biases] | ||
|
||
# pool5 | ||
self.pool5 = tf.nn.max_pool(self.conv5_3, | ||
ksize=[1, 2, 2, 1], | ||
strides=[1, 2, 2, 1], | ||
padding='SAME', | ||
name='pool4') | ||
|
||
def fc_layers(self): | ||
# fc1 | ||
with tf.name_scope('fc1') as scope: | ||
shape = int(np.prod(self.pool5.get_shape()[1:])) | ||
fc1w = tf.Variable(tf.truncated_normal([shape, 4096], | ||
dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
fc1b = tf.Variable(tf.constant(1.0, shape=[4096], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
pool5_flat = tf.reshape(self.pool5, [-1, shape]) | ||
fc1l = tf.nn.bias_add(tf.matmul(pool5_flat, fc1w), fc1b) | ||
self.fc1 = tf.nn.relu(fc1l) | ||
self.parameters += [fc1w, fc1b] | ||
|
||
# fc2 | ||
with tf.name_scope('fc2') as scope: | ||
fc2w = tf.Variable(tf.truncated_normal([4096, 4096], | ||
dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
fc2b = tf.Variable(tf.constant(1.0, shape=[4096], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
fc2l = tf.nn.bias_add(tf.matmul(self.fc1, fc2w), fc2b) | ||
self.fc2 = tf.nn.relu(fc2l) | ||
self.parameters += [fc2w, fc2b] | ||
|
||
# fc3 | ||
with tf.name_scope('fc3') as scope: | ||
fc3w = tf.Variable(tf.truncated_normal([4096, 1000], | ||
dtype=tf.float32, | ||
stddev=1e-1), name='weights') | ||
fc3b = tf.Variable(tf.constant(1.0, shape=[1000], dtype=tf.float32), | ||
trainable=True, name='biases') | ||
self.fc3l = tf.nn.bias_add(tf.matmul(self.fc2, fc3w), fc3b) | ||
self.parameters += [fc3w, fc3b] | ||
|
||
def load_weights(self, weight_file, sess): | ||
weights = np.load(weight_file) | ||
keys = sorted(weights.keys()) | ||
for i, k in enumerate(keys): | ||
print(i, k, np.shape(weights[k])) | ||
sess.run(self.parameters[i].assign(weights[k])) | ||
|
||
def process_image(fname): | ||
sess = tf.Session() | ||
imgs = tf.placeholder(tf.float32, [None, 224, 224, 3]) | ||
vgg = vgg16(imgs, 'vgg16_weights.npz', sess) | ||
|
||
img1 = imread(fname, mode='RGB') | ||
img1 = imresize(img1, (224, 224)) | ||
|
||
prob = sess.run(vgg.probs, feed_dict={vgg.imgs: [img1]})[0] | ||
preds = (np.argsort(prob)[::-1])[0:5] | ||
for p in preds: | ||
print(class_names[p], prob[p]) | ||
|
||
def get_features(folder, ydict, my_fc2): | ||
sess = tf.Session() | ||
imgs = tf.placeholder(tf.float32, [None, 224, 224, 3]) | ||
vgg = vgg16(imgs, 'vgg16_weights.npz', sess) | ||
|
||
paths = glob.glob(folder) | ||
X = np.zeros((len(paths), 4096)) | ||
Y = np.zeros(len(paths)) | ||
|
||
for i,img_name in enumerate(paths): | ||
print(img_name) | ||
base = os.path.basename(img_name) | ||
Y[i] = ydict[base] | ||
|
||
img1 = imread(img_name, mode='RGB') | ||
img1 = imresize(img1, (224, 224)) | ||
|
||
# TODO implement fc2 extration | ||
|
||
fc2 = my_fc2 | ||
|
||
X[i, :] = fc2 | ||
return X, Y | ||
|
||
def load_txt(fname): | ||
line_dict = {} | ||
for line in open(fname): | ||
fname, class_id = line.strip().split() | ||
line_dict[fname] = class_id | ||
|
||
return line_dict | ||
|
||
|
||
|
||
def process_folder(folder, X_test, Y_test): | ||
ydict = load_txt(os.path.join(folder,'results.txt')) | ||
|
||
X, Y = get_features(os.path.join(folder, 'train/*jpg'), ydict) | ||
#X_test, Y_test = #??? | ||
|
||
#SVM? | ||
|
||
Y_test_pred = clf.predict(X_test) | ||
print(sum(Y_test == Y_test_pred)) | ||
|
||
if __name__ == '__main__': | ||
process_image(path_to_image) | ||
|
||
|
||
#use for 3) | ||
#process_folder(path_to_data) |