25
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

VGG16の特徴マップを可視化する

Last updated at Posted at 2019-01-22

VGG16とは

畳み込み13層とフル結合3層の計16層から成る畳み込みニューラルネットワークのこと。
2014年のILSVRC(ImageNet Large Scale Visual Recognition Challenge)という画像分類のコンペで提案された。
構成は以下の図を参照。

vgg16_structure.png

可視化する

実際に特徴マップを可視化していく。

  • VGG16学習済みモデル
  • 特徴抽出したい画像

を用意するだけで可視化できる。学習済みモデルに関してはimportすれば自動でダウンロードしてくれる。便利。

特徴マップの選択

  • Convolution Layer
  • Pooling Layer

の2種類を可視化する。

入力に使う画像

turu.jpeg

今回はツルの画像を使う。というのも鳥系の画像は特徴マップが比較的みやすいからだ。

ソースコード

画像の読み込み


    # NOTE: Load image.
    img = image.load_img(args.img, target_size=(224, 224))
    img = image.img_to_array(img)
    img = np.expand_dims(img, axis=0)
    img = preprocess_input(img)
    print("IMAGE FILENAME: %s" % os.path.basename(args.img))

学習済みモデルのロード


    # NOTE: Load trained model.
    print("[status] Loaded model...")
    if args.model is not None:
        model = load_model(args.model)
    elif not (args.model_json is None or args.model_weight is None):
        model = model_from_json(open(args.model_json).read())
        model.load_weights(args.model_weight)
    else:
        model = VGG16(weights="imagenet")

出力する層の選択(Convolution and Pooling Layer)


    # NOTE: Select output layer and predict.
    print("[status] Extract input image features...")
    layers = model.layers[1:19]
    layer_outputs = [layer.output for layer in layers]
    activation_model = models.Model(inputs=model.input, outputs=layer_outputs)
    # activation_model.summary()
    activations = activation_model.predict(img)

    # NOTE: Select visualize layers.
    conv_and_pool_activations = []
    for layer, activation in zip(layers, activations):
        is_pooling_layer = isinstance(layer, MaxPooling2D)
        is_convolution_layer = isinstance(layer, Convolution2D)
        if is_pooling_layer or is_convolution_layer:
            conv_and_pool_activations.append([layer.name, activation])

特徴マップをヒートマップに変換して保存


    # NOTE: Generate heatmap.
    print("[status] Generating heatmaps...")
    os.makedirs(args.directory, exist_ok=True)
    for i, (name, activation) in enumerate(conv_and_pool_activations):
        print("[status] Processing %s layer..." % name)
        n_imgs = activation.shape[3]
        n_cols = math.ceil(math.sqrt(n_imgs))
        n_rows = math.floor(n_imgs / n_cols)
        screens = []
        for y in range(0, n_rows):
            rows = []
            for x in range(0, n_cols):
                j = y * n_cols + x
                if j < n_imgs:
                    featuremap_img = activation[0, :, :, j]
                    rows.append(featuremap_img)
                else:
                    rows.append(np.zeros())
            screens.append(np.concatenate(rows, axis=1))
        screens = np.concatenate(screens, axis=0)
        plt.figure()
        sns.heatmap(screens, xticklabels=False, yticklabels=False)
        save_name = "%s.png" % name
        save_path = os.path.join(args.directory, save_name)
        plt.savefig(save_path)
        plt.close()
    print("[status] Generating heatmap has finished...")

出力結果

heatmaps_turu.gif

Layerが進に従って画像は小さくなり、特徴も大まかになっている。これだけじゃイマイチ分からないので、特徴強度の中から平均強度が最も高い特徴強度を選んでみた。

heatmap_turu.gif

最後は大まかな特徴を捉えられている。すごい。

終わりに

VGG16の特徴マップを可視化しました。
今回使用したコードはGitHubにあげています。
https://github.com/yukitaka13-1110

25
28
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
28

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?