VGG-16复现
python版本:2.7
TensorFlow版本:0.8.0rc0(输入tf.__version__即可查看)
由于TensorFlow版本较低,个别函数用法已经发生变化,不过无关紧要,出现错误网上都有解决方法。
利用VGG-16网络实现千分类。
VGG论文中的网络结果和参数个数分析如下:
模型结构可视化:
输入图片路径,即可查看top-5分类结果。VGG网络结构较为简单,网上学习资源也很多,也可以参考北京大学mooc的tensorflow笔记,本代码也是参考该学习资源。
原始图片和预处理图片:
top5分类:
模型代码:
#!/usr/bin/python
# coding:utf-8
import inspect
import os
import numpy as np
import tensorflow as tf
import time
import matplotlib.pyplot as plt
# 图像平均灰度值
VGG_MEAN = [103.939, 116.779, 123.68]
class Vgg16():
def __init__(self, vgg16_path=None):
if vgg16_path is None:
vgg16_path = os.path.join(os.getcwd(), "vgg16.npy")
# 改
self.data_dict = np.load(vgg16_path, encoding='latin1',allow_pickle=True).item()
def forward(self, images):
print("build model started")
start_time = time.time()
rgb_scaled = images * 255.0
print tf.shape(rgb_scaled)
# 版本问题# tf.split(axis, num_or_size_splits, value)
red, green, blue = tf.split(3, 3, rgb_scaled)
# 改
bgr = tf.concat(3,[
blue - VGG_MEAN[0],
green - VGG_MEAN[1],
red - VGG_MEAN[2]])
self.conv1_1 = self.conv_layer(bgr, "conv1_1")
self.conv1_2 = self.conv_layer(self.conv1_1, "conv1_2")
self.pool1 = self.max_pool_2x2(self.conv1_2, "pool1")
self.conv2_1 = self.conv_layer(self.pool1, "conv2_1")
self.conv2_2 = self.conv_layer(self.conv2_1, "conv2_2")
self.pool2 = self.max_pool_2x2(self.conv2_2, "pool2")
self.conv3_1 = self.conv_layer(self.pool2, "conv3_1")
self.conv3_2 = self.conv_layer(self.conv3_1, "conv3_2")
self.conv3_3 = self.conv_layer(self.conv3_2, "conv3_3")
self.pool3 = self.max_pool_2x2(self.conv3_3, "pool3")
self.conv4_1 = self.conv_layer(self.pool3, "conv4_1")
self.conv4_2 = self.conv_layer(self.conv4_1, "conv4_2")
self.conv4_3 = self.conv_layer(self.conv4_2, "conv4_3")
self.pool4 = self.max_pool_2x2(self.conv4_3, "pool4")
self.conv5_1 = self.conv_layer(self.pool4, "conv5_1")
self.conv5_2 = self.conv_layer(self.conv5_1, "conv5_2")
self.conv5_3 = self.conv_layer(self.conv5_2, "conv5_3")
self.pool5 = self.max_pool_2x2(self.conv5_3, "pool5")
self.fc6 = self.fc_layer(self.pool5, "fc6")
self.relu6 = tf.nn.relu(self.fc6)
self.fc7 = self.fc_layer(self.relu6, "fc7")
self.relu7 = tf.nn.relu(self.fc7)
self.fc8 = self.fc_layer(self.relu7, "fc8")
self.prob = tf.nn.softmax(self.fc8, name="prob")
end_time = time.time()
print(("time consuming: %f" % (end_time - start_time)))
self.data_dict = None
def conv_layer(self, x, name):
with tf.variable_scope(name):
w = self.get_conv_filter(name)
conv = tf.nn.conv2d(x, w, [1, 1, 1, 1], padding='SAME')
conv_biases = self.get_bias(name)
result = tf.nn.relu(tf.nn.bias_add(conv, conv_biases))
return result
def get_conv_filter(self, name):
return tf.constant(self.data_dict[name][0], name="filter")
def get_bias(self, name):
return tf.constant(self.data_dict[name][1], name="biases")
def max_pool_2x2(self, x, name):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME', name=name)
def fc_layer(self, x, name):
with tf.variable_scope(name):
shape = x.get_shape().as_list()
dim = 1
for i in shape[1:]:
dim *= i
x = tf.reshape(x, [-1, dim])
w = self.get_fc_weight(name)
b = self.get_bias(name)
result = tf.nn.bias_add(tf.matmul(x, w), b)
return result
def get_fc_weight(self, name):
return tf.constant(self.data_dict[name][0], name="weights")
不疯魔不成活