コードは蘇Jianlinからです
#- * -コーディング:UTF-8 - * - 。 から keras.layers インポートレイヤー のインポートkeras.backend AS K クラスCRF(レイヤー): 「」 " CRFの達成するために、純粋なKeras層 損失を本質的に計算CRFトレーニングパラメータを持つ層であり、層、層CRFのみのモデルを訓練するために使用され、 そしてあなたは、予測モデルを作成する必要がありますが、まだ転送行列を使用するように訓練された 「」「 DEF __init__(セルフ、ignore_last_label = Falseを、** kwargsから): 」「」ignore_last_label :最後のラベルを無視するかどうかの定義は、マスクエフェクトを再生 「」 " self.ignore_last_label = 1 IF ignore_last_label 他0 スーパー(CRF、セルフ)。__init__(** kwargsから) デフ(自己、input_shape)のビルド: self.num_labels = input_shape [-1] - self.ignore_last_label self.trans = self.add_weight(名= ' crf_trans ' 、 形状 = (self.num_labels、self.num_labels)、 の初期化子 = " glorot_uniform ' 、 訓練可能 = TRUE) DEFのlog_norm_step(セルフ、入力、アメリカ合衆国): "" " 再帰的計算正規化係数 点:1、再帰的計算; 2、logsumexp避けオーバーフロー有する。 ヒント:expand_dimsによってテンソルを整列させます。 " "" 状態 = K.expand_dims(状態[0]、2) #前の 入力= K.expand_dims(入力、2) #は、これはタグタイミングのスコアであり、排出スコア トランス= K.expand_dimsを(self.trans、0) #転送マトリクス 出力 = K.logsumexp(入力米国+ +トランス,. 1)#1 E加算指数、オーバーフロー防止ログ リターン出力を、[出力] DEFのpath_score(セルフ、入力、ラベル): 「」 " 相対経路計算対象確率(正規化されていない)は、 ハイライト:スコアによってラベル、共に遷移確率スコアを有する。 ヒント:抽出された目標スコアのパスの「予測」ドット「ターゲット」を使用します。 「」" #はCRFにラベルに関するプラス遷移確率スコア、これはポイントスコアである形状のラベルと同等のタグスコアは、(場合に、実際に本物のタグの位置合計スコアの予測を表示するラベル)[B、T、N]、及びNになっていますこの次元は、ワンホットです #ここPREDを乗じたスコアの存在に対応するラベル、残りは、第2の次元を追加する0の値を表し、全て0である場合、それは除去され、次いでラベルを追加すると、総スコア見つける示し = point_scoreをK.sum(K.sum(入力*ラベル、2),. 1、keepdims = TRUE) #タブスコアによって、[B ,. 1]形状 labels1 = K.expand_dims(ラベル[:、:-1] ,. 3)位[B ,. 1-T、N ,. 1]形状 labels2 = K.expand_dims(ラベル[:、1:]、2)#1 [B、T-1 ,. 1、N]シェイプ #ここでは、乗算オブジェクトに対応経時ラベル転送から現在の時刻と判断された転送時間、現在時刻、ラベルは、ワンホット形式であるため、最終的な素子における2つだけの寸法は、他のすべてが0であり、1でありますフラグは、遷移 ラベル= labels1 labels2 * #2は、転送対象スコア形状〔B、T-1、撮影を担当するラベル、オフセット N、N]を転送行列から トランス= K.expand_dims(K.expand_dims(self.transを、0 )、0) #K.sum(トランス*ラベル、[2 、3])、 その結果であるので、トランス*ラベルは[B、T-1、N 、N]、 しかしは、後で1の値を有する2つの次元で、スコアが転送表し trans_scoreをK.sum =(K.sum(トランス*ラベル、[2 ,. 3]),. 1、keepdims = TRUE) #は、全ての転送時間T-1合計スコアの確率、K.sum(トランス*ラベル、[取得 2 3])、各時間スコアは転送表す 戻り point_score + trans_score #スコアとの2つの部分を DEFコール(セルフ、入力): #CRF自体のは、それが唯一の損失であり、出力を変更しない リターン入力 DEFの損失(セルフ、y_true、 y_pred): #の目標は、1枚のホットy_pred形式にする必要が マスク= 1-y_true [-1:1:。、]。IF self.ignore_last_label 他なし y_true、y_pred =y_trueの[:、:、:self.num_labels]、y_pred [:、:、:self.num_labels] init_states = [y_pred [:0] #初期状態 log_norm、_、_ = K.rnn( self.log_norm_step、 y_pred [:、1:]、init_states、マスク=マスク)#は、対数(ベクトルZを算出する)BATCH_SIZE、output_dim]形状 log_norm = K.logsumexp(log_norm ,. 1、keepdims = TRUE) #は、Z(対数)の形状を算出します[BATCH_SIZE、1]の合計を算出 path_score = self.path_score(y_pred、y_true) #は、分子(対数)を算出 戻り log_norm - path_score #すなわち、ログ(分子/分母) DEFの精度(セルフ、y_true、y_pred):#1 研修をフレーム精度による機能表示処理フレーム、マスクの影響を除いた マスク= 1-y_true。[:、:、 - 1] IFself.ignore_last_label 他なし y_true、y_pred = y_true [:、:、:self.num_labels]、y_pred [:、:、:self.num_labels] 関数isequal = K.equal(K.argmax(y_true、2)、K.argmax (y_pred、2 )) 関数isequal = K.cast(isequalを、' のfloat32 ' ) であればマスク== なし: 返すK.mean(isequalを) 他: 返す K.sum(関数isequal *マスク)/ K.sum(マスク)