ChunPom’s diary

数学、物理、機械学習に関する話題。あと院試、資格、大学入試まで。

ニューラルネットの中間層から出力層までのネットワークを取り出す

kerasでニューラルネットの入力層から中間層までのネットワークを取り出すのはよくあるけど、中間層から最終層(出力層)までのネットワークを取り出してる例はあまり少ないので紹介する。例として、MNISTの数字画像のデータに対するオートエンコーダーのネットワークを考える。

まずは必要なライブラリのインポートとデータの取得&整形。訓練データとテストデータを定義する。

from keras.layers import Input, Dense
from keras.models import Model
from keras.datasets import mnist
import numpy as np

(x_train, y_train), (x_test, y_test) = mnist.load_data()
image_size = x_train.shape[1] # = 784
original_dim = image_size * image_size
x_train = np.reshape(x_train, [-1, original_dim])
x_test = np.reshape(x_test, [-1, original_dim])
x_train = x_train.astype('float32') / 255
x_test = x_test.astype('float32') / 255


次にモデルを構築する。一気に入力層から最終層までのネットワークを実装せずに、入力層から中間層までのネットワーク(=前半のネットワーク)と、中間層から最終層までのネットワーク(=後半のネットワーク)を分けてモデル化するのがミソ。もたらん分け方を変えれば、任意の部分ネットワークを引っ張ってこれる。

# 前半のネットワーク構築
encoding_dim = 32#中間層のノード数。これが小さいほど特徴量が圧縮される。
input_img = Input(shape=(784,))
x1 = Dense(256, activation='relu')(input_img)  
x2 = Dense(64, activation='relu')(x1)  
encoded = Dense(encoding_dim, activation='relu')(x2) 
encoder = Model(input_img, encoded)
encoder.summary()

# 後半のネットワーク構築
input_hidden=Input(shape=(encoding_dim),)
x3 = Dense(64, activation='relu')(input_hidden)
x4 = Dense(256, activation='relu')(x3)  
decoded = Dense(784, activation='sigmoid')(x4) 
decoder=Model(input_hidden,decoded)
decoder.summary()

# 全体のネットワーク構築
z_output = encoder(input_img)#前半のネットワークの出力=中間層の出力のこと
outputs = decoder(z_output)#前半のネットワークの出力を新たな入力として、後半のネットワークの出力を求める

autoencoder = Model(input_img, outputs)#全体のネットワーク。次で最適化方法や損失関数を定義する。
autoencoder.compile(optimizer='Adam', loss='binary_crossentropy')#optimizerには色々あるが、デフォルト値ではadamがベストだった
autoencoder.summary()  


次に全体のネットワークを学習する。これにより前半のネットワークや後半のネットワークもフィッティングされる。普通の教師ありの場合には、x_train→y_trainやx_test→y_testなどのように教師データに適宜変更してください(今回はオートエンコーダーなので、入力データと教師データが同じになってます)。

autoencoder.fit(x_train, x_train,
                epochs=50,    
                batch_size=256,
                shuffle=True,
                validation_data=(x_test, x_test))


学習が完了したので、あとは「decoder.predict(中間層に入力したいデータ)」などのコマンドにより、後半のネットワークの予測値を引っ張ってこれる。
確認のため、テストデータを前半のネットワーク(encoder)に入力して得られた中間層の出力値を、後半のネットワーク(decoder)に入力してみよう。当然、これは全体のネットワーク(autoencoder)にテストデータを放り込んだ値に一致するはずである。printでそれぞれの値を出力して一致するか確認してみよう。

encoded_x_test=encoder.predict(x_test)
print(decoder.predict(encoded_x_test))

print(autoencoder.predict(x_test))

xlearnでFFMを動かす(備忘録)

FM(Factorization Machines)はRendleが2010年に提案したレコメンダ向けアルゴリズムである(https://www.csie.ntu.edu.tw/~b97053/paper/Rendle2010FM.pdf)。

これの表現力をさらに向上させたFFM(Field-aware Factorization Machines)が2017年にYuchin Juanらにより提案された。

https://www.csie.ntu.edu.tw/~cjlin/papers/ffm.pdf

 その名の通り,カテゴリごとに異なる潜在ベクトルを用意して使い分けるFMアルゴリズムである。同著者のlibFFMなどでCのソースコードが公開されているが,Pythonで動かしたかったため,xlearn(https://xlearn-doc.readthedocs.io/en/latest/index.html)を導入することにした。xlearnではFFMだけでなく通常のFMなども使用でき,FM関係の計算環境構築に便利。以下,導入手順をまとめておく(Windows/anaconda/pythonを想定)。

 

①WSL構築,VScode,anaconda導入

 https://penyoo.hatenablog.com/entry/2019/11/30/002503の手順でOK。

②xlearn導入

2-1 cmakeインストール

 Ubuntuのterminalを開き,sudo apt install cmake

2-2 xlearnのインストール

git clone https://github.com/aksnzhy/xlearn.git

cd xlearn
mkdir build
cd build
cmake ../
make

2-3 インストール状況が100%になったら,初期動作確認。

 ./run_example.shを実行。xlearnのAAが表示されればOK。

③FFMデモコード動作確認

3-1 python開く

cd python-package

python

3-2 デモ実行

import xlearn as xl

ffm_model = xl.create_ffm() 

ffm_model.setTrain("/home/user/xlearn/demo/classification/criteo_ctr/small_train.txt") ffm_model.setValidate("/home/user/xlearn/demo/classification/criteo_ctr/small_test.txt")

param = {'task':'binary', 'lr':0.2, 'lambda':0.002, 'metric':'acc'}

ffm_model.fit(param, './model.out')

*「user」はひとそれぞれ。上記のアドレスは訓練データとテストデータのデフォルトの保存場所にしましたが,人によっては異なるかも。その場合は,windows側から保存場所を確認したいなら,適当なフォルダを開いて「\\wsl$\Ubuntu\」のおまじないを入力し,xlearnのフォルダ場所を地道に探してみてください。

ルジャンドル変換を高校数学で理解する

 ルジャンドル変換(Legendre変換)は,熱力学における特性関数の解析や,最適化問題における双対問題など,様々な分野で現れる重要な理論である。本稿では高校数学のみを用いてルジャンドル変換の導出を図る。

 ルジャンドル変換は平たく言えば,凸関数{\displaystyle y=f(x)}における接線の{\displaystyle y}切片を求める理論である。ここで凸関数は{\displaystyle y=x^2}のように下に凸な関数の総称である。

 具体的には接線の傾きを{\displaystyle t}としたときの切片{\displaystyle C}を,{\displaystyle t}の関数{\displaystyle C(t)}として求めるものである。高校数学では,「接線はまず接点の{\displaystyle x}座標を{\displaystyle x_0}おけ!」というのがスローガンであろう。そういう意味では,傾きを変数で置くところから始まるルジャンドル変換は多少とっつきにくいかもしれない。なので,「接線はまず接点の{\displaystyle x}座標を{\displaystyle x_0}おけ!」という高校数学のセオリーにのっとってルジャンドル変換を導出してみよう。

このとき,接線の方程式は{\displaystyle y=f'(x_0)(x-x_0)+f(x_0)}と書けるから,{\displaystyle y=tx+C(t)}と比較することで,

{\displaystyle \ \ (1)\ t=f'(x_0)}

{\displaystyle \ \ (2)\ C(t)=f(x_0)-x_0 f'(x_0)}

を得る。これらの式から{\displaystyle x_0}を消去すれば{\displaystyle C(t)}を求めることができそうだが,式(1)は{\displaystyle f(x)}が与えられていないと陽に解くことができない...そこで,{\displaystyle x_0}を別の方法で求めてみよう。{\displaystyle f(x)}は凸関数であるから,任意の接線はこれより下に来る。すなわち{\displaystyle f(x)-(tx+C(t))\geq 0}である。特に,接するとき等号が成り立つので,

{\displaystyle \ \ (3)\ x_0=argmin_x\{f(x)-tx-C(t)\}=argmin_x\{f(x)-tx\}}

となる。ここで{\displaystyle argmin_x}は最小値を与える{\displaystyle x}座標を示す。{\displaystyle C(t)}{\displaystyle x}に依らないため,(3)の第二式が得られる。式(1),(2)より{\displaystyle C(t)=f(x_0)-t x_0 =(f(x)-tx)_{x=x_0}}となるが,式(3)の結果から{\displaystyle f(x)-tx}{\displaystyle x=x_0}で最小となるため,

{\displaystyle \ \ (4)\ C(t)=\min_x\{f(x)-tx\}}

を得る。こうして,接点の座標{\displaystyle x_0}を用いずに傾き{\displaystyle t}のみを用いて,切片の表式を表すことができた。式(4)がルジャンドル変換である。

ルベーグ積分の公式集8:有界変分関数の微分可能性

ルベーグ積分には様々な定理や公式が出てきて理解が追い付かなくなることがよくある。本ブログでは,理解の一助として,基本的な公式をまとめた。内容は随時追加していく予定。

 

有界変分関数の微分可能性

・単調関数の連続性と有界

単調関数{\displaystyle f:[a,b]\to \mathbb{R}}有界であり,不連続点はの集合の測度は0である(高々加算個で積分に寄与しない)。

また{\displaystyle f}有界変分である。すなわち,以下のように全変分が有限となる。{\displaystyle \Delta}は任意の分割を表す。

{\displaystyle \ \ \ \ V_b^a [f]=\sup_{\Delta} \sum_{i=1}^{n}|f(x_i)-f(x_{i-1})|\lt \infty}

 

有界変分関数は単調非減少関数の差

有界変分関数{\displaystyle f:[a,b]\to \mathbb{R}}は,2つの単調非減少関数の差として表される。一例が{\displaystyle f(x)=V_a^x[f]-(V_a^x[f]-f(x))}である。

 

・ヴィタリの被覆定理

{\displaystyle E\subset \mathbb{R}}かつ,が{\displaystyle \mathfrak{I}}区間の集合とする。任意の{\displaystyle \forall x\in E,\  \forall \epsilon \gt 0}に対して

(1) {\displaystyle \ \ \ x\in I}かつ{\displaystyle \lambda(I)\lt \epsilon}

を満たす区間{\displaystyle I\in \mathfrak{I}}が存在するとき,{\displaystyle \mathfrak{I}}{\displaystyle E}をヴィタリの意味で被覆するという。ここで{\displaystyle \lambda}ルベーグ測度を表す。

また,{\displaystyle \lambda}から構成される外測度{\displaystyle \lambda^*}に対して{\displaystyle \lambda^*}-測度有限な集合{\displaystyle E\subset \mathbb{R}}を,区間の集合{\displaystyle \mathfrak{I}}が被覆するとする。このとき,

(2) {\displaystyle \ \ \ \mu^* \left (E \setminus \cup_{n=1}^N I_i \right) \lt \epsilon}

なる有限{\displaystyle N}個の区間{\displaystyle I_n \in \mathfrak{I}}が存在する。

 

有界変分関数の微分可能性

ヴィタリの被覆定理の定理を用いると,単調関数{\displaystyle f:[a,b]\to \mathbb{R}}{\displaystyle (a,b)}のほとんどすべての点で微分可能となる。

また,有界変分関数が2つの単調非減少関数の差で書けることを踏まえると,有界変分関数もほとんどすべての点で微分可能となる。

ルベーグ積分の公式集7:ラドン-ニコディムの定理

ルベーグ積分には様々な定理や公式が出てきて理解が追い付かなくなることがよくある。本ブログでは,理解の一助として,基本的な公式をまとめた。内容は随時追加していく予定。

 

ラドン-ニコディムの定理

・変動の定義

可測空間{\displaystyle (X,\mathscr{A})}が与えられ,任意の{\displaystyle E \in \mathscr{A}}に対して有限の実数値をとる集合関数{\displaystyle \Phi(E)}が完全加法性を満たすとき,{\displaystyle X}上の加法的集合関数と呼ぶ。ただし,測度とは違い負値も取りうる。なお測度と同じように,公式集1の連続性の各性質を満たす。このとき,

{\displaystyle \ \ \ \  \overline{V}(\Phi, E)=\sup_{A\subset E}\Phi(A)}

{\displaystyle \ \ \ \  \underline{V}(\Phi, E)=\inf_{A\subset E}\Phi(A)}

{\displaystyle \ \ \ \  V(\Phi, E)=|\overline{V}(\Phi, E)|+|\underline{V}(\Phi, E)|}

をそれぞれ上変動,下変動,全変動と定義する。なお,{\displaystyle  -\infty \lt \underline{V}(\Phi, E) \leq 0\leq \overline{V}(\Phi, E)\lt \infty }が成り立つ。

 

ジョルダン分解とハーン分解

上記の任意の{\displaystyle E}に対して以下のジョルダン分解が可能である。

(1) {\displaystyle \Phi(E)=\overline{V}(\Phi, E)+\underline{V}(\Phi, E)}

また,以下のハーンの分解定理が成り立つ。

(2) {\displaystyle \overline{V}(\Phi, X-A)=0,\underline{V}(\Phi, A)=0}となる{\displaystyle A\subset X}が存在する。

 

・絶対連続の定義

測度空間{\displaystyle (X,\mathscr{A},\mu)}に対する加法的集合関数{\displaystyle \Phi(E)}を考える。これが測度{\displaystyle \mu}に対して絶対連続であるとは,{\displaystyle \mu(E)=0}なるすべての{\displaystyle E}に対して{\displaystyle \Phi(E)=0}となることである。

絶対連続な関数の例として,積分可能な{\displaystyle f(x)}不定積分

{\displaystyle \ \ \ \ F(E)=\int_E f(x) d\mu(x)}がある

また特異であるとは,{\displaystyle \mu(E_0)=0}なるある集合{\displaystyle E_0}が存在し,{\displaystyle \forall E \subset X-E_0}に対して{\displaystyle \Phi(E)=0}となることをいう。

 

ラドン-ニコディムの定理

{\displaystyle \sigma}-有限な測度{\displaystyle \mu}を仮定する。すなわち,

{\displaystyle \ \ \ \ X=\cup_{n=1}^{\infty} E_n}なる集合列{\displaystyle E_n}が存在するとする。

このとき,絶対連続な{\displaystyle F(E)}と特異な{\displaystyle \psi(E)}を用いて以下のルベーグ分解が可能である(一意的)。

(1) {\displaystyle \ \ \ \ \Phi(E)=F(E)+\psi(E)}

ここで,{\displaystyle F(E)}に対して{\displaystyle \mu}-a.e. {\displaystyle x}で定義される積分可能な関数{\displaystyle f}が存在して

(2) {\displaystyle \ \ \ \ F(E)=\int_E f(x) d\mu(x)}

と表される。{\displaystyle f}{\displaystyle F}{\displaystyle \mu}に対する密度関数と呼ぶ。

ルベーグ積分の公式集6:積分(フビニの定理)

ルベーグ積分には様々な定理や公式が出てきて理解が追い付かなくなることがよくある。本ブログでは,理解の一助として,基本的な公式をまとめた。内容は随時追加していく予定。

 

★フビニの定理

・直積測度空間

2つの測度空間{\displaystyle (X,\mathscr{E}_X, \mu),\ (Y,\mathscr{E}_Y, \nu)}に対し,任意の{\displaystyle A\in \mathscr{E}_X,\ B\in \mathscr{E}_Y}の直積{\displaystyle A\times B}を長方形と呼ぶ。互いに素な長方形の合併

{\displaystyle \ \ \ \  F_n=\cup_{i=1}^{n} A_i \times B_i}

で表される集合全体の族を{\displaystyle \mathscr{F}}とする。{\displaystyle F_n}に対する集合関数を

{\displaystyle \ \ \ \  \gamma(F_n)=\sum_{i=1}^{n} \mu(A_i) \cdot \nu(B_i)}

で定義すると,{\displaystyle \gamma}{\displaystyle \mathscr{F}}上の測度となる。公式集2の測度の拡大の手続きにより,{\displaystyle \gamma}{\displaystyle \mathscr{F}}の生成する{\displaystyle \sigma}-加法族の測度に拡大できる。こうして得られる測度空間{\displaystyle (X\times Y,\mathscr{E}_X \otimes \mathscr{E}_Y, \mu \otimes \nu)}を直積測度空間と呼ぶ。

 

・切り口

2つの可測空間{\displaystyle (X,\mathscr{E}_X),\ (Y,\mathscr{E}_Y)},直積空間上の可測関数{\displaystyle f}があるとする。このとき,任意の{\displaystyle x\in X}に対し関数{\displaystyle f(x,y)}{\displaystyle y}の関数として可測関数となる。

また,{\displaystyle (X,\mathscr{E}_X),\ (Y,\mathscr{E}_Y)}{\displaystyle \sigma}-有限な測度空間で,直積空間上の非負可測関数を{\displaystyle f}とするとき,関数{\displaystyle \int _X f(x,y) d\mu}は可測関数となる。

 

・フビニの定理

{\displaystyle (X,\mathscr{E}_X),\ (Y,\mathscr{E}_Y)}{\displaystyle \sigma}-有限な測度空間で,直積空間上の積分可能な関数を{\displaystyle f}とすると,関数{\displaystyle \int _X f(x,y) d\mu}積分可能であり,かつ以下の等式が成り立つ。

\begin{eqnarray*} \int _{X\times Y} f(x,y) d(\mu\otimes \nu)&=&\int_X \left( \int_Y f(x,y)d\nu \right ) d\mu \\&=&\int_Y \left( \int_X f(x,y)d\mu \right ) d\nu \end{eqnarray*}

ルベーグ積分の公式集5:積分(項別積分)

ルベーグ積分には様々な定理や公式が出てきて理解が追い付かなくなることがよくある。本ブログでは,理解の一助として,基本的な公式をまとめた。内容は随時追加していく予定。

 

★項別積分

・ファトゥの補題

可測集合{\displaystyle E}上の非負可測関数列{\displaystyle  \{f_n\}}に対して以下が成り立つ。

{\displaystyle \ \ \ \  \int _E \varliminf_{n \to \infty} f_n d\mu \leq \varliminf_{n \to \infty}  \int_E f_n d \mu}

 

ルベーグの収束定理

関数{\displaystyle f_n(x)}{\displaystyle E}上可測関数で,{\displaystyle E}積分可能な{\displaystyle \phi (x)}を用いて各点で{\displaystyle |f_n(x)|\leq \phi (x)}と抑えられるならば,以下が成り立つ。

(1) {\displaystyle \ \ \ \int _E \varliminf_{n \to \infty} f_n d\mu \leq \varliminf_{n \to \infty}  \int_E f_n d\mu}

(2) {\displaystyle \ \ \ \int _E \varlimsup_{n \to \infty} f_n d\mu \geq \varlimsup_{n \to \infty}  \int_E f_n d\mu}

さらに{\displaystyle f=\lim_{n\to \infty}f_n}が存在すれば

(3) {\displaystyle \ \ \ \int _E \lim_{n \to \infty} f_n d\mu = \lim_{n \to \infty}  \int_E f_n d\mu}

 

有界収束定理

有限測度の集合{\displaystyle E}上の可測関数列{\displaystyle  \{f_n\}}がある定数{\displaystyle C}により{\displaystyle |f_n(x)|\leq C}で抑えられ(一様収束),かつ{\displaystyle f=\lim_{n\to \infty}f_n}が存在すれば,

{\displaystyle \ \ \ \ \int _E \lim_{n \to \infty} f_n d\mu = \lim_{n \to \infty}  \int_E f_n d\mu}

 

微分積分の順序交換

測度関数{\displaystyle (X, \mathscr{A},\mu)}があり,{\displaystyle X}上で積分可能な{\displaystyle f(x,t)}が,{\displaystyle t}の関数として微分可能とする。この導関数{\displaystyle X}積分可能な{\displaystyle \phi(x)}により,{\displaystyle t}の定義域で{\displaystyle |f_t(x,t)|\leq \phi(x)}で抑えられるとする。このとき,{\displaystyle f(x,t)}{\displaystyle x}に関する積分{\displaystyle t}の関数として微分可能であり,

{\displaystyle \ \ \ \ \frac{d}{dt}\int _X f(x,t) d\mu(x) =  \int_X f_t(x,t)d\mu(x)}

が成り立つ。