猫狗识别大战实践经验分享

举报
huxian123 发表于 2019/07/27 10:28:30 2019/07/27
【摘要】 猫狗识别大战是图像识别领域经典的案例,本次案例主要基于ModelArts人工智能平台,利用VGG模型对猫狗图片进行训练并进行保存,对测试图片进行预测。

猫狗识别大战是图像识别领域经典的案例,本次案例主要基于ModelArts人工智能平台,利用VGG模型对猫狗图片进行训练并进行保存,对测试图片进行预测。

部分代码如下:

导入依赖库
### 导入依赖库
import os, cv2, random
import numpy as np

# 画图工具
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

from keras.layers import Input, Dense
from keras.optimizers import RMSprop
from keras.callbacks import Callback, EarlyStopping, TensorBoard
from keras.applications.vgg16 import VGG16
from keras.models import Model
from keras.utils import np_utils

from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

from keras import backend as K
K.set_image_data_format('channels_last') # 数据格式data_format设置为 NHWC

下载数据集

#下载数据压缩包,解压,然后清理压缩包。
from modelarts.session import Session
session = Session()

if not os.path.exists('./data'):
    session.download_data(
    bucket_path="modelarts-labs/notebook/DL_image_recognition/image_recognition.tar.gz",
    path="./image_recognition.tar.gz")

    # 使用tar命令解压资源包
    !tar xf ./image_recognition.tar.gz

    # 清理压缩包
    !rm -f ./image_recognition.tar.gz

数据下载.jpg

读取数据集,将数据加载到内存中,并对数据进行预处理

### 读取数据集

#读取数据集,并把图像resize到 128 * 128 大小。
DATA_DIR = './data/' # 数据集路径

ROWS = 128
COLS = 128
CHANNELS = 3

image_file_names = [DATA_DIR+i for i in os.listdir(DATA_DIR)] 
dogs = [DATA_DIR+i for i in os.listdir(DATA_DIR) if 'dog' in i]
cats = [DATA_DIR+i for i in os.listdir(DATA_DIR) if 'cat' in i]

# 数据洗牌
random.shuffle(image_file_names)

def read_image(file_path):
    img = cv2.imread(file_path, cv2.IMREAD_COLOR) # 彩色模式读取图像
    return cv2.resize(img, (ROWS, COLS), interpolation=cv2.INTER_CUBIC)

def prep_data(image_file_names):
    count = len(image_file_names)
    data = np.ndarray((count, ROWS, COLS, CHANNELS), dtype=np.uint8)
    
    for i, image_file in enumerate(image_file_names):
        image = read_image(image_file)
        data[i] = image
        if i%1000 == 0: print('Processed {} of {}'.format(i, count))
    
    return data

# 读取图片至内存
images = prep_data(image_file_names)

数据加载.jpg

给图片打标签 和 切分数据

#我们根据图片名称包含的字符串给图片打标签。我们用0表示cat,1表示dog。
num_train_samples = len(image_file_names)
num_classes = 2
labels = []

index = 0
for filename in image_file_names:
    if 'dog' in filename:
        labels.append(1)
    elif 'cat' in filename:
        labels.append(0)
        
# 把类别标签转换为onehot编码
labels = np_utils.to_categorical(labels, num_classes)
### 切分数据集

#(train_data,train_label)是训练数据,(test_data,test_label)是测试数据。测试数据占25%。
train_data, test_data, train_label, test_label = train_test_split(images, labels, test_size=0.25, random_state=10)
查看猫狗样本图片
### 查看猫狗的样本图片

#这些图片是经过尺寸调整后的图片
#%%
def show_cats_and_dogs(idx):
    cat = read_image(cats[idx])
    dog = read_image(dogs[idx])
    pair = np.concatenate((cat, dog), axis=1)
    plt.figure(figsize=(10,5))
    plt.imshow(pair)
    plt.show()
    
for idx in range(0,3):
    show_cats_and_dogs(idx)

猫狗图片1.jpg

猫狗图片2.jpg

猫狗图片3.jpg

构建神经网络

Keras是一个非常简单易用的,适合新手入门的深度学习引擎。接下来,我们使用Keras搭建一个VGG16卷积神经网络。

##设置超参
batch_size = 32 # 批大小
learning_rate = 1e-4 # 设置学习率为1e-4
##设置优化器
optimizer = RMSprop(lr=learning_rate) # 优化器使用 RMSprop 
objective = 'binary_crossentropy' # loss 函数使用交叉熵
def load_model():
    # 这是一个模型参数随机初始化的模型,如果想要加载imagenet预训练模型,可以设置 weights='imagenet'
    base_model = VGG16(include_top=False, weights=None, input_shape=(ROWS, COLS, CHANNELS), pooling='avg')
    
    # 修改base_model的模型输出层
    prediction_layer = Dense(2, activation='softmax')(base_model.output)
    
    # 组装成新的模型
    model = Model(inputs=base_model.input, outputs=prediction_layer)
    
    # 模型编译
    model.compile(loss=objective, optimizer=optimizer, metrics=['accuracy'])
    return model
model = load_model()

模型结构概览

可以查看到刚刚搭建的神经网络结构的详情。

model.summary()

模型概览.jpg


模型训练

在模型训练过程中,为了防止过拟合,我们使用了early stopping策略,当val_loss在连续3个epoch不再减少的情况下,就停止训练。

可以看到训练日志输出,其中会打印Loss(损失函数)和acc(精确度)信息。

epochs = 10 # 训练轮数

# early stopping策略
early_stopping = EarlyStopping(monitor='val_loss', patience=3, verbose=1, mode='auto')   

def run_train():
    
    # 开始训练
    history = model.fit(
        train_data, 
        train_label, 
        batch_size=batch_size, 
        epochs=epochs,
        validation_split=0.25,  # 训练数据中,抽取25%的数据作为验证数据
        verbose=2,
        shuffle=True,
        callbacks=[early_stopping]) 
    return history

history = run_train()

模型训练.jpg

保存模型

训练好的模型可以保存起来,永久使用。

OUTPUT = 'output'

if not os.path.exists(OUTPUT):
    os.mkdir(OUTPUT)

model.save(os.path.join(OUTPUT, 'model.h5'))

可视化训练过程

将Loss随epoch的变化趋势使用折线图展示

loss = history.history['loss']
val_loss = history.history['val_loss']

plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.title('VGG-16 Loss Trend')
plt.plot(loss, 'blue', label='Training Loss')
plt.plot(val_loss, 'green', label='Validation Loss')
plt.xticks(range(0, epochs)[0::2])
plt.legend()
plt.show()

结果展示1.jpg

将accurary随epoch的变化趋势使用折线图展示

acc = history.history['acc']
val_acc = history.history['val_acc']

plt.xlabel('Epochs')
plt.ylabel('acc')
plt.title('VGG-16 acc Trend')
plt.plot(acc, 'blue', label='Training acc')
plt.plot(val_acc, 'green', label='Validation acc')
plt.xticks(range(0, epochs)[0::2])
plt.legend()
plt.show()

结果展示2.jpg

样本数据预测

预测测试集

predictions = model.predict(test_data, verbose=0)
#直观展示10个样本数据的预测结果
for i in range(0,10):
    p = predictions[i]
    
    if round(p[1]) == 1: 
        print('I am {:.2%} sure this is a Dog'.format(p[1]))
    else: 
        print('I am {:.2%} sure this is a Cat'.format(1 - p[1]))
        
    plt.imshow(test_data[i])
    plt.show()

结果1.jpg

结果2.jpg

结果3.jpg

结果4.jpg

结果5.jpg

结果6.jpg

结果7.jpg

结果8.jpg

结果9.jpg

结果10.jpg

评估模型准确度

通过测试集的预测结果,计算模型的准确度。

predictions_test_array = []
test_label_array = []

# 将onehot编码的数据进行格式转换
for p in predictions:
    if round(p[1]) == 1:
        predictions_test_array.append(1)
    else:
        predictions_test_array.append(0)
        
for t in test_label:
    if int(t[1]) == 1:
        test_label_array.append(1)
    else:
        test_label_array.append(0)
        
acc = accuracy_score(test_label_array, predictions_test_array)
print('训练得到的猫狗识别模型的准确度是:%f' % acc)

训练得到的猫狗识别模型的准确度是:0.910880


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。