深度学习应用系列(二) | 如何使用keras进行迁移学习,以训练和识别自己的图片集
本文的keras后台为tensorflow,介绍如何利用预编译的模型进行迁移学习,以训练和识别自己的图片集。
官网 https://keras.io/applications/ 已经介绍了各个基于ImageNet的预编译模型,对于我们来说,既可以直接为我所用进行图片识别,也可在其基础上进行迁移学习,以满足自己的需求。
但在迁移学习的例子中,并不描述的十分详细,我将给出一个可运行的代码,以介绍如何进行迁移学习。
from tensorflow.keras.applications.vgg19 import VGG19, preprocess_input
from tensorflow.keras.models import Model
from tensorflow.keras.layers import GlobalAveragePooling2D, Dense
from tensorflow.keras.preprocessing.image import ImageDataGenerator, load_img, img_to_array
from tensorflow.keras.optimizers import SGD
import tensorflow.keras.backend as K # 训练和测试的图片分为'bus', 'dinosaur', 'flower', 'horse', 'elephant'五类
# 其图片的下载地址为 http://pan.baidu.com/s/1nuqlTnN ,总共500张图片,其中图片以3,4,5,6,7开头进行按类区分
# 训练图片400张,测试图片100张;注意下载后,在train和test目录下分别建立上述的五类子目录,keras会按照子目录进行分类识别
NUM_CLASSES = 5
TRAIN_PATH = '/home/yourname/Documents/tensorflow/images/500pics/train'
TEST_PATH = '/home/yourname/Documents/tensorflow/images/500pics/test'
# 代码最后挑出一张图片进行预测识别
PREDICT_IMG = '/home/yourname/Documents/tensorflow/images/500pics/test/elephant/502.jpg'
# FC层定义输入层的大小
FC_NUMS = 1024
# 冻结训练的层数,根据模型的不同,层数也不一样,根据调试的结果,VGG19和VGG16c层比较符合理想的测试结果,本文采用VGG19做示例
FREEZE_LAYERS = 17
# 进行训练和测试的图片大小,VGG19推荐为224×244
IMAGE_SIZE = 224 # 采用VGG19为基本模型,include_top为False,表示FC层是可自定义的,抛弃模型中的FC层;该模型会在~/.keras/models下载基本模型
base_model = VGG19(input_shape=(IMAGE_SIZE, IMAGE_SIZE, 3), include_top=False, weights='imagenet') # 自定义FC层以基本模型的输入为卷积层的最后一层
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(FC_NUMS, activation='relu')(x)
prediction = Dense(NUM_CLASSES, activation='softmax')(x) # 构造完新的FC层,加入custom层
model = Model(inputs=base_model.input, outputs=prediction)
# 可观察模型结构
model.summary()
# 获取模型的层数
print("layer nums:", len(model.layers)) # 除了FC层,靠近FC层的一部分卷积层可参与参数训练,
# 一般来说,模型结构已经标明一个卷积块包含的层数,
# 在这里我们选择FREEZE_LAYERS为17,表示最后一个卷积块和FC层要参与参数训练
for layer in model.layers[:FREEZE_LAYERS]:
layer.trainable = False
for layer in model.layers[FREEZE_LAYERS:]:
layer.trainable = True
for layer in model.layers:
print("layer.trainable:", layer.trainable) # 预编译模型
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy', metrics=['accuracy']) # 给出训练图片的生成器, 其中classes定义后,可让model按照这个顺序进行识别
train_datagen = ImageDataGenerator()
train_generator = train_datagen.flow_from_directory(directory=TRAIN_PATH,
target_size=(IMAGE_SIZE, IMAGE_SIZE), classes=['bus', 'dinosaur', 'flower', 'horse', 'elephant'])
test_datagen = ImageDataGenerator()
test_generator = test_datagen.flow_from_directory(directory=TEST_PATH,
target_size=(IMAGE_SIZE, IMAGE_SIZE), classes=['bus', 'dinosaur', 'flower', 'horse', 'elephant']) # 运行模型
model.fit_generator(train_generator, epochs=5, validation_data=test_generator) # 找一张图片进行预测验证
img = load_img(path=PREDICT_IMG, target_size=(IMAGE_SIZE, IMAGE_SIZE))
# 转换成numpy数组
x = img_to_array(img)
# 转换后的数组为3维数组(224,224,3),
# 而训练的数组为4维(图片数量, 224,224, 3),所以我们可扩充下维度
x = K.expand_dims(x, axis=0)
# 需要被预处理下
x = preprocess_input(x)
# 数据预测
result = model.predict(x, steps=1)
# 最后的结果是一个含有5个数的一维数组,我们取最大值所在的索引号,即对应'bus', 'dinosaur', 'flower', 'horse', 'elephant'的顺序
print("result:", K.eval(K.argmax(result)))
需要说明的是,各个预编译模型在面临不同的数据集时,其训练效果表现不一,需要我们不断地调整各种超参数,以期找到满意的模型
深度学习应用系列(二) | 如何使用keras进行迁移学习,以训练和识别自己的图片集的更多相关文章
- 深度学习基础系列(十一)| Keras中图像增强技术详解
在深度学习中,数据短缺是我们经常面临的一个问题,虽然现在有不少公开数据集,但跟大公司掌握的海量数据集相比,数量上仍然偏少,而某些特定领域的数据采集更是非常困难.根据之前的学习可知,数据量少带来的最直接 ...
- Telegram学习解析系列(二):这我怎么给后台传输数据?
写在前面: 在iOS开发的过程中,有很多时候我们都在和数据打交道,最基本的就是数据的下载和上传了,估计很多很多的小伙伴都在用AFNetworking与后台数据打交道,可有没有想过,哪天AFNetwor ...
- Socket学习总结系列(二) -- CocoaAsyncSocket
这是系列的第二篇 这是这个系列文章的第二篇,要是没有看第一篇的还是建议看看第一篇,以为这个是接着第一篇梳理的 先大概的总结一下在上篇的文章中说的些内容: 1. 整理了一下做IM我们有那些途径,以及我们 ...
- 小白学习Spark系列二:spark应用打包傻瓜式教程(IntelliJ+maven 和 pycharm+jar)
在做spark项目时,我们常常面临如何在本地将其打包,上传至装有spark服务器上运行的问题.下面是我在项目中尝试的两种方案,也踩了不少坑,两者相比,方案一比较简单,本博客提供的jar包适用于spar ...
- 学习CNN系列二:训练过程
卷积神经网络在本质上是一种输入到输出的映射,它能够学习大量的输入与输出之间的映射关系,而不需要任何输入和输出之间精确的数学表达式,只要用已知的模式对卷积神经网络加以训练,网络就具有输入.输出之间映射的 ...
- Dubbo源码学习总结系列二 dubbo-rpc远程调用模块
dubbo本质是一个RPC框架,我们首先讨论这个骨干中的骨干,dubbo-rpc模块. 主要讨论一下几部分内容: 一.此模块在dubbo整体框架中的作用: 二.此模块需要完成的需求功能点及接口定义: ...
- JNI 学习笔记系列(二)
c中没有Boolean类型的值,一般是使用1表示true,0表示false,c中也没有String类型的数据,c中的字符串要通过char数组来表示.c中没有byte类型,一般用char表示byte类型 ...
- Windows-universal-samples学习笔记系列二:Controls, layout, and text
Controls, layout, and text AutoSuggestBox migration Clipboard Commanding Context menu Context menu ( ...
- TensorFlow学习笔记(二)-- MNIST机器学习入门程序学习
此程序被称为TF的 Hello World,19行代码,给人感觉很简单.第一遍看的时候,不到半个小时,就把程序看完了.感觉有点囫囵吞枣的意思,没理解透彻.现在回过头来看,感觉还可以从中学到更多东西. ...
随机推荐
- 【LuoguP3038/[USACO11DEC]牧草种植Grass Planting】树链剖分+树状数组【树状数组的区间修改与区间查询】
模拟题,可以用树链剖分+线段树维护. 但是学了一个厉害的..树状数组的区间修改与区间查询.. 分割线里面的是转载的: ----------------------------------------- ...
- 【游记】NOIP 2017
时间:2017.11.11~2017.11.12 地点:广东省广州市第六中学 Day1 T1:看到题目,心想这种题目也能放在T1? 这个结论我之前遇到过至少3次,自己也简单证明过.初见是NOIP200 ...
- Machine Learning(CF940F+带修改莫队)
题目链接:http://codeforces.com/problemset/problem/940/F 题目: 题意:求次数的mex,mex的含义为某个集合(如{1,2,4,5})第一个为出现的非负数 ...
- 简易微信小程序签到功能
一.效果图 点击签到后 二.数据库 用一张数据表存用户签到的信息,每次用户签到都会往表中添加一条记录了用户id和签到日期的数据,如下图 三.后端 后端写两个接口,一个用于查询用户今日是否签到和签到记录 ...
- elementui table 多选 获取id
//多选相关方法 toggleSelection(rows) { if (rows) { rows.forEach(row => { this.$refs.multipleTable.toggl ...
- python进行EDA探索性数据分析
1.查看数据的类型概况 cols = [c for c in train.columns] #返回数据的列名到列表里 print('Number of features: {}'.format(l ...
- Android开发中的各种尺度单位
px 像素(pixel),表示屏幕上一个物理像素点 不建议直接使用 px 绘制UI,因为受像素密度的影响,以 px 为单位绘制的UI在不同手机上显示的实际大小会不同 dp (用于定义控件大小) 密 ...
- Android使用TextView实现跑马灯效果(自定义控件)
对于一个长的TetxView 折行显示是一个很好的办法,另一种方法就是跑马灯显示(单行滚动) 1.折行显示的长TextView <LinearLayout xmlns:android=" ...
- 任务调度框架kunka
kunka kunka是一个任务调度框架.用户只需要在Task接口中实现自己要执行的功能,并且选择合适的执行器,放入TaskManager中,就可以了完成整个任务了. 实现细节 整个任务信息存放在内存 ...
- elk + suricata 实验环境详细安装教程
1.安装运行suricata,需要*** sudo add-apt-repository ppa:oisf/suricata-stable sudo apt-get update sudo apt-g ...