图片训练集下载地址
图片资源不大,学习使用。
可以先看这篇文章图片训练。https://blog.csdn.net/java_leaf/article/details/136758861
VGG(Visual Geometry Group)是一种深度卷积神经网络模型
看下面的训练,少量图片在第10轮基本上准确率达到 100%,ho dear! 太惊人了。
查看VGG网络参数
vgg = VGG16(weights='imagenet',
include_top=False, input_shape=(200, 200, 3))
vgg.summary();
Model: "vgg16"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 200, 200, 3)] 0
block1_conv1 (Conv2D) (None, 200, 200, 64) 1792
block1_conv2 (Conv2D) (None, 200, 200, 64) 36928
block1_pool (MaxPooling2D) (None, 100, 100, 64) 0
block2_conv1 (Conv2D) (None, 100, 100, 128) 73856
block2_conv2 (Conv2D) (None, 100, 100, 128) 147584
block2_pool (MaxPooling2D) (None, 50, 50, 128) 0
block3_conv1 (Conv2D) (None, 50, 50, 256) 295168
block3_conv2 (Conv2D) (None, 50, 50, 256) 590080
block3_conv3 (Conv2D) (None, 50, 50, 256) 590080
block3_pool (MaxPooling2D) (None, 25, 25, 256) 0
block4_conv1 (Conv2D) (None, 25, 25, 512) 1180160
block4_conv2 (Conv2D) (None, 25, 25, 512) 2359808
block4_conv3 (Conv2D) (None, 25, 25, 512) 2359808
block4_pool (MaxPooling2D) (None, 12, 12, 512) 0
block5_conv1 (Conv2D) (None, 12, 12, 512) 2359808
block5_conv2 (Conv2D) (None, 12, 12, 512) 2359808
block5_conv3 (Conv2D) (None, 12, 12, 512) 2359808
block5_pool (MaxPooling2D) (None, 6, 6, 512) 0
=================================================================
Total params: 14,714,688
Trainable params: 14,714,688
Non-trainable params: 0
_________________________________________________________________
vgg帮你定义好了网络模型。
这里还是重提一下:
VGG是由Simonyan 和Zisserman在文献《Very Deep Convolutional Networks for Large Scale Image Recognition》中提出卷积神经网络模型,其名称来源于作者所在的牛津大学视觉几何组(Visual Geometry Group)的缩写。
该模型参加2014年的 ImageNet图像分类与定位挑战赛,取得了优异成绩:在分类任务上排名第二,在定位任务上排名第一。
可能大家会想,这样一个这么强的模型肯定很复杂吧?
其实一点也不复杂,它的结构如下图所示:
这是一个VGG被用到烂的图,但确实很好的反应了VGG的结构:
1、一张原始图片被resize到(224,224,3)。
2、conv1两次[3,3]卷积网络,输出的特征层为64,输出为(224,224,64),再2X2最大池化,输出net为(112,112,64)。
3、conv2两次[3,3]卷积网络,输出的特征层为128,输出net为(112,112,128),再2X2最大池化,输出net为(56,56,128)。
4、conv3三次[3,3]卷积网络,输出的特征层为256,输出net为(56,56,256),再2X2最大池化,输出net为(28,28,256)。
5、conv4三次[3,3]卷积网络,输出的特征层为512,输出net为(28,28,512),再2X2最大池化,输出net为(14,14,512)。
6、conv5三次[3,3]卷积网络,输出的特征层为512,输出net为(14,14,512),再2X2最大池化,输出net为(7,7,512)。
7、利用卷积的方式模拟全连接层,效果等同,输出net为(1,1,4096)。共进行两次。
8、利用卷积的方式模拟全连接层,效果等同,输出net为(1,1,1000)。
最后输出的就是每个类的预测。
————————————————
编码实现demo
# -*- coding: utf-8 -*-
# file: VGG16_ch01.py
# author: laich
"""
VGG 迁移学习:特殊的训练模型,针对小数据集
RMSprop 优化器 解决了 RProp 无法处理小批量的问题。
"""
import os
import pathlib
import keras
import numpy as np
from keras.applications import VGG16
import tensorflow as tf
from keras.preprocessing.image import ImageDataGenerator
base_dir = 'E:/usr/';
train_dir = os.path.join(base_dir, 'train')
train_dir_path = pathlib.Path(train_dir)
test_dir = os.path.join(base_dir, 'validation')
class_names = np.array([item.name for item in train_dir_path.glob('*') if item.is_dir()])
print(class_names)
# 标准化到[0,1]
train_data_gen = ImageDataGenerator(rescale=1. / 255)
test_data_gen = ImageDataGenerator(rescale=1. / 255)
# flow_from_directory 以文件夹路径为参数,生成经过数据提升/归一化后的数据,在一个无限循环中无限产生batch数据
train_data = train_data_gen.flow_from_directory(train_dir, batch_size=15,
shuffle=True,
# classes=list(class_names),
# class_mode='binary',
target_size=(200, 200))
test_data = test_data_gen.flow_from_directory(test_dir, batch_size=10,
shuffle=True,
# class_mode='binary',
target_size=(200, 200))
# print(train_data.classes)
vgg = VGG16(weights='imagenet',
include_top=False, input_shape=(200, 200, 3))
vgg.summary();
# 冻结卷积最后4层
for layer in vgg.layers[:-4]:
layer.trainable = False
# 创建模型
vgg_model = keras.Sequential([
vgg,
])
vgg_model.add(tf.keras.layers.Flatten())
vgg_model.add(tf.keras.layers.Dense(128, activation='relu'))
vgg_model.add(tf.keras.layers.Dense(64, activation='relu'))
# 输出层
vgg_model.add(tf.keras.layers.Dense(4, activation='softmax'))
# 要用很小的学习率,过大会破坏最后一层的权重,达不到效果
# RMSProp 代表均方根传播,采用梯度下降算法进行优化。它属于自适应优化算法的范畴。这些自适应优化器带来了更快、更高效的学习时间。
# https://mazhonggang.blog.csdn.net/article/details/135141033
vgg_model.compile(optimizer=tf.optimizers.RMSprop(learning_rate=0.0001),
loss=tf.losses.CategoricalCrossentropy(),
metrics=['accuracy']
)
history = vgg_model.fit(train_data, steps_per_epoch=10,
epochs=15, # 训练15轮
batch_size=10,
verbose=2,
validation_steps=8 # 验证批次
)
'''绘图查看训练结果'''
vgg_model.save('./h5/my_model_VGG.h5')
验证数据
class_names = ['cat', 'daisy', 'roses', 'woman']
# 读取并调用模型
pre_model = tf.keras.models.load_model("./h5/my_model_VGG.h5")
# print(pre_model)
cat_url = "http://c-ssl.duitang.com/uploads/item/202006/28/20200628000044_bltmw.jpg"
玫瑰 = "https://pics0.baidu.com/feed/d000baa1cd11728bba9bc66464ad5dc3c2fd2ca5.jpeg"
fl01 = "https://ss2.meipian.me/users/9465404/35e29dac75f7bac444fcce3d8af81123.jpg"
mm = "http://pic.imeitou.com/uploads/allimg/2019052008/3de1q2uscco.jpg";
mm2 = "http://img.520touxiang.com/uploads/allimg/160910/3-160910120J5-50.jpg"
cat_1 = "https://img-qn.51miz.com/preview/photo/00/01/58/88/P-1588885-0DA71C19.jpg"
flower_1 = "https://img.lrgarden.cn/feed_pic/167/20/1000271015_1000013406_1498890132.jpg"
# img0 = PIL.Image.open(str(cat_url)) # 打开一张玫瑰花图片查看
# plt.imshow(img0)
# plt.show()
女人 = "https://img11.360buyimg.com/n1/jfs/t1/14078/14/23682/60708/623db2dcE2d21a0b5/cae014f9cfb7047b.jpg"
sunflower_path = tf.keras.utils.get_file('file_' + str(random.randint(1, 1000)), origin=flower_1)
img = tf.keras.preprocessing.image.load_img(
sunflower_path, target_size=(200, 200)
)
plt.imshow(img)
plt.show()
img_array = tf.keras.preprocessing.image.img_to_array(img)
img_array = tf.expand_dims(img_array, 0) # Create a batch
##将预测结果转化为概率值
result = pre_model.predict(img_array)
# 将预测结果转化为概率值
result2 = np.squeeze(pre_model.predict(img_array))
predict_class = np.argmax(result, axis=1)