前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >以图搜图之模型篇: 基于 InceptionV3 的模型 finetune

以图搜图之模型篇: 基于 InceptionV3 的模型 finetune

作者头像
用户2434869
发布2018-12-14 11:17:56
1.3K0
发布2018-12-14 11:17:56
举报
文章被收录于专栏:yl 成长笔记

在以图搜图的过程中,需要以来模型提取特征,通过特征之间的欧式距离来找到相似的图形。

本次我们主要讲诉以图搜图模型创建的方法。

图片预处理方法,看这里: https://keras.io/zh/preprocessing/image/

本文主要参考了这位大神的文章, 传送门在此: InceptionV3进行fine-tuning

训练模型代码如下:

代码语言:javascript
复制
# 基本流程
# 
import os
import sys
import glob
import argparse
import matplotlib.pyplot as plt

from keras.applications.inception_v3 import InceptionV3, preprocess_input
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
from keras.preprocessing.image import ImageDataGenerator
from keras.optimizers import SGD

# 一、定义函数
IM_WIDTH, IM_HEIGHT = 299, 299   # inceptionV3 指定图片尺寸
FC_SIZE = 1024                   # 全连接层的数量

# 二、数据处理
# 图片归类放在不同文件夹下
train_dir = 'E:/Project/Image/data/finetune/train'  # 训练集数据
val_dir = 'E:/Project/Image/data/finetune/test' # 验证集数据
nb_epoch = 1
batch_size = 15
nb_classes = len(glob.glob(train_dir + "/*"))  # 分类数


# 图片增强
# ImageDataGenerator 会自动根据路径下的文件夹创建标签,所以在代码中只看到输入的 x, 看不到 y
train_datagen = ImageDataGenerator(
    preprocessing_function=preprocess_input,
    rotation_range=30,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True
)

train_generator = train_datagen.flow_from_directory(
    train_dir, target_size=(IM_WIDTH, IM_HEIGHT),batch_size=batch_size, class_mode='categorical'
)

validation_generator = train_datagen.flow_from_directory(
    val_dir, target_size=(IM_WIDTH, IM_HEIGHT),batch_size=batch_size, class_mode='categorical'
)

# 三、使用 bottleneck finetune
# 去掉 模型最外层的全连接层,添加上自己的 全连接层
# 添加新层函数
def add_new_last_layer(base_model, nb_classes):
    x = base_model.output
    x = GlobalAveragePooling2D()(x) # 下采样
    x = Dense(FC_SIZE, activation='relu')(x)
    predict_bottle_feat = Dense(nb_classes, activation='softmax')(x)
    model = Model(input=base_model.input, output=predict_bottle_feat)
    return model

# 冻结 base_model 所有层
def setup_to_transfer_learn(model, base_model):
    for layer in base_model.layers:
        layer.trainable = False
    model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])

# 定义网络框架
base_model = InceptionV3(weights='imagenet', include_top=False)
model = add_new_last_layer(base_model, nb_classes)
setup_to_transfer_learn(model, base_model)

# 训练
# 模式一训练
steps = 20 # 可以自由定义,越大结果越精准,但过大容易过拟合
history_tl = model.fit_generator(
  train_generator,
  epochs=nb_epoch,
  steps_per_epoch=steps,
  validation_data=validation_generator,
  validation_steps=steps,
  class_weight='auto')

# 保存模型
model.save("my_inceptionV3.h5")

使用模型提取指定层的特征:

代码语言:javascript
复制
from keras.preprocessing import image
from keras_applications.inception_v3 import preprocess_input
from keras.models import Model, load_model
import numpy as np

target_size = (229, 229) #fixed size for InceptionV3 architecture
base_model = load_model(filepath="my_inceptionV3.h5")

# 需要提取那一层的特征,此处就写入指定层的名称
model = Model(input=base_model.input, output=base_model.get_layer('block4_pool').output)

img_path = "C:/Users/Administrator/Pictures/搜图/horse.jpg"
img = image.load_img(img_path, target_size=target_size)
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

block4_pool_features = model.predict(x)

使用模型进行预测:

代码语言:javascript
复制
from keras.preprocessing import image
from  keras.models import load_model
import numpy as np
import json
from keras_applications.imagenet_utils import decode_predictions


def predict(model, img, target_size):
  """Run model prediction on image
  Args:
    model: keras model
    img: PIL format image
    target_size: (w,h) tuple
  Returns:
    list of predicted labels and their probabilities
  """
  if img.size != target_size:
    img = img.resize(target_size)

  x = image.img_to_array(img)
  x = np.expand_dims(x, axis=0)
  x = preprocess_input(x)
  preds = model.predict(x)   # 此处获取的为
  return preds[0]            # 返回 numpy array [classes, ]

def decode_predict(probalities_list):
  with open("img_classes.json", 'r') as load_f:
    load_dict = json.load(load_f)
  index = probalities_list.index(max(probalities_list))
  target_class = load_dict[str(index)]
  return target_class

target_size = (229, 229) #fixed size for InceptionV3 architecture
model = load_model(filepath="my_inceptionV3.h5")
img = image.load_img("C:/Users/Administrator/Pictures/搜图/horse.jpg")

res_numpy = predict(model, img, target_size=target_size)
res_list = res_numpy.tolist()
target_class = decode_predict(res_list)
print(target_class)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-11-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档