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

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

新規登録して質問してみよう
ただいま回答率
85.39%
Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

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

Python

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

Q&A

0回答

638閲覧

[深層距離学習] 取得した特徴ベクトルで類似度を算出する方法

harug

総合スコア28

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

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

Python

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

0グッド

0クリップ

投稿2023/01/17 14:08

編集2023/01/17 14:10

前提

現在,pythonを用いてResNet50v2+ArcFaceのモデルを実装しています.
Qiitaのサイトと,GitHubのコードを参考にしモデルを構築しました.
ハイパーパラメータなどはOputunaで最適化を行い,最終的にベストな重みのみを保存するようなプログラムを組んでいます.

実現したいこと

参考サイトではいづれも推論用モデル(Qiitaのサイトではpredict_model)を,ベストな重みをロードしたモデルからArcFaceLayer以降を全て削除し,ベースネットの最後のconvの出力を最終出力とするようなモデルとしていました.(今までは最終出力をSoftmaxなどとするモデルを扱ってきたので少し困惑しました.)

そこで,predict_mdelを用いて以下を実現したいと思っています.

① 各データ間の距離の値を取得したい

これは例えば,predict_mdelに2つのデータをそれぞれ入力し得られた特徴ベクトルを用いて,その都度cos類似度などで類似度を計算してあげる必要があるのでしょうか.

② 入力画像に対する出力層のsoftmaxの値を取得したい

どのクラスにも属さない未知画像に対し,最終的なsoftmaxの値(クラス数次元のベクトル)をpredict_modelから取得したいのですがその方法が分かりません.

該当のソースコード

以下に現在使用しているソースコードを示します.

python

1# 総クラス数,エポック数,入力画像のサイズを指定 2num_classes = 29 3epochs = 100 4height = 110 # 像のピクセル数(縦) 5width = 110 # 像のピクセル数(横)

python

1class Arcfacelayer(Layer): 2 # s:softmaxの温度パラメータ, m:margin 3 def __init__(self, output_dim, s, m, easy_margin=False): 4 self.output_dim = output_dim 5 self.s = s 6 self.m = m 7 self.easy_margin = easy_margin 8 super(Arcfacelayer, self).__init__() 9 10 def get_config(self): 11 config = { 12 "output_dim" : self.output_dim, 13 "s" : self.s, 14 "m" : self.m, 15 "easy_margin" : self.easy_margin 16 } 17 base_config = super().get_config() 18 return dict(list(base_config.items()) + list(config.items())) 19 20 21 # 重みの作成 22 def build(self, input_shape): 23 print(f'buildのinput_shape:{input_shape}') 24 # Create a trainable weight variable for this layer. 25 self.kernel = self.add_weight(name='kernel', 26 shape=(input_shape[0][1], self.output_dim), 27 initializer='uniform', 28 trainable=True) 29 super(Arcfacelayer, self).build(input_shape) 30 31 32 # mainの処理 33 def call(self, x): 34 35 y = x[1] 36 x_normalize = tf.math.l2_normalize(x[0]) # x = x'/ ||x'||2 37 k_normalize = tf.math.l2_normalize(self.kernel) # Wj = Wj' / ||Wj'||2 38 39 cos_m = K.cos(self.m) 40 sin_m = K.sin(self.m) 41 th = K.cos(np.pi - self.m) 42 mm = K.sin(np.pi - self.m) * self.m 43 44 cosine = K.dot(x_normalize, k_normalize) # W.Txの内積 45 sine = K.sqrt(1.0 - K.square(cosine)) 46 47 phi = cosine * cos_m - sine * sin_m #cos(θ+m)の加法定理 48 49 if self.easy_margin: 50 phi = tf.where(cosine > 0, phi, cosine) 51 52 else: 53 phi = tf.where(cosine > th, phi, cosine - mm) 54 55 # 正解クラス:cos(θ+m) 他のクラス:cosθ 56 output = (y * phi) + ((1.0 - y) * cosine) 57 output *= self.s 58 59 return output 60 61 def compute_output_shape(self, input_shape): 62 return (input_shape[0][0], self.output_dim) #入力[x,y]のためx[0]はinput_shape[0][0]

python

1# ResNet50v2 + ArcFace定義 2# 学習に使用 3def create_arcface_with_resnet50v2(input_shape, s, m): 4 # ResNet50V2の入力層の前に独自の入力層を追加 5 input_tensor = input_shape 6 print(input_tensor) 7 8 input_model = Sequential() 9 input_model.add(InputLayer(input_shape=input_tensor)) 10 input_model.add(Conv2D(3, (7, 7), padding='same')) 11 input_model.add(BatchNormalization()) 12 input_model.add(Activation('relu')) 13 14 resnet50v2 = ResNet50V2(include_top=False, weights=None, input_tensor=input_model.output) 15 16# DLしてある重みの読み込み 17 resnet50v2.load_weights('save_model(weights_imagenet)/weights_imagenet.hdf5', by_name=True) 18 19 20 flat = Flatten()(resnet50v2.layers[-1].output) 21 dense = Dense(512, activation="relu", kernel_initializer="he_normal", name="hidden")(flat) 22 23 x = BatchNormalization()(dense) 24 25 yinput = Input(shape=(num_classes,)) #ArcFaceで使用 26 27 s_cos = Arcfacelayer(num_classes, s, m)([x,yinput]) #outputをクラス数と同じ数に 28 prediction = Dense(num_classes, activation="softmax")(s_cos) 29 30 model = Model(inputs=[resnet50v2.input,yinput], outputs=prediction) 31 32 return model 33

現在は次のコードを用いてoptunaを使用し,val_lossを最適化した学習を行っています.

python

1# モデル定義 2def trainer(**param): 3 4 5 lr = param['lr'] 6 batch_size = param['batch_size'] 7 s = param['s'] 8 m = param['m'] 9 10 11 model = create_arcface_with_resnet50v2(input_shape, s, m) 12 13 14 # 自動的に学習をやめる 15 early_stopping = EarlyStopping(monitor='val_loss', 16 min_delta=0.0, 17 patience=3, 18 mode='min' 19 ) 20 # 最良の重みとモデルを保存 21 fpath = 'Weight/{}/{}_{}_{}_{}_({{epoch:02d}}-{{loss:.2f}}-{{accuracy:.2f}}-{{val_loss:.5f}}-{{val_accuracy:.2f}}).hdf5'.format(f_elem, batch_size, lr, s, m) 22 model_checkpoint = ModelCheckpoint(filepath=fpath, monitor='val_loss', save_best_only=True, mode='min') 23 # 学習中に学習率を調整 24 lr_scheduler = LearningRateScheduler(lr_schedul, verbose=1) 25 26 27 adam = Adam(learning_rate=lr) 28 model.compile(loss='categorical_crossentropy', optimizer=adam, metrics=['accuracy']) 29 30 31 32 try: 33 34 H = model.fit([x_train, y_train], y_train, # ここの[x_train, y_train]をx_trainにしたい 35 epochs=epochs, 36 verbose=1, 37 steps_per_epoch = math.ceil(len(x_train)/batch_size), 38 validation_data=([x_test, y_test], y_test), 39 callbacks=[early_stopping, model_checkpoint, lr_scheduler]) 40 41 part = f_elem.split('/')[1] 42 M_path = 'Model/{}/{}_{}_{}_{}_model_{}.h5'.format(f_elem, batch_size, lr, s, m, part) 43 model.save(M_path) 44 45 #テストデータで精度を確認 46 score = model.evaluate([x_test, y_test], y_test) 47 48 return score[0] # vall_lossが最小であるモデルを探すため 49 50 except Exception as e: 51 print(e)

推論用のモデルです.

python

1model = create_arcface_with_resnet50v2(input_shape, s=best_s, m=best_m) # best_sとbest_mはOptunaで最適化された値 2model.load_weights(W_path) # W_pathはOptunaの学習で得たベストの重みのパス 3 4predict_model = Model(model.get_layer(index=0).input, model.get_layer(index=-5).output)

なお使用しているデータのshapeは以下のようになっています.
x_train.shape → (1566, 110, 110, 1)
y_train.shape → (1566, 29) # one-hot

x_test.shape → (88, 110, 110, 1)
y_test.shape → (88, 29) # one-hot

input_shape → (110, 110, 1)

どなたか上記➀, ②を実現できる方法やアドバイスなどあれば教えていただきたいです.

補足情報(FW/ツールのバージョンなど)

ubuntu 20.04
Python 3.8.10

tensorflow-gpu 2.5.3
keras 2.8.0
numpy 1.19.5

jupyter lab 2.3.2

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.39%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問