質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Python

    11707questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • 機械学習

    958questions

    機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

  • TensorFlow

    920questions

  • Keras

    472questions

メルカリのCNN後の次元削減手法について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,072

trafalbad

score 202

メルカリでこんな記事がありました

メルカリに学ぶ深層学習基盤

inceptionV3の中間層から取り出した特徴デカすぎない?リアルタイムで計算できるの?
特徴はPCAで次元潰して計算コスト下げてる

メルカリにおける AI 活用事例 PyCon JP 2018

これに書いてあるのはinceptionv3の中間層から取り出した特徴ベクトルを、PCAで次元削減しているようです。
自分も試しにやって見たのですが、上手く行きません?

kerasのmodelに次元削減は無理なのでしょうか?

この中間層のベクトルを次元削減する手法はどのようにやるのかについて、何か参考になること、推論、資料なんでもいい良いので、知恵を貸していただけないでしょうか?

=>実験

# tfrecordの場合
train_image, train_labels=distorted_input(filenames, batch_size=256, train=True)
train_image
>>><tf.Tensor 'Sub_1:0' shape=(256, 150, 150, 3) dtype=float32>
model= InceptionV3(include_top=False, weights=None, input_tensor=train_image, pooling='avg', classes=200)
model
>>> <keras.engine.training.Model at 0x1a325c4eb8>


# shape指定の場合
model= InceptionV3(include_top=False, weights=None, input_shape=(150,150,3), pooling='avg', classes=200)
model
>>> <keras.engine.training.Model at 0x1a38b6a208>

# 次元削減
pca = PCA(n_components=500)
pca.fit(model)

plt.plot(np.cumsum(pca.explained_variance_ratio_))

# エラー
TypeError                                 Traceback (most recent call last)
<ipython-input-11-ceb44ec0ea8f> in <module>()
      1 
      2 pca = PCA(n_components=500)
----> 3 pca.fit(model)
      4 
      5 plt.plot(np.cumsum(pca.explained_variance_ratio_))

/anaconda3/lib/python3.6/site-packages/sklearn/decomposition/pca.py in fit(self, X, y)
    327             Returns the instance itself.
    328         """
--> 329         self._fit(X)
    330         return self
    331 

/anaconda3/lib/python3.6/site-packages/sklearn/decomposition/pca.py in _fit(self, X)
    368 
    369         X = check_array(X, dtype=[np.float64, np.float32], ensure_2d=True,
--> 370                         copy=self.copy)
    371 
    372         # Handle n_components==None

/anaconda3/lib/python3.6/site-packages/sklearn/utils/validation.py in check_array(array, accept_sparse, dtype, order, copy, force_all_finite, ensure_2d, allow_nd, ensure_min_samples, ensure_min_features, warn_on_dtype, estimator)
    431                                       force_all_finite)
    432     else:
--> 433         array = np.array(array, dtype=dtype, order=order, copy=copy)
    434 
    435         if ensure_2d:

TypeError: float() argument must be a string or a number, not 'Model'
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+2

中間層の特徴抽出は Keras でもできます。

 ステップ1 中間層の特徴量を取り出す。

このスライド にかかれている中間層を抽出する方法を記載します。

ImageNet 学習済みの InceptionV3 モデルを構築して、取り出す中間層を確認します。

from keras.applications.inception_v3 import InceptionV3, preprocess_input
from keras.layers import GlobalMaxPooling2D, Input
from keras.models import Model

base_model = InceptionV3(include_top=False, weights='imagenet',
                         input_tensor=Input((299, 299, 3)))

# モデル構造を可視化する。
from keras.utils import plot_model
plot_model(base_model, to_file='model.png',
           show_shapes=True, show_layer_names=True)

mixed7  (None, 17, 17, 768) という中間層がスライドに記載がある場所と思われるます。
ここの出力に Global Average Pooling を追加した新しいモデルを作成します。

# 以下の層を取り出す。
# mixed7  (None, 17, 17, 768) 
feature = base_model.get_layer('mixed7')
print(type(feature))  # <class 'keras.layers.merge.Concatenate'>
print(feature.name, feature.output_shape)  # mixed7 (None, 17, 17, 768)

# Global Average Polling 層を追加する。
output = GlobalMaxPooling2D()(feature.output)

# モデル作成
model = Model(inputs=base_model.input, outputs=output)
print(model.output_shape)  # (None, 768)

 ステップ2 データセットの特徴量を取り出す。

質問者さんが学習したいデータセットの画像を全部ネットワークに流し、特徴量に変換します。画像の枚数が N 枚だとしたら、これで (N, 768) のデータが得られます。

以下の例は1枚の特徴マップを取り出す例です。

import numpy as np
from PIL import Image

input_h, input_w = model.input_shape[1:3]
img = Image.open('dog.jpg')  # RGB 形式で読み込むこと
img = img.resize((input_h, input_w))  # モデルの入力サイズに合わせてリサイズする。

x = np.array(img)  # PIL -> numpy
x = preprocess_input(x)  # [0, 255] -> [-1, 1] Inception 用の前処理
print(x.shape)  # (299, 299, 3)

# 今回は1枚だけ試しに流した。実際は複数枚でミニバッチを作る。
batch = np.expand_dims(x, axis=0)  # (229, 229, 3) -> (1, 229, 229, 3)
features = model.predict(batch)
print(features.shape)  # (1, 768)

 ステップ3 主成分分析を行う。

(N, 768) のデータに対して、主成分分析を行います。
n_components は寄与度を見ながら、パラメータチューニングしてください。

# 主成分分析を行う。
from sklearn.decomposition import PCA
pca = PCA(n_components=100)
pca.fit(features)

# 主成分分析の結果に基づき、次元削減する。
data = fit_transform(features)

 ステップ4 学習する。

以上の過程で (N, n_components) のデータ及び (N,) のラベルができたと思うので、ニューラルネットワークでも SVM でも適当なモデル使って学習してください。

 ステップ5 推論する。

学習するときと同じ流れで以下のことをすればよいです。

  1. 画像から特徴量抽出
  2. PCA で次元削減
  3. 学習したモデルに流す。

 追加の質問について

1. 学習済みのモデルなければいけない

今回のメルカリの記事はディープラーニングで End-to-End で分類モデルを学習するという話でなく、学習済みのモデルを使って特徴量を抽出して、次元圧縮して、分類に利用するって話ですよね。
だから、学習済みモデルを使っています。

学習済みモデルを使うメリットについては 過去の質問 を参考にしてください。

2. tfrecordの場合は次元削減できないので、numpyの画像を使うしかない
の2つは絶対条件なのでしょうか?

tfrecord にこだわる理由はなにかあるのでしょうか?
tfrecord は Tensorflow でデータセットを扱う際に protocol buffer 形式で画像やラベルなど必要なデータをまとめたファイルフォーマットです。なので、元の画像があれば、わざわざ tf-recoard 形式にしなくてもそれを numpy として読み込んめばいいかと思います。
もちろん、protocol buffer は複数のデータを構造体のように固めただけなのでそこからデータ取り出すこともできます。

ちなみに sklearn の PCA で次元削減することと Deep Learning ライブラリで画像の特徴を抽出することは直接は関係ないので、そこは切り分けて考えてください。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/09/22 14:26

    ありがとうございます!
    質問なのですが、
    1. 学習済みのモデルなければいけない
    2. tfrecordの場合は次元削減できないので、numpyの画像を使うしかない
    の2つは絶対条件なのでしょうか?
    この2点は学習済みでなくても良い or tfrecordの次元削減は可能というケースはあるのでしょうか?

    キャンセル

  • 2018/09/22 18:00

    追記しました。
    絶対条件ではなく、質問で Keras を使われているようだったので、Keras のやり方を紹介しただけです。
    別のライブラリを使っても同じことはできます。

    キャンセル

  • 2018/09/22 18:48

    丁寧な回答ありがとうございました、とても参考になりました!

    キャンセル

同じタグがついた質問を見る

  • Python

    11707questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • 機械学習

    958questions

    機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

  • TensorFlow

    920questions

  • Keras

    472questions