VGG16模型

转载vgg16-Bubbliiiing
VGG是由Simonyan 和Zisserman在文献《Very Deep Convolutional Networks for Large Scale Image Recognition》中提出卷积神经网络模型,其名称来源于作者所在的牛津大学视觉几何组(Visual Geometry Group)的缩写。
该模型参加2014年的 ImageNet图像分类与定位挑战赛,取得了优异成绩:在分类任务上排名第二,在定位任务上排名第一。
可能大家会想,这样一个这么强的模型肯定很复杂吧?

它的结构如下图所示:

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_1 (InputLayer)         (None, 224, 224, 3)       0
_________________________________________________________________
block1_conv1 (Conv2D)        (None, 224, 224, 64)      1792
_________________________________________________________________
block1_conv2 (Conv2D)        (None, 224, 224, 64)      36928
_________________________________________________________________
block1_pool (MaxPooling2D)   (None, 112, 112, 64)      0
_________________________________________________________________
block2_conv1 (Conv2D)        (None, 112, 112, 128)     73856
_________________________________________________________________
block2_conv2 (Conv2D)        (None, 112, 112, 128)     147584
_________________________________________________________________
block2_pool (MaxPooling2D)   (None, 56, 56, 128)       0
_________________________________________________________________
block3_conv1 (Conv2D)        (None, 56, 56, 256)       295168
_________________________________________________________________
block3_conv2 (Conv2D)        (None, 56, 56, 256)       590080
_________________________________________________________________
block3_conv3 (Conv2D)        (None, 56, 56, 256)       590080
_________________________________________________________________
block3_pool (MaxPooling2D)   (None, 28, 28, 256)       0
_________________________________________________________________
block4_conv1 (Conv2D)        (None, 28, 28, 512)       1180160
_________________________________________________________________
block4_conv2 (Conv2D)        (None, 28, 28, 512)       2359808
_________________________________________________________________
block4_conv3 (Conv2D)        (None, 28, 28, 512)       2359808
_________________________________________________________________
block4_pool (MaxPooling2D)   (None, 14, 14, 512)       0
_________________________________________________________________
block5_conv1 (Conv2D)        (None, 14, 14, 512)       2359808
_________________________________________________________________
block5_conv2 (Conv2D)        (None, 14, 14, 512)       2359808
_________________________________________________________________
block5_conv3 (Conv2D)        (None, 14, 14, 512)       2359808
_________________________________________________________________
block5_pool (MaxPooling2D)   (None, 7, 7, 512)         0
_________________________________________________________________
flatten (Flatten)            (None, 25088)             0
_________________________________________________________________
fullc1 (Dense)               (None, 4096)              102764544
_________________________________________________________________
fullc2 (Dense)               (None, 4096)              16781312
fullc3 (Dense)               (None, 20)                81940
=================================================================
Total params: 134,342,484
Trainable params: 134,342,484
Non-trainable params: 0
_________________________________________________________________
None

因为只对猫和狗进行分类,所以最后的全连接层可以缩小一点,本例子中将其缩小到256。
前面的卷积层可以不训练,因为卷积层的作用主要是提取特征,已经训练好的VGG提取的特征都是比较有用的,所以可以不进行调整,只对最后三个全连接层进行训练。

训练前的准备

1、数据集处理

在数据集处理之前,首先要下载猫狗数据集,地址如下。
链接:https://pan.baidu.com/s/1HBewIgKsFD8hh3ICOnnTwA
提取码:ktab
源代码
链接: https://pan.baidu.com/s/1r79Ey_2ZPZc73GND-kUxxg
提取码: w5bg
下载完后数据集如下,我们需要将其记录在文本中可以让后续可以进行处理

数据存储在train中,我们运行generat_traintxt.py生成train.txt
generat_traintxt.py
就是列举文件夹中的文件,然后根据文件名在末尾打上标签

import oswith open('./train.txt','w') as f:after_generate = os.listdir("./train")for image in after_generate:if image.split(".")[0]=='cat':f.write(image + ";" + "0" + "\n")else:f.write(image + ";" + "1" + "\n")

2创建vgg16 Keras模型

VGG的模型的结构已经在上面介绍过了,利用Keras就可以构建。在这里我给他添加了一个7x7的卷积层,同时把全连接层改为256。

import tensorflow as tf
from tensorflow import keras
from keras import Model,Sequential
from keras.layers import Flatten, Dense, Conv2D, GlobalAveragePooling2D
from keras.layers import Input, MaxPooling2D, GlobalMaxPooling2Ddef VGG16(num_classes):image_input = Input(shape = (224,224,3))# 第一个卷积部分x = Conv2D(64,(3,3),activation = 'relu',padding = 'same',name = 'block1_conv1')(image_input)x = Conv2D(64,(3,3),activation = 'relu',padding = 'same', name = 'block1_conv2')(x)x = MaxPooling2D((2,2), strides = (2,2), name = 'block1_pool')(x)# 第二个卷积部分x = Conv2D(128,(3,3),activation = 'relu',padding = 'same',name = 'block2_conv1')(x)x = Conv2D(128,(3,3),activation = 'relu',padding = 'same',name = 'block2_conv2')(x)x = MaxPooling2D((2,2),strides = (2,2),name = 'block2_pool')(x)# 第三个卷积部分x = Conv2D(256,(3,3),activation = 'relu',padding = 'same',name = 'block3_conv1')(x)x = Conv2D(256,(3,3),activation = 'relu',padding = 'same',name = 'block3_conv2')(x)x = Conv2D(256,(3,3),activation = 'relu',padding = 'same',name = 'block3_conv3')(x)x = MaxPooling2D((2,2),strides = (2,2),name = 'block3_pool')(x)# 第四个卷积部分x = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block4_conv1')(x)x = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block4_conv2')(x)x = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block4_conv3')(x)x = MaxPooling2D((2,2),strides = (2,2),name = 'block4_pool')(x)# 第五个卷积部分x = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block5_conv1')(x)x = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block5_conv2')(x)x = Conv2D(512,(3,3),activation = 'relu',padding = 'same', name = 'block5_conv3')(x)x = MaxPooling2D((2,2),strides = (2,2),name = 'block5_pool')(x)# 分类部分x = Conv2D(256,(7,7),activation = 'relu',padding = 'valid', name = 'block6_conv4')(x)x = Flatten(name = 'flatten')(x)x = Dense(256,activation = 'relu',name = 'fullc1')(x)x = Dense(256,activation = 'relu',name = 'fullc2')(x)x = Dense(num_classes,activation = 'softmax',name = 'fullc3')(x)model = Model(image_input,x,name = 'vgg16')return model

下载权重

这个网址拉到最下面就可以了。
https://github.com/fchollet/deep-learning-models/releases
下载这个文件:vgg16_weights_tf_dim_ordering_tf_kernels.h5。

开始训练

训练的主函数主要包括如下部分:
1、读取训练用txt,并打乱,利用该txt进行训练集和测试集的划分。
2、建立VGG16模型,载入权重。这里要注意skip_mismatch=True。
3、利用model.layers[i].trainable = False将VGG16前面的卷积层设置成不可训练。仅训练最后2层。
3、设定模型保存的方式、学习率下降的方式、是否需要早停。
4、利用model.fit_generator训练模型。
具体代码如下:

from keras.callbacks import TensorBoard, ModelCheckpoint, ReduceLROnPlateau, EarlyStopping
from keras.utils import np_utils
from keras.optimizers import Adam
from vgg import VGG16
import numpy as np
import utils
import cv2
from keras import backend as KK.set_image_data_format('channels_last')def generate_arrays_from_file(lines, batch_size):# 获取总长度n = len(lines)i = 0while 1:X_train = []Y_train = []# 获取一个batch_size大小的数据for b in range(batch_size):if i == 0:np.random.shuffle(lines)name = lines[i].split(';')[0]# 从文件中读取图像img = cv2.imread("./vgg/data/train" + '/' + name)img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)img = img / 255X_train.append(img)Y_train.append(lines[i].split(';')[1])# 读完一个周期后重新开始i = (i + 1) % n# 处理图像X_train = utils.resize_image(X_train, (224, 224))X_train = X_train.reshape(-1, 224, 224, 3)Y_train = np_utils.to_categorical(np.array(Y_train), num_classes=2)yield (X_train, Y_train)if __name__ == "__main__":# 模型保存的位置log_dir = "./vgg/logs/"# 打开数据集的txtwith open("./vgg/data/train.txt", "r") as f:lines = f.readlines()# 打乱行,这个txt主要用于帮助读取数据来训练# 打乱的数据更有利于训练np.random.seed(10101)np.random.shuffle(lines)np.random.seed(None)# 90%用于训练,10%用于估计。num_val = int(len(lines) * 0.1)num_train = len(lines) - num_val# 建立AlexNet模型model = VGG16(2)# 注意要开启skip_mismatch和by_namemodel.load_weights("./vgg/vgg16_weights_tf_dim_ordering_tf_kernels.h5", by_name=True, skip_mismatch=True)# 指定训练层for i in range(0, len(model.layers) - 2):model.layers[i].trainable = False# 保存的方式,3世代保存一次checkpoint_period1 = ModelCheckpoint(log_dir + 'ep{epoch:03d}-loss{loss:.3f}-val_loss{val_loss:.3f}.h5',monitor='acc',save_weights_only=False,save_best_only=True,period=3)# 学习率下降的方式,acc三次不下降就下降学习率继续训练reduce_lr = ReduceLROnPlateau(monitor='acc',factor=0.5,patience=3,verbose=1)# 是否需要早停,当val_loss一直不下降的时候意味着模型基本训练完毕,可以停止early_stopping = EarlyStopping(monitor='val_loss',min_delta=0,patience=10,verbose=1)# 交叉熵model.compile(loss='categorical_crossentropy',optimizer=Adam(lr=1e-3),metrics=['accuracy'])# 一次的训练集大小batch_size = 16print('Train on {} samples, val on {} samples, with batch size {}.'.format(num_train, num_val, batch_size))# 开始训练model.fit_generator(generate_arrays_from_file(lines[:num_train], batch_size),steps_per_epoch=max(1, num_train // batch_size),validation_data=generate_arrays_from_file(lines[num_train:], batch_size),validation_steps=max(1, num_val // batch_size),epochs=50,initial_epoch=0,callbacks=[checkpoint_period1, reduce_lr])model.save_weights(log_dir + 'last1.h5')

在训练和预测中用到了util模块的代码调用,具体为裁减图形 重新设定输入图片大小为(n,224,224,3),

import matplotlib.image as mpimg
import numpy as np
import cv2
import tensorflow as tf
from tensorflow.python.ops import array_opsdef load_image(path):# 读取图片,rgbimg = 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_imgdef resize_image(image, size):with tf.name_scope('resize_image'):images = []for i in image:i = cv2.resize(i, size)images.append(i)images = np.array(images)return images

结果预测

具体说明图像显示

mport numpy as np
import utils
import cv2
from keras import backend as K
from vgg import VGG16
import matplotlib.pyplot as pltK.set_image_data_format('channels_last')
class_classification = ["cat", "dog"]if __name__ == "__main__":model = VGG16(2)model.load_weights("./logs/last1.h5")# img = cv2.imread("./data/train/cat.1.jpg")# img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)# img = img/255# img = np.expand_dims(img,axis = 0)# img = utils.resize_image(img,(224,224))# utils.print_answer(np.argmax(model.predict(img)))# print(utils.print_answer(np.argmax(model.predict(img))))# print(class_classification[np.argmax(model.predict(img))])# showwith open("./data/train.txt", "r") as f:lines = f.readlines()np.random.shuffle(lines)plt.figure(figsize=(10, 10))for i in range(9):plt.subplot(3, 3, i+1)num = int(np.random.random() * len(lines))name = lines[num].split(';')[0]img = cv2.imread("./data/train" + '/' + name)img_input = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)img_input = img_input / 255print("image=",np.shape(img_input))img_input = np.expand_dims(img_input, axis=0)print("image2=",np.shape(img_input))img_input = utils.resize_image(img_input, (224, 224))print("image3=" , np.shape(img_input))predit = class_classification[np.argmax(model.predict(img_input))]plt.title("label=%s predit=%s"%(name.split(".")[0], predit))plt.imshow(cv2.resize(img,(224,224)))plt.axis('off')plt.show()

keras迁移学习猫狗大战-Vgg16相关推荐

  1. Keras深度学习使用VGG16预训练神经网络实现猫狗分类

    Keras深度学习使用VGG16预训练神经网络实现猫狗分类 最近刚刚接触深度学习不久,而Keras呢,是在众多的深度学习框架中,最适合上手的,而猫狗的图像分类呢,也算是计算机视觉中的一个经典案例,下面 ...

  2. keras提取模型中的某一层_Keras做图片分类(四):迁移学习--猫狗大战实战

    本项目数据集来自kaggle竞赛,地址: https://www.kaggle.com/c/dogs-vs-cats-redux-kernels-edition/data 数据的训练集放在train文 ...

  3. 迁移学习之VGG16和VGG19

    文章目录 1.输出效果: 2.主文件TransorVGG16AndVGG19.py: 1.输出效果: 实际的图片--Dog: 预测的结果有误.但是没关系,自己可以找一些数据集,在此模型的基础上进行微调 ...

  4. tensorflow迁移学习:VGG16花朵分类

    转自:https://blog.csdn.net/weixin_41770169/article/details/80330581 github地址:https://github.com/126921 ...

  5. 手把手带你从0完成医疗行业影像图像检测三大经典模型InceptionV3-RestNet50-VGG16(附python源代码及数据库)——改变世界经典人工智能项目实战(一)手把手教学迁移学习

    手把手带你从0完成医疗行业影像图像检测三大经典模型InceptionV3-RestNet50-VGG16 1.迁移学习简介 2.项目简介 3.糖尿病视网膜病变数据集 4.考虑类别不平衡问题 5.定义模 ...

  6. 什么是迁移学习?什么时候使用迁移学习?

    迁移学习是一种深度学习策略,它通过将解决一个问题所获得的知识应用于另一个不同但相关的问题来重用这些知识.例如,有3种类型的花:玫瑰.向日葵和郁金香.可以使用标准的预训练模型,如VGG16/19.Res ...

  7. 大作业论文之基于迁移学习的图像预测研究

    基于迁移学习的图像预测研究 摘  要:深度学习技术发展迅速,在图像处理领域取得了显著成果.[2]但是由于部分图像样本少,标注困难,使得深度学习的效果远未达到预期.迁移学习是机器学习中一种新的学习范式, ...

  8. DL之VGG16:基于VGG16(Keras)利用Knifey-Spoony数据集对网络架构进行迁移学习

    DL之VGG16:基于VGG16(Keras)利用Knifey-Spoony数据集对网络架构迁移学习 目录 数据集 输出结果 设计思路 1.基模型 2.思路导图 核心代码 更多输出 数据集 Datas ...

  9. 基于tensorflow2.0实现猫狗大战(搭建网络迁移学习)

    猫狗大战是kaggle平台上的一个比赛,用于实现猫和狗的二分类问题.最近在学卷积神经网络,所以自己动手搭建了几层网络进行训练,然后利用迁移学习把别人训练好的模型直接应用于猫狗分类这个数据集,比较一下实 ...

最新文章

  1. 03-2 BGP专有命令--BGP命令与配置手册
  2. 智能音箱二战:国内Q1出货量5倍增长,BAX上屏、扩类、做家居
  3. Exadata上的分页查询性能测试
  4. 背包问题 codevs2210 数字组合
  5. php代码最佳实践,分享几个 PHP 编码的最佳实践
  6. Struts2中访问web元素
  7. JS 判断一个字符串是否包含在一个数组中
  8. 【MySQL】一条查询语句在MySQL内部的执行过程
  9. 纽约出租车计费问题:数据清洗与初探
  10. Atitit attilax涉及到的大数据 数据分析 数据挖掘 ai人工智能的处理技术 目录 1.1. 大数据 机器视觉 图像处理 数据分析 数据挖掘 知识图谱 ai人工智能方面系列项目 1 2.
  11. 关于我国高等数学教材的版权发财户
  12. Php支付宝掉线,12月5日支付宝崩了怎么回事支付宝登陆不上去一直掉线怎么办
  13. 写贺卡给毕业师姐怎么写计算机系的,师哥送下一届毕业的寄语
  14. 这些优秀的音视频开源框架你值得收藏
  15. PTA 程序设计天梯赛【day2】
  16. 专业卡与游戏卡的区别
  17. 新一代视频编解码标准H266正式公布!
  18. 可视化1300个故事 揭秘6种情节套路
  19. Qt实现桌面画线、标记,流畅绘制,支持鼠标和多点触控绘制原创
  20. 【miscellaneous】星光级超低照度摄像机技术分析

热门文章

  1. vue+python把woff字体文件中的字体全部读取出来
  2. Kafka入门(一) 概述、部署与API的简单使用
  3. SDK接口调用主流程
  4. Python爬虫——百度+新浪微盘下载歌曲
  5. php采集百度top,PHP教程之采集百度音乐程序
  6. 未能加载文件或程序集“xxx”或它的某一个依赖项。试图加载格式不正确的程序。
  7. 一、程序设计和C语言
  8. 此更新不适用于您的计算机 kb4012212,2017 年 3 月发布的适用于 Windows 7 SP1 和 Windows Server 2008 R2 SP1 的纯安全质量更新...
  9. mysql优化十:从架构角度全局理解mysql性能优化
  10. 面试题:谈谈对mysql性能优化的理解