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

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

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

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

深層学習

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

機械学習

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

Python

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

Q&A

解決済

1回答

1016閲覧

ResNet + ArcFaceのモデルを作成する方法

harug

総合スコア28

Keras

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

深層学習

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

機械学習

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

Python

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

0グッド

1クリップ

投稿2022/12/18 13:26

前提

現在,こちらを参考にしてResNet50v2 + ArcFaceの実装を行っています.

ArcFaceの定義自体は上記のサイトをそのまま使用する形で実装しています.
そこで以下のような問題が発生しました.

現在の実装内容とエラー内容

1. 現在の実装内容

まずは,現在使用しているソースコードを記します.

使用しているクラス数と入力画像のshapeです.

python

1from tensorflow.keras.applications.resnet_v2 import ResNet50V2 2from keras.layers import Layer 3(他のimportは省略) 4 5num_classes = 29 6input_shape = (80, 80, 1) # 入力画像shape

次に示すのが,ArcFaceの機能を定義したものになります. こちらは先述の通り上記のサイトを参考にしています.

python

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

次に示すのが,ResNet50v2をベースネットワークとしたArcFaceモデルの定義です. こちらも上記のサイトを参考にしていますが,引数やアーキテクチャを多少変更しています.

python

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

上記の実装内容から以下を実行すると実行結果とともに次のようなエラーが吐かれました.
Arcfacelayerクラス内のcallメソッドが呼び出される前にbuildメソッドが呼び出されています.

python

1arcface_model = create_arcface_with_resnet50v2(num_classes, input_shape) 2 3 4(↓実行結果とエラー内容) 5 6input_shape:[None, TensorShape([None, 29])] 729 8--------------------------------------------------------------------------- 9TypeError Traceback (most recent call last) 10Input In [11], in <cell line: 1>() 11----> 1 arcface_model = create_arcface_with_resnet50v2(num_classes, input_shape) 12 13Input In [5], in create_arcface_with_resnet50v2(num_classes, input_shape) 14 22 base_network.load_weights('save_model(weights_imagenet)/weights_imagenet.hdf5', by_name=True) 15 24 yinput = Input(shape=(num_classes,)) #ArcFaceで使用 16---> 26 s_cos = Arcfacelayer(num_classes, 30, 0.05)([base_network,yinput]) #outputをクラス数と同じ数に 17 27 prediction = Activation('softmax')(s_cos) 18 29 model = Model(inputs=[base_network.input,yinput], outputs=prediction) 19 20File /usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py:67, in filter_traceback.<locals>.error_handler(*args, **kwargs) 21 65 except Exception as e: # pylint: disable=broad-except 22 66 filtered_tb = _process_traceback_frames(e.__traceback__) 23---> 67 raise e.with_traceback(filtered_tb) from None 24 68 finally: 25 69 del filtered_tb 26 27Input In [4], in Arcfacelayer.build(self, input_shape) 28 13 print(self.output_dim) 29 14 # Create a trainable weight variable for this layer. 30 15 self.kernel = self.add_weight(name='kernel', 31---> 16 shape=(input_shape[0][1], self.output_dim), # ★ 32 17 initializer='uniform', 33 18 trainable=True) 34 19 super(Arcfacelayer, self).build(input_shape) 35 36TypeError: 'NoneType' object is not subscriptable

メッセージ内の★の部分の第一要素がNoneであることがエラーの原因であったため,input_shape[0][1] (=None)をinput_shape[1][1] (=29)に変えると上記のエラーは改善されたが,次は以下のエラーが吐かれるようになってしましました.

・エラー2

こちらのエラーはbuildメソッドの後にcallメソッドが呼び出されてはいて,引数xの0番目の要素についてのエラーであることは理解できるのですが,何が原因でエラーを起こしてしまったのかが分かりません.

input_shape:[None, TensorShape([None, 29])] self.output_dim:29 call関数を読み込みました. 入力x: [<keras.engine.functional.Functional object at 0x7f2125fba580>, <tf.Tensor 'Placeholder:0' shape=(None, 29) dtype=float32>] --------------------------------------------------------------------------- TypeError Traceback (most recent call last) Input In [11], in <cell line: 1>() ----> 1 arcface_model = create_arcface_with_resnet50v2(num_classes, input_shape) Input In [5], in create_arcface_with_resnet50v2(num_classes, input_shape) 22 base_network.load_weights('save_model(weights_imagenet)/weights_imagenet.hdf5', by_name=True) 24 yinput = Input(shape=(num_classes,)) #ArcFaceで使用 ---> 26 s_cos = Arcfacelayer(num_classes, 30, 0.05)([base_network,yinput]) #outputをクラス数と同じ数に 27 prediction = Activation('softmax')(s_cos) 29 model = Model(inputs=[base_network.input,yinput], outputs=prediction) File /usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py:67, in filter_traceback.<locals>.error_handler(*args, **kwargs) 65 except Exception as e: # pylint: disable=broad-except 66 filtered_tb = _process_traceback_frames(e.__traceback__) ---> 67 raise e.with_traceback(filtered_tb) from None 68 finally: 69 del filtered_tb File /usr/local/lib/python3.8/dist-packages/tensorflow/python/autograph/impl/api.py:692, in convert.<locals>.decorator.<locals>.wrapper(*args, **kwargs) 690 except Exception as e: # pylint:disable=broad-except 691 if hasattr(e, 'ag_error_metadata'): --> 692 raise e.ag_error_metadata.to_exception(e) 693 else: 694 raise TypeError: Exception encountered when calling layer "arcfacelayer" (type Arcfacelayer). in user code: File "/tmp/ipykernel_6559/4194376824.py", line 27, in call * x_normalize = tf.math.l2_normalize(x[0]) # x = x'/ ||x'||2 TypeError: Failed to convert elements of <keras.engine.functional.Functional object at 0x7f2125fba580> to Tensor. Consider casting elements to a supported type. See https://www.tensorflow.org/api_docs/python/tf/dtypes for supported TF dtypes. Call arguments received: • x=['<keras.engine.functional.Functional object at 0x7f2125fba580>', 'tf.Tensor(shape=(None, 29), dtype=float32)']

webサイトを参考にしているため,用いるデータの相違などによって生じたエラーか?とも考えています.
しかし,今まで使用してこなかった新たな概念が多いこともあり自力では上記の解決方法が分かりませんでした.

・エラー1の★部分のshapeにはどのような値を設定すればいいのか
・エラー2はどのようなエラーでありどのように修正するとよいか

以上お力をお貸しいただけますと幸いです.よろしくお願いします.

補足情報(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

回答1

0

自己解決

上記のモデル定義部分の中で
s_cos = Arcfacelayer(num_classes, 30, 0.05)([base_network,yinput])
の部分を以下のように変更すると実行できました.

python

1s_cos = Arcfacelayer(num_classes, 30, 0.05)([base_network,yinput])

投稿2023/01/12 13:11

harug

総合スコア28

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問