1. 程式人生 > >Keras 利用vgg16進行貓狗識別

Keras 利用vgg16進行貓狗識別

前面我們介紹了基於Tensorflow使用vgg16 fine-tuning實現了貓狗大戰

這裡採用keras實現vgg16 fine-tuning實現了貓狗大戰

1、資料的提取

import os
import numpy as np
import random
from keras.preprocessing import image

def onehot(labels):
    n_sample = len(labels)
    n_class = max(labels) + 1
    onehot_labels = np.zeros((n_sample, n_class))
    onehot_labels[np.arange(n_sample), labels] = 1
    return onehot_labels


def read_and_process_image(data_dir, width=64, height=64, channels=3, preprocess=False):
    train_images = [data_dir + i for i in os.listdir(data_dir)]

    random.shuffle(train_images)

    def read_image(file_path, preprocess):
        img = image.load_img(file_path, target_size=(height, width))
        x = image.img_to_array(img)
        x = np.expand_dims(x, axis=0)
        # if preprocess:
        # x = preprocess_input(x)
        return x

    def prep_data(images, proprocess):
        count = len(images)
        data = np.ndarray((count, height, width, channels), dtype=np.float32)

        for i, image_file in enumerate(images):
            image = read_image(image_file, preprocess)
            data[i] = image

        return data

    def read_labels(file_path):
        labels = []
        for i in file_path:
            label = 1 if 'dog' in i else 0
            labels.append(label)

        return labels

    X = prep_data(train_images, preprocess)
    labels = read_labels(train_images)

    assert X.shape[0] == len(labels)

    print("Train shape: {}".format(X.shape))

    return X, labels



2、vgg 16 的模型複用

WIDTH = 224
HEIGHT = 224
CHANNELS = 3
def vgg16_model(input_shape=(HEIGHT, WIDTH, CHANNELS)):
    vgg16 = VGG16(include_top=False, weights='imagenet', input_shape=input_shape)
    for layer in vgg16.layers:
        layer.trainable = False
    last = vgg16.output
    # 後面加入自己的模型
    x = Flatten()(last)
    x = Dense(256, activation='relu')(x)
    x = Dense(256, activation='relu')(x)
    x = Dense(2, activation='softmax')(x)
    model = Model(inputs=vgg16.input, outputs=x)
    return model

3、模型的訓練

if __name__ == '__main__':
    X, Y = reader2.read_and_process_image('./train/', width=224, height=224, channels=3)
    X_train = X[0:1000, :, :, :]
    X_test = X[5000:6000, :, :, :]
    Y_train = Y[0:1000]
    Y_test = Y[5000:6000]
    model_vgg16 = vgg16_model()
    model_vgg16.summary()
    model_vgg16.compile(loss='categorical_crossentropy', optimizer=Adam(0.0001), metrics=['accuracy'])
    Y_train = reader2.onehot(Y_train)
    Y_test = reader2.onehot(Y_test)
    history = model_vgg16.fit(X_train, Y_train, epochs=5, batch_size=25, verbose=True)
    loss, accuracy = model_vgg16.evaluate(X_test, Y_test, verbose=0)
    print("loss, accuracy", loss, accuracy)

訓練結果

365s 365ms/step - loss: 0.0774 - acc: 0.9900

測試結果:

loss, accuracy 0.43413801922850054 0.958