前言:

上一节介绍的图像识别中一个经典的模型AlexNet,今天介绍的是图像识别领域另一个经典的模型VGG-19。VGG-19是由牛津大学的Oxford Visual Geometry Group实验室发明的。因为不像是AlexNet是由Alex一个人完成的。所以这个模型就按照实验室的名称的缩写命名。VGG-19和AlexNet的整体架构是相似的,只是在AlexNet进行了一些改进,具体的有。

第一: VGG16相比AlexNet的一个改进是采用连续的几个3x3的卷积核代替AlexNet中的较大卷积核(11x11,7x7,5x5)

第二: VGGNet的结构非常简洁,整个网络都使用了同样大小的卷积核尺寸(3x3)和最大池化尺寸(2x2)

VGG-19的架构图:

首先让我们看一下VGG的发展历程,第三行表示VGG不同版本的卷积层数,从11层到13再到16最后达到19层。

首先同样是本程序的主程序:

和上一节的AlexNet几乎一毛一样。所以只把代码公布一下,就不做解释了。

# -*- coding: utf-8 -*-
# @Time    : 2019/7/2 16:07
# @Author  : YYLin
# @Email   : 854280599@qq.com
# @File    : VGG_19_Train.py
# 定义一些模型中所需要的参数
from VGG_19 import VGG19
import tensorflow as tf
import os
import cv2
import numpy as np
from keras.utils import to_categoricalbatch_size = 64
img_high = 100
img_width = 100
Channel = 3
label = 9# 定义输入图像的占位符
inputs = tf.placeholder(tf.float32, [batch_size, img_high, img_width, Channel], name='inputs')
y = tf.placeholder(dtype=tf.float32, shape=[batch_size, label], name='label')
keep_prob = tf.placeholder("float")
is_train = tf.placeholder(tf.bool)model = VGG19(inputs, keep_prob, label)
score = model.fc8
softmax_result = tf.nn.softmax(score)# 定义损失函数 以及相对应的优化器
cross_entropy = -tf.reduce_sum(y*tf.log(softmax_result))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)# 显示最后预测的结果
correct_prediction = tf.equal(tf.argmax(softmax_result, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))# 现在的我只需要加载图像和对应的label即可 不需要加载text中的内容
def load_satetile_image(batch_size=128, dataset='train'):img_list = []label_list = []dir_counter = 0if dataset == 'train':path = '../Dataset/baidu/train_image/train'# 对路径下的所有子文件夹中的所有jpg文件进行读取并存入到一个list中for child_dir in os.listdir(path):child_path = os.path.join(path, child_dir)for dir_image in os.listdir(child_path):img = cv2.imread(os.path.join(child_path, dir_image))img = img / 255.0img_list.append(img)label_list.append(dir_counter)dir_counter += 1else:path = '../Dataset/baidu/valid_image/valid'# 对路径下的所有子文件夹中的所有jpg文件进行读取并存入到一个list中for child_dir in os.listdir(path):child_path = os.path.join(path, child_dir)for dir_image in os.listdir(child_path):img = cv2.imread(os.path.join(child_path, dir_image))img = img / 255.0img_list.append(img)label_list.append(dir_counter)dir_counter += 1# 返回的img_list转成了 np.array的格式X_train = np.array(img_list)Y_train = to_categorical(label_list, 9)# print('to_categorical之后Y_train的类型和形状:', type(Y_train), Y_train.shape)# 加载数据的时候 重新排序data_index = np.arange(X_train.shape[0])np.random.shuffle(data_index)data_index = data_index[:batch_size]x_batch = X_train[data_index, :, :, :]y_batch = Y_train[data_index, :]return x_batch, y_batch# 开始feed 数据并且训练数据
with tf.Session() as sess:sess.run(tf.global_variables_initializer())for i in range(500000//batch_size):# 加载训练集和验证集img, img_label = load_satetile_image(batch_size, dataset='train')img_valid, img_valid_label = load_satetile_image(batch_size, dataset='vaild')# print('使用 mnist.train.next_batch加载的数据集形状', img.shape, type(img))# print('模型使用的是dropout的模型')dropout_rate = 0.5# print('经过 tf.reshape之后数据的形状以及类型是:', img.shape, type(img))if i % 20 == 0:train_accuracy = accuracy.eval(feed_dict={inputs: img, y: img_label, keep_prob: dropout_rate})print("step %d, training accuracy %g" % (i, train_accuracy))train_step.run(feed_dict={inputs: img, y: img_label, keep_prob: dropout_rate})# 输出验证集上的结果if i % 50 == 0:dropout_rate = 1valid_socre = accuracy.eval(feed_dict={inputs: img_valid, y: img_valid_label, keep_prob: dropout_rate})print("step %d, valid accuracy %g" % (i, valid_socre))

本节的核心代码 VGG-19:

从图中我们可以看到VGG-19有16个卷积层,卷积层的通道数分别是64、128、256、512。最后有三个全连接层通道数分别是4096,4096,1000。

第一: VGG-19所有的卷积核大小都是 3 * 3,  步长为1 * 1。 代码中满足要求

第二: VGG-19所有最大池化层的卷积核大小为2 * 2, 步长为1 * 1  代码中满足要求

第三: 根据上图查看一下每层卷积操作的通道数是否与代码对应    显然代码满足要求。

第四: 在第一节的时候我们向模型中增加一些优化技巧,我们发现使用batch normalize的话,能够极大的提高模型的准确率。但是VGG-19中并没有增加。 尝试增加batch normalize。而且也没有使用一些激活函数,所以说这个模型可以尝试的优化方案还是很多的。

# -*- coding: utf-8 -*-
# @Time    : 2019/7/2 8:18
# @Author  : YYLin
# @Email   : 854280599@qq.com
# @File    : VGG_19.py
# 本模型为VGG-19参考代码链接
import tensorflow as tfdef maxPoolLayer(x, kHeight, kWidth, strideX, strideY, name, padding="SAME"):return tf.nn.max_pool(x, ksize=[1, kHeight, kWidth, 1],strides=[1, strideX, strideY, 1], padding=padding, name=name)def dropout(x, keepPro, name=None):return tf.nn.dropout(x, keepPro, name)def fcLayer(x, inputD, outputD, reluFlag, name):with tf.variable_scope(name) as scope:w = tf.get_variable("w", shape=[inputD, outputD], dtype="float")b = tf.get_variable("b", [outputD], dtype="float")out = tf.nn.xw_plus_b(x, w, b, name=scope.name)if reluFlag:return tf.nn.relu(out)else:return outdef convLayer(x, kHeight, kWidth, strideX, strideY, featureNum, name, padding = "SAME"):channel = int(x.get_shape()[-1])with tf.variable_scope(name) as scope:w = tf.get_variable("w", shape=[kHeight, kWidth, channel, featureNum])b = tf.get_variable("b", shape=[featureNum])featureMap = tf.nn.conv2d(x, w, strides=[1, strideY, strideX, 1], padding=padding)out = tf.nn.bias_add(featureMap, b)return tf.nn.relu(tf.reshape(out, featureMap.get_shape().as_list()), name=scope.name)class VGG19(object):def __init__(self, x, keepPro, classNum):self.X = xself.KEEPPRO = keepProself.CLASSNUM = classNumself.begin_VGG_19()def begin_VGG_19(self):"""build model"""conv1_1 = convLayer(self.X, 3, 3, 1, 1, 64, "conv1_1" )conv1_2 = convLayer(conv1_1, 3, 3, 1, 1, 64, "conv1_2")pool1 = maxPoolLayer(conv1_2, 2, 2, 2, 2, "pool1")conv2_1 = convLayer(pool1, 3, 3, 1, 1, 128, "conv2_1")conv2_2 = convLayer(conv2_1, 3, 3, 1, 1, 128, "conv2_2")pool2 = maxPoolLayer(conv2_2, 2, 2, 2, 2, "pool2")conv3_1 = convLayer(pool2, 3, 3, 1, 1, 256, "conv3_1")conv3_2 = convLayer(conv3_1, 3, 3, 1, 1, 256, "conv3_2")conv3_3 = convLayer(conv3_2, 3, 3, 1, 1, 256, "conv3_3")conv3_4 = convLayer(conv3_3, 3, 3, 1, 1, 256, "conv3_4")pool3 = maxPoolLayer(conv3_4, 2, 2, 2, 2, "pool3")conv4_1 = convLayer(pool3, 3, 3, 1, 1, 512, "conv4_1")conv4_2 = convLayer(conv4_1, 3, 3, 1, 1, 512, "conv4_2")conv4_3 = convLayer(conv4_2, 3, 3, 1, 1, 512, "conv4_3")conv4_4 = convLayer(conv4_3, 3, 3, 1, 1, 512, "conv4_4")pool4 = maxPoolLayer(conv4_4, 2, 2, 2, 2, "pool4")conv5_1 = convLayer(pool4, 3, 3, 1, 1, 512, "conv5_1")conv5_2 = convLayer(conv5_1, 3, 3, 1, 1, 512, "conv5_2")conv5_3 = convLayer(conv5_2, 3, 3, 1, 1, 512, "conv5_3")conv5_4 = convLayer(conv5_3, 3, 3, 1, 1, 512, "conv5_4")pool5 = maxPoolLayer(conv5_4, 2, 2, 2, 2, "pool5")print('最后一层卷积层的形状是:', pool5.shape)fcIn = tf.reshape(pool5, [-1, 4*4*512])fc6 = fcLayer(fcIn, 4*4*512, 4096, True, "fc6")dropout1 = dropout(fc6, self.KEEPPRO)fc7 = fcLayer(dropout1, 4096, 4096, True, "fc7")dropout2 = dropout(fc7, self.KEEPPRO)self.fc8 = fcLayer(dropout2, 4096, self.CLASSNUM, True, "fc8")

VGG-19增加batch normalize: 亲测是可以使用的,但是需要将batch_size修改成32不然GPU显存溢出

# -*- coding: utf-8 -*-
# @Time    : 2019/7/2 16:57
# @Author  : YYLin
# @Email   : 854280599@qq.com
# @File    : VGG_19_BN.py
import tensorflow as tf# 相对于第一个版本 增加的批量正则化 2019 7 2
def bn(x, is_training):return tf.layers.batch_normalization(x, training=is_training)def maxPoolLayer(x, kHeight, kWidth, strideX, strideY, name, padding="SAME"):return tf.nn.max_pool(x, ksize=[1, kHeight, kWidth, 1],strides=[1, strideX, strideY, 1], padding=padding, name=name)def dropout(x, keepPro, name=None):return tf.nn.dropout(x, keepPro, name)def fcLayer(x, inputD, outputD, reluFlag, name):with tf.variable_scope(name) as scope:w = tf.get_variable("w", shape=[inputD, outputD], dtype="float")b = tf.get_variable("b", [outputD], dtype="float")out = tf.nn.xw_plus_b(x, w, b, name=scope.name)if reluFlag:return tf.nn.relu(out)else:return outdef convLayer(x, kHeight, kWidth, strideX, strideY, featureNum, name, padding = "SAME"):channel = int(x.get_shape()[-1])with tf.variable_scope(name) as scope:w = tf.get_variable("w", shape=[kHeight, kWidth, channel, featureNum])b = tf.get_variable("b", shape=[featureNum])featureMap = tf.nn.conv2d(x, w, strides=[1, strideY, strideX, 1], padding=padding)out = tf.nn.bias_add(featureMap, b)return tf.nn.relu(tf.reshape(out, featureMap.get_shape().as_list()), name=scope.name)class VGG19(object):def __init__(self, x, keepPro, classNum, is_training):self.X = xself.KEEPPRO = keepProself.CLASSNUM = classNumself.is_training = is_trainingself.begin_VGG_19()def begin_VGG_19(self):"""build model"""conv1_1 = convLayer(self.X, 3, 3, 1, 1, 64, "conv1_1" )conv1_1 = bn(conv1_1, self.is_training)conv1_2 = convLayer(conv1_1, 3, 3, 1, 1, 64, "conv1_2")conv1_2 = bn(conv1_2, self.is_training)pool1 = maxPoolLayer(conv1_2, 2, 2, 2, 2, "pool1")conv2_1 = convLayer(pool1, 3, 3, 1, 1, 128, "conv2_1")conv2_1 = bn(conv2_1, self.is_training)conv2_2 = convLayer(conv2_1, 3, 3, 1, 1, 128, "conv2_2")conv2_2 = bn(conv2_2, self.is_training)pool2 = maxPoolLayer(conv2_2, 2, 2, 2, 2, "pool2")conv3_1 = convLayer(pool2, 3, 3, 1, 1, 256, "conv3_1")conv3_1 = bn(conv3_1, self.is_training)conv3_2 = convLayer(conv3_1, 3, 3, 1, 1, 256, "conv3_2")conv3_2 = bn(conv3_2, self.is_training)conv3_3 = convLayer(conv3_2, 3, 3, 1, 1, 256, "conv3_3")conv3_3 = bn(conv3_3, self.is_training)conv3_4 = convLayer(conv3_3, 3, 3, 1, 1, 256, "conv3_4")conv3_4 = bn(conv3_4, self.is_training)pool3 = maxPoolLayer(conv3_4, 2, 2, 2, 2, "pool3")conv4_1 = convLayer(pool3, 3, 3, 1, 1, 512, "conv4_1")conv4_1 = bn(conv4_1, self.is_training)conv4_2 = convLayer(conv4_1, 3, 3, 1, 1, 512, "conv4_2")conv4_2 = bn(conv4_2, self.is_training)conv4_3 = convLayer(conv4_2, 3, 3, 1, 1, 512, "conv4_3")conv4_3 = bn(conv4_3, self.is_training)conv4_4 = convLayer(conv4_3, 3, 3, 1, 1, 512, "conv4_4")conv4_4 = bn(conv4_4, self.is_training)pool4 = maxPoolLayer(conv4_4, 2, 2, 2, 2, "pool4")conv5_1 = convLayer(pool4, 3, 3, 1, 1, 512, "conv5_1")conv5_1 = bn(conv5_1, self.is_training)conv5_2 = convLayer(conv5_1, 3, 3, 1, 1, 512, "conv5_2")conv5_2 = bn(conv5_2, self.is_training)conv5_3 = convLayer(conv5_2, 3, 3, 1, 1, 512, "conv5_3")conv5_3 = bn(conv5_3, self.is_training)conv5_4 = convLayer(conv5_3, 3, 3, 1, 1, 512, "conv5_4")conv5_4 = bn(conv5_4, self.is_training)pool5 = maxPoolLayer(conv5_4, 2, 2, 2, 2, "pool5")print('最后一层卷积层的形状是:', pool5.shape)fcIn = tf.reshape(pool5, [-1, 4*4*512])fc6 = fcLayer(fcIn, 4*4*512, 4096, True, "fc6")dropout1 = dropout(fc6, self.KEEPPRO)fc7 = fcLayer(dropout1, 4096, 4096, True, "fc7")dropout2 = dropout(fc7, self.KEEPPRO)self.fc8 = fcLayer(dropout2, 4096, self.CLASSNUM, True, "fc8")

VGG-19模型运行的结果分析:

VGG-19 增加BN之后的结果分析:

使用VGG-19模型训练自己的数据集相关推荐

  1. 神经网络学习小记录19——微调VGG分类模型训练自己的数据(猫狗数据集)

    神经网络学习小记录19--微调VGG分类模型训练自己的数据(猫狗数据集) 注意事项 学习前言 什么是VGG16模型 VGG模型的复杂程度 训练前准备 1.数据集处理 2.创建Keras的VGG模型 3 ...

  2. 【转发】实现yolo3模型训练自己的数据集总结

    原文链接:实现yolo3模型训练自己的数据集总结 经过两天的努力,借鉴网上众多博客,在自己电脑上实现了使用yolo3模型训练自己的数据集并进行测试图片.本文主要是我根据下面参考文章一步步实施过程的总结 ...

  3. Deep-Learning-YOLOV4实践:ScaledYOLOv4模型训练自己的数据集调试问题总结

    error error1: CUDA out of memory error2:TypeError: can't convert cuda: error Deep-Learning-YOLOV4实践: ...

  4. alexeyab darknet 编译_【目标检测实战】Darknet—yolov3模型训练(VOC数据集)

    原文发表在:语雀文档 0.前言 本文为Darknet框架下,利用官方VOC数据集的yolov3模型训练,训练环境为:Ubuntu18.04下的GPU训练,cuda版本10.0:cudnn版本7.6.5 ...

  5. 实现yolo3模型训练自己的数据集总结

    经过两天的努力,借鉴网上众多博客,在自己电脑上实现了使用yolo3模型训练自己的数据集并进行测试图片.本文主要是我根据下面参考文章一步步实施过程的总结,可能没参考文章中那么详细,但是会包含一些参考文章 ...

  6. detectron2训练自己的数据集_TensorFlow2学习十五、使用VGG16模型训练自己的数据集...

    一.说明 VGG16在2014年ImageNet比赛中获胜.ImageNet数据集中有1000个图像属于1000个不同的类别. VGG模型的权重是免费的,可以在您自己的模型和应用程序中加载和使用.这使 ...

  7. 用Yolact模型训练自己的数据集

    1.首先用labelme标注数据(分割法) 2.yolact训练的数据集为coco数据集,所以要转化数据集,使用从Git下载的labelme项目中的labelme2coco转换就可以 这里因为我的标注 ...

  8. SSD-Pytorch模型训练自己的数据集

    1.下载SSD-Pytorch代码 SSD-pytorch代码链接: https://github.com/amdegroot/ssd.pytorch git clone https://github ...

  9. 机器学习之模型训练(二)皮马印第安人糖尿病数据集

    1. 数据说明: Pima Indians Diabetes Data Set(皮马印第安人糖尿病数据集) 根据现有的医疗信息预测5年内皮马印第安人糖尿病发作的概率. 数据链接:https://arc ...

最新文章

  1. 用枚举来处理java自定义异常
  2. oracle 存储过程 ,触发器练习
  3. string.h包含哪些函数_多个函数组合拳专治不规则时间转化难题|Excel134
  4. 微软宣布公开预览Dev Spaces for AKS
  5. 【总结】找到自适合的学习方法
  6. Linux 实操———CentOS 6 安装配置 Oracle JDK 1.8
  7. 常用基础Linux操作命令总结与hadoop基础操作命令
  8. JAVA集合(四、ConcurrentHashMap)
  9. FinTech领域实践:乐维监控助力西南某上市城商行IT运维转型升级!
  10. Ruby小白入门笔记之Rubymine工具的快捷键
  11. 查找某个整数(数组)
  12. LintCode 1350: Excel Sheet Column Title
  13. android toast显示在中间,android Toast 弹出在屏幕中间位置以及自定义Toast
  14. 摄影构图学83年绝版_让模特露肩、露腿的摄影师们,我求求你别再祸害“古风摄影”了!...
  15. 解决fatal: could not get a repository handle
  16. HarvestText
  17. 【openlayers】ol3入门一基础篇
  18. java 根据ip获取mac地址,java服务器端根据ip获取客户端mac地址
  19. SwipeRefreshLayout极其简单的下拉刷新工具
  20. c语言输出cad scr文件,CAD脚本文件(*.scr)有什么用?

热门文章

  1. python tomorrow多线程应用
  2. 计算机对逻辑算符的运算次序,逻辑运算符的优先顺序
  3. 虽然这个社会是浮躁的,但是请不要做浮躁的的人
  4. bzoj3875 骑士游戏 最短路
  5. faile什么意思_fail是什么意思_fail在线翻译_英语_读音_用法_例句_海词词典
  6. 云计算需要python吗_国内python云计算是啥
  7. Kafka 如何给集群配置Scram账户认证
  8. 【青春记忆】叹!雪……
  9. HDCP Paring
  10. 不再追求安全感,你才能走向成熟。