ホップフィールドネットワーク(hopfield network)

ホップフィールドネットワーク概要

ホップフィールドネットワーク(hopfield network)とは、 全結合の無効グラフのニューラルネットワークで、
情報を記憶し、その情報を想起することができるネットワークのことを言います。

以下、イメージ図

f:id:ttt242242:20170128203338p:plain

ホップフィールドネットの処理

ネットワークの初期化

データ数分のノードがネットワークを作成します。
記憶するデータが[1, -1, 1, -1]のような配列であれば、ノード数は4になります。
以下はネットワークのイメージです。

f:id:ttt242242:20190727144052p:plain

ネットワークに記憶

ネットワークに元の情報を覚えさせます。
つまり、リンクの重みとして記憶させます。

各リンクは以下の式で情報を覚えさせます。

$$ \begin{equation} w_{ij} = x_i x_j \end{equation} $$

  • \(x_i\)はノード\(i\)の値。つまり、覚えさせたいデータ
  • \(w_{ij}\)はノード\(i\)とノード\(j\)のリンクの重み

式の意味としては、リンクの両端のノードが同じ値であれば、結合を強くするというものである。
これをヘブ則と言います。

データが複数ある時には、単純に総和を取るだけです。

$$
\begin{eqnarray}
w_{ij} = \sum_{d \in D} x^{d}_i x^{d}_j
\end{eqnarray}
$$

Dはデータの集合です。

ちなみに上述した式は\(x_i \in {1,-1}\)の時です。
\(x_i \in {0,1}\)の場合については補足を参照してください。

ノイズありデータからの想起

記憶させたデータにノイズを加えたデータから、元のデータを想起させる処理についてです。

例えば、元データが[1, -1, 1]で、
ノイズありデータが[-1, -1, 1]だとしたら、
ノイズありデータをネットワークに入力すると、元データ[1, -1, 1]を出力するということです。

0. ノイズありデータをネットワークに入力
1. ランダムにノードを選択、更新

ノード\(x_i\)の値、つまり入力されたデータを値を変更していきます。

まず、以下の式を用いて、各ノード\(x_i\)に対応した\(y_i\)を計算します。

$$
\begin{eqnarray}
y_i = \sum_{j=1}^{N} w_{ij} x_j
\end{eqnarray}
$$

\(y_i\)は選択されたノードの値と、そのノードに結合しているリンクの積の総和になります。

そして、以下のルールに従って、ノード\(x_i\)をの値を更新します。

$$
x_{i}= \left\{ \begin{array}{rcl} 1 & y_i > 0 \\ x_i & y_i = 0 \\ -1 & y_i < 0 \\ \end{array} \right. $$

2. エネルギー関数の計算

次にネットワーク全体の状態を表すエネルギー関数\(E\)を計算します。

エネルギー関数\(E\)は以下のように計算します。

$$
\begin{eqnarray}
E= -\frac{1}{2}\sum_{ij}^{N} w_{ij} x_i x_j
\end{eqnarray}
$$
3. 1,2をエネルギー関数が最小化するまで繰り返す

補足(入力値が{0,1}の場合)

入力値が{0,1}の場合には、 ヘブ則による更新式が異なります。 具体的には以下の式を用います。

上記の式も同様にリンクの両端のノードの値が一致していれば、 そのリンクの重みを強くすることを表しています。

実装

データを1つだけ記憶するhopfield networkを実装しました。

このプログラムでは、
まず、[1., 1., -1., 1., -1., 1., -1., 1., 1., -1., -1., 1., 1.] というデータを元データとして、ネットワークに記憶させます。 このデータにノイズを加えたテストデータ(最初の2つの値を-1にした)を作成します。
そして、このテストデータをhopfiled networkに入力させ、
元データを想起させています。

上記のプログラムを実行すると、

[1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0]
test data
[-1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0]
result
[1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0]

うまく元データを想起させることができています。

コメント

  1. […] […]

タイトルとURLをコピーしました