TensorFLow 載入VGG19 模型並進行預測
阿新 • • 發佈:2019-01-28
import tensorflow as tf import scipy.io import numpy as np import cv2 #download from here http://www.vlfeat.org/matconvnet/models/beta16/imagenet-vgg-verydeep-19.mat DEFAULT_PATH="./imagenet-vgg-verydeep-19.mat" VGG19_LAYERS=('conv1_1','relu1_1','conv1_2','relu1_2','pool1', 'conv2_1','relu2_1','conv2_2','relu2_2','pool2', 'conv3_1','relu3_1','conv3_2','relu3_2','conv3_3','relu3_3','conv3_4','relu3_4','pool3', 'conv4_1','relu4_1','conv4_2','relu4_2','conv4_3','relu4_3','conv4_4','relu4_4','pool4', 'conv5_1','relu5_1','conv5_2','relu5_2','conv5_3','relu5_3','conv5_4','relu5_4','pool5', 'fc6','relu6', 'fc7','relu7', 'fc8','softmax', ) # input shape: [batch, height, width, channels], only one image, so batch=1. INPUT_SHAPE=(1,224,224,3) class VGG19: def __init__(self,model_path=None): print ("Load Pre-Trained Model....."); mat = None; if (model_path == None): mat = scipy.io.loadmat(DEFAULT_PATH); else: mat = scipy.io.loadmat(model_path); assert mat != None #print (mat) #load normalization pixel value to calculate average pixel value norm_pic = mat['normalization'][0][0][0]; self.mean_pix = np.mean(norm_pic,axis=(0,1)) self.layer_params = mat['layers'][0] def build_VGGnet(self): print ("Building VGG19 Net..........") self.image = tf.placeholder(tf.float32, shape=INPUT_SHAPE,name="input_image") self.layers = {} last_layer = self.image assert last_layer != None for i, name in enumerate(VGG19_LAYERS): type = name[:3] temp_layer = None if type == "con": filters,bias = self.layer_params[i][0][0][0][0] filters = np.transpose(filters, (1,0,2,3)) bias = np.reshape(bias,-1) conv = tf.nn.conv2d(last_layer, tf.constant(filters), strides=[1,1,1,1], padding='SAME') temp_layer = tf.nn.bias_add(conv, tf.constant(bias)) elif type == 'rel': temp_layer = tf.nn.relu(last_layer) elif type == 'poo': temp_layer = tf.nn.max_pool(last_layer, ksize=[1,2,2,1], strides=[1,2,2,1], padding='SAME') elif name == 'fc6': weights,bias = self.layer_params[i][0][0][0][0] bias = np.reshape(bias,-1) #flatten the output from pooling layer last_layer = tf.reshape(last_layer,[last_layer.shape[0],-1]) weights = np.reshape(weights,(-1,weights.shape[-1])) temp_layer = tf.nn.bias_add(tf.matmul(last_layer,weights),bias) elif name == 'fc7': weights,bias = self.layer_params[i][0][0][0][0] bias = np.reshape(bias,-1) weights = np.reshape(weights,(-1,weights.shape[-1])) temp_layer = tf.nn.bias_add(tf.matmul(last_layer,weights),bias) elif name == 'fc8': weights,bias = self.layer_params[i][0][0][0][0] bias = np.reshape(bias,-1) weights = np.reshape(weights,(-1,weights.shape[-1])) temp_layer = tf.nn.bias_add(tf.matmul(last_layer,weights),bias) elif name == 'softmax': temp_layer = tf.nn.softmax(last_layer) assert temp_layer != None self.layers[name]=temp_layer last_layer = temp_layer; def predict(self,imgPath=None): if imgPath is None: imgPath="./test_data/test1.jpg" #imgPATH="./test_data/cat.jpg" # download labels from here https://github.com/sh1r0/caffe-Android-demo/blob/master/app/src/main/assets/synset_words.txt labels = [str.strip() for str in open("./synset.txt").readlines()] # load image and pre process input image img = cv2.imread(imgPath) assert img is not None #change BGR -> RGB pattern img = img[:,:,::-1] img = cv2.resize(img,(224,224),interpolation=cv2.INTER_CUBIC) img = img.astype(np.float32) #extand image into {batch,width,height,channels] img = np.expand_dims(img, axis=0) #subtract channel mean to adapt vgg19 net input img = img - self.mean_pix with tf.Session() as sess: image_feed = {self.image:img} probs = self.layers['softmax'][0].eval(feed_dict = image_feed) #probs = np.reshape(probs,-1) maxIndex = np.argmax(probs); print ("index:",maxIndex) print ("prob:",probs[maxIndex]) print ("label:",labels[maxIndex]) if __name__ == "__main__": vgg = VGG19(); vgg.build_VGGnet(); vgg.predict()