python神經(jīng)網(wǎng)絡(luò)VGG16模型復(fù)現(xiàn)及其如何預(yù)測(cè)詳解
學(xué)一些比較知名的模型對(duì)身體有好處噢!
什么是VGG16模型
VGG是由Simonyan 和Zisserman在文獻(xiàn)《Very Deep Convolutional Networks for Large Scale Image Recognition》中提出卷積神經(jīng)網(wǎng)絡(luò)模型,其名稱來(lái)源于作者所在的牛津大學(xué)視覺幾何組(Visual Geometry Group)的縮寫。
該模型參加2014年的 ImageNet圖像分類與定位挑戰(zhàn)賽,取得了優(yōu)異成績(jī):在分類任務(wù)上排名第二,在定位任務(wù)上排名第一。
可能大家會(huì)想,這樣一個(gè)這么強(qiáng)的模型肯定很復(fù)雜吧?
其實(shí)一點(diǎn)也不復(fù)雜,它的結(jié)構(gòu)如下圖所示:

這是一個(gè)VGG被用到爛的圖,但確實(shí)很好的反應(yīng)了VGG的結(jié)構(gòu):
1、一張?jiān)紙D片被resize到(224,224,3)。
2、conv1兩次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為64,輸出為(224,224,64),再2X2最大池化,輸出net為(112,112,64)。
3、conv2兩次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為128,輸出net為(112,112,128),再2X2最大池化,輸出net為(56,56,128)。
4、conv3三次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為256,輸出net為(56,56,256),再2X2最大池化,輸出net為(28,28,256)。
5、conv3三次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為256,輸出net為(28,28,512),再2X2最大池化,輸出net為(14,14,512)。
6、conv3三次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為256,輸出net為(14,14,512),再2X2最大池化,輸出net為(7,7,512)。
7、利用卷積的方式模擬全連接層,效果等同,輸出net為(1,1,4096)。共進(jìn)行兩次。
8、利用卷積的方式模擬全連接層,效果等同,輸出net為(1,1,1000)。
最后輸出的就是每個(gè)類的預(yù)測(cè)。
VGG網(wǎng)絡(luò)部分實(shí)現(xiàn)代碼
#-------------------------------------------------------------#
# vgg16的網(wǎng)絡(luò)部分
#-------------------------------------------------------------#
import tensorflow as tf
# 創(chuàng)建slim對(duì)象
slim = tf.contrib.slim
def vgg_16(inputs,
num_classes=1000,
is_training=True,
dropout_keep_prob=0.5,
spatial_squeeze=True,
scope='vgg_16'):
with tf.variable_scope(scope, 'vgg_16', [inputs]):
# 建立vgg_16的網(wǎng)絡(luò)
# conv1兩次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為64,輸出為(224,224,64)
net = slim.repeat(inputs, 2, slim.conv2d, 64, [3, 3], scope='conv1')
# 2X2最大池化,輸出net為(112,112,64)
net = slim.max_pool2d(net, [2, 2], scope='pool1')
# conv2兩次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為128,輸出net為(112,112,128)
net = slim.repeat(net, 2, slim.conv2d, 128, [3, 3], scope='conv2')
# 2X2最大池化,輸出net為(56,56,128)
net = slim.max_pool2d(net, [2, 2], scope='pool2')
# conv3三次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為256,輸出net為(56,56,256)
net = slim.repeat(net, 3, slim.conv2d, 256, [3, 3], scope='conv3')
# 2X2最大池化,輸出net為(28,28,256)
net = slim.max_pool2d(net, [2, 2], scope='pool3')
# conv3三次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為256,輸出net為(28,28,512)
net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv4')
# 2X2最大池化,輸出net為(14,14,512)
net = slim.max_pool2d(net, [2, 2], scope='pool4')
# conv3三次[3,3]卷積網(wǎng)絡(luò),輸出的特征層為256,輸出net為(14,14,512)
net = slim.repeat(net, 3, slim.conv2d, 512, [3, 3], scope='conv5')
# 2X2最大池化,輸出net為(7,7,512)
net = slim.max_pool2d(net, [2, 2], scope='pool5')
# 利用卷積的方式模擬全連接層,效果等同,輸出net為(1,1,4096)
net = slim.conv2d(net, 4096, [7, 7], padding='VALID', scope='fc6')
net = slim.dropout(net, dropout_keep_prob, is_training=is_training,
scope='dropout6')
# 利用卷積的方式模擬全連接層,效果等同,輸出net為(1,1,4096)
net = slim.conv2d(net, 4096, [1, 1], scope='fc7')
net = slim.dropout(net, dropout_keep_prob, is_training=is_training,
scope='dropout7')
# 利用卷積的方式模擬全連接層,效果等同,輸出net為(1,1,1000)
net = slim.conv2d(net, num_classes, [1, 1],
activation_fn=None,
normalizer_fn=None,
scope='fc8')
# 由于用卷積的方式模擬全連接層,所以輸出需要平鋪
if spatial_squeeze:
net = tf.squeeze(net, [1, 2], name='fc8/squeezed')
return net
圖片預(yù)測(cè)
在圖片預(yù)測(cè)之前首先看看整個(gè)文檔的結(jié)構(gòu)。需要完整代碼可以直接下載
VGG16的模型下載可以用
鏈接: https://pan.baidu.com/s/18IT3ILvnD0uUJDx9-ums2A
提取碼: jr6u 完成

model用于存儲(chǔ)模型,nets用于存儲(chǔ)網(wǎng)絡(luò)結(jié)構(gòu),test_data用于存放圖片,demo就是之后要執(zhí)行的測(cè)試程序。
圖片預(yù)測(cè)的步驟其實(shí)就是利用訓(xùn)練好的模型進(jìn)行預(yù)測(cè)。
1、載入圖片
2、建立會(huì)話Session;
3、將img_input的placeholder傳入網(wǎng)絡(luò),建立網(wǎng)絡(luò)結(jié)構(gòu);
4、初始化所有變量;
5、利用saver對(duì)象restore載入所有參數(shù)。
6、讀取預(yù)測(cè)結(jié)果
demo.py的代碼如下:
from nets import vgg16
import tensorflow as tf
import numpy as np
import utils
# 讀取圖片
img1 = utils.load_image("./test_data/dog.jpg")
# 對(duì)輸入的圖片進(jìn)行resize,使其shape滿足(-1,224,224,3)
inputs = tf.placeholder(tf.float32,[None,None,3])
resized_img = utils.resize_image(inputs, (224, 224))
# 建立網(wǎng)絡(luò)結(jié)構(gòu)
prediction = vgg16.vgg_16(resized_img)
# 載入模型
sess = tf.Session()
ckpt_filename = './model/vgg_16.ckpt'
sess.run(tf.global_variables_initializer())
saver = tf.train.Saver()
saver.restore(sess, ckpt_filename)
# 最后結(jié)果進(jìn)行softmax預(yù)測(cè)
pro = tf.nn.softmax(prediction)
pre = sess.run(pro,feed_dict={inputs:img1})
# 打印預(yù)測(cè)結(jié)果
utils.print_prob(pre[0], './synset.txt')
utils里是一些工具代碼(工具人),包括載入圖片、圖片大小更改、打印預(yù)測(cè)結(jié)果等:
import matplotlib.image as mpimg
import numpy as np
import tensorflow as tf
from tensorflow.python.ops import array_ops
def load_image(path):
# 讀取圖片,rgb
img = mpimg.imread(path)
# 將圖片修剪成中心的正方形
short_edge = min(img.shape[:2])
yy = int((img.shape[0] - short_edge) / 2)
xx = int((img.shape[1] - short_edge) / 2)
crop_img = img[yy: yy + short_edge, xx: xx + short_edge]
return crop_img
def resize_image(image, size,
method=tf.image.ResizeMethod.BILINEAR,
align_corners=False):
with tf.name_scope('resize_image'):
image = tf.expand_dims(image, 0)
image = tf.image.resize_images(image, size,
method, align_corners)
image = tf.reshape(image, tf.stack([-1,size[0], size[1], 3]))
return image
def print_prob(prob, file_path):
synset = [l.strip() for l in open(file_path).readlines()]
# 將概率從大到小排列的結(jié)果的序號(hào)存入pred
pred = np.argsort(prob)[::-1]
# 取最大的1個(gè)、5個(gè)。
top1 = synset[pred[0]]
print(("Top1: ", top1, prob[pred[0]]))
top5 = [(synset[pred[i]], prob[pred[i]]) for i in range(5)]
print(("Top5: ", top5))
return top1
該圖的預(yù)測(cè)結(jié)果為:

('Top1: ', 'n02099601 golden retriever', 0.98766345)
('Top5: ', [('n02099601 golden retriever', 0.98766345), ('n02099712 Labrador retriever', 0.0108569125), ('n02101556 clumber, clumber spaniel', 0.00039345716), ('n02102480 Sussex spaniel', 0.0002893341), ('n02102318 cocker spaniel, English cocker spaniel, cocker', 0.00018955152)])
以上就是VGG16模型的復(fù)現(xiàn)及其詳解(包含如何預(yù)測(cè))的詳細(xì)內(nèi)容,更多關(guān)于VGG16模型復(fù)現(xiàn)預(yù)測(cè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
pytest fixtures裝飾器的使用和如何控制用例的執(zhí)行順序
這篇文章主要介紹了pytest fixtures裝飾器的使用和如何控制用例的執(zhí)行順序,幫助大家更好的理解和使用pytest測(cè)試框架,感興趣的朋友可以了解下2021-01-01
Python中的None與 NULL(即空字符)的區(qū)別詳解
這篇文章主要介紹了Python中的None與 NULL(即空字符)的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Python讀取xlsx文件的實(shí)現(xiàn)方法
這篇文章主要介紹了Python讀取xlsx文件的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
Windows 平臺(tái)做 Python 開發(fā)的最佳組合(推薦)
在 Windows 上如何做 Python 開發(fā)呢?相信大神們都會(huì)有自己的解決方案,但本文希望介紹微軟官方發(fā)布的 Terminal 和 Visual Studio Code,希望它們能構(gòu)建更流暢的 Windows 開發(fā)體驗(yàn),感興趣的朋友跟隨小編一起看看吧2020-07-07
解決Python運(yùn)行文件出現(xiàn)out of memory框的問(wèn)題
今天小編就為大家分享一篇解決Python運(yùn)行文件出現(xiàn)out of memory框的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
python用socket實(shí)現(xiàn)協(xié)議TCP長(zhǎng)連接框架
大家好,本篇文章主要講的是python用socket實(shí)現(xiàn)協(xié)議TCP長(zhǎng)連接框架,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02
Django項(xiàng)目基礎(chǔ)配置和基本使用過(guò)程解析
這篇文章主要介紹了Django項(xiàng)目基礎(chǔ)配置和基本使用過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11

