ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

迁移学习VGG16实现猫狗大战

2020-02-05 17:08:54  阅读:733  来源: 互联网

标签:img VGG16 batch 大战 test 迁移 model size


本文主要讲述如何使用keras来微调VGG16模型在kaggle的猫狗大战的数据集上实现迁移学习,精度达到了97%,在多训练几个epoch会更高,如果本文有错误的地方欢迎大家斧正,有什么问题也欢迎大家与我交流讨论。

一、对数据集进行预处理

读取图像数据存储到数组中,然后归一化到0-1之间,将图像大小统一resize为100x100

设置数据生成器,减小内存负担。

def data_generator(all_img_name, all_label, batch_size, h=100, w=100):
    """
    该函数用于生成批量的数据,用于fit_generator批量训练
    :param all_train_name:
    :param batch_size:
    :return:
    """

    batches = len(all_img_name) // batch_size

    while True:
        for i in range(batches):
            name_batch = all_img_name[i * batch_size: (i + 1) * batch_size]
            label_batch = all_label[i * batch_size: (i + 1) * batch_size]
            # label 转化为one-hot编码
            Y = to_categorical(label_batch, num_classes=2)

            X = np.array([])
            for j in range(batch_size):
                img_path = name_batch[j]
                labels = label_batch

                # 读取img
                img = cv.imread(img_path)
                # resize
                img = cv.resize(img, (h, w))/255.0

                if len(X.shape) < 3:
                    X = img[np.newaxis, :, :]
                else:
                    X = np.concatenate((X, img[np.newaxis, :, :]), axis=0)

            yield (X, Y)

二、定义网络结构

在这里我们以VGG16的结构为基础,去掉其后面的全连接层,加上自己设计的3个全连接层,下图左图为我使用的网络结构右图为VGG16的网络结构,我修改了网络的输入大小,vgg16的大小为224x224我的大小为100x100

                   

keras封装了vgg模型的函数

model = keras.applications.vgg16.VGG16(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000)

你可以在下面这个地址下载VGG16的权重(如果你设置weights参数为imagenet的话他会自动下载)

https://github.com/fchollet/deep-learning-models/releases/download/v0.1/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5

参数
include_top:是否保留顶层的3个全连接网络
weights:None代表随机初始化,即不加载预训练权重。'imagenet'代表加载预训练权重,这里输入权重的地址,如果你填的是imagenet那么他会自动从github上下载VGG16的权重
input_tensor:可填入Keras tensor作为模型的图像输出tensor
input_shape:可选,仅当include_top=False有效,应为长为3的tuple,指明输入图片的shape,图片的宽高必须大于48,如(200,200,3)
返回值
pooling:当include_top=False时,该参数指定了池化方式。None代表不池化,最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化,‘max’代表全局最大值池化。
classes:可选,图片分类的类别数,仅当include_top=True并且不加载预训练权重时可用。

def vgg_model(vgg_weights_path):
    # 定义模型
    base_model = VGG16(weights=vgg_weights_path,
                       include_top=False, input_shape=(100, 100, 3))

    x = Flatten()(base_model.output)
    x = Dense(1024, activation="relu")(x)
    x = Dense(200, activation="relu")(x)
    y_pred = Dense(2, activation="softmax")(x)

    model = Model(inputs=base_model.input, outputs=y_pred)
    model.summary()

    return model

训练

使用sklearn.model_selection的train_test_split函数来划分训练集与测试集

train_X, test_X, train_Y, test_Y = train_test_split(x_name, y, test_size=0.2, random_state=0)

使用keras里面的fit_generator()函数来进行批量训练

history = model.fit_generator(generator=data_generator(train_X, train_Y, batch_size, h, w),
                    steps_per_epoch=len(train_X) // batch_size,
                    epochs=epoch, verbose=1, validation_data=data_generator(test_X, test_Y, h, w),
                    validation_steps=len(test_X) // batch_size)

在这里我是使用GPU来进行训练的,一个epoch大概3-4分钟左右

预测

预测效果如下,我总共训练了4个epoch,在训练集上的精度达到了98%,在测试集上的精度达到了95%,稍微有点过拟合,加个dropout然后稍微调一下应该就好了。

总结

keras真的是简洁方便

白金之星1717 发布了5 篇原创文章 · 获赞 6 · 访问量 2146 私信 关注

标签:img,VGG16,batch,大战,test,迁移,model,size
来源: https://blog.csdn.net/qq_41997888/article/details/104162436

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有