ニューラルネットワークを作成するための「ユニバーサル」ライブラリの開発(ホーム)

背景


私は単なる人間であり、AIをユニバーサルアシスタントとは考えず、C上のAWS(C / C ++)に冷静にコーディングしました。

私はかつて、AWPのコーディングのトピックに専念するフォーラムで男性に会いました。かなり長い間、彼は私に多くを説明し、助けてくれました。+彼自身も非常に多くの興味深いことをしました。 しかし、ある日はAIについてでした。「コンピューターで面白いのは、デバッガー、タスクマネージャー+ ICQのボットです。これは、チューリングテストに複数回合格しました」というスタイルの彼の答えに興味がありました。 もちろん、私は完全に適切な人として、それを信じていませんでした。 彼はソースコードの提供を拒否し、完成したプログラムを私が彼のコンピューターをハックしてFSにアクセスする場合にのみ提供することを約束しました。 それから数年が経ち、彼のAIを犠牲にして話題が何度も取り上げられました。 私はまだプロトタイプを入手できませんでしたが、彼がまったくプロトタイプを持っているとは完全に確信していませんが、これは重要ではありません。 会話のたびに、自分のAIを口ずさむというアイデアが生まれました。



開始する


もちろん、最初に開発に必要なすべてのリストを作成する必要がありました。お気に入りのC / C ++をベースとして選択したとき、友人は「あなたの知性は通常言語で書かれていないので、宣言された言語を選択する必要があります」と私に言いました。 原則がまったく異なる新しい言語を再学習する必要があるため、私はすぐにこの考えが好きではありませんでしたが、それでもチャンスをとることに決めました。

そのため、C / C ++言語が選択されました。

次に、開発を開始するライブラリの小さな選択(当時考えていたように)まででしたが、ここで2番目の落とし穴がありました。 私はANNに関する多くの記事をレビューし、多くのライブラリを再編集しましたが、ライブラリの柔軟性が不十分であるか、理解が困難であるか、速度の点で満足できないため、適切なものを見つけられませんでした。 もちろん後で彼についてもう1つありました。

したがって、タスクはライブラリを作成するように設定されました。

行こう


水曜日に、私はRad Studioを選択しました。

確認するためにクイックフォームスプリッタが必要なので、インターフェイスに多くの時間を費やしません

Delphiへの移植のシンプルさが必要でした。 多くの友人がそれをメイン言語として選択し、 Rad Studioは彼のメイン環境です

gcc、MS VSへの移植が容易であるため、VCLにコードを打ち負かすつもりはありませんでした。

プラットフォーム間の移行を容易にするために、最小限のツールセットを使用するようにします。



したがって、各ネットワークの主な構造は



そしてそのタスクのために、どうにかしてそれらを互いに解きほぐす必要がありましたが、同時にそれらを連携させる必要がありました。 すぐに考えが浮かびました-クラスですが、少し考えた後、すべての重量を量って、そして-反対に、私はそれらを放棄しなければなりませんでした。 ネットワークは、メモリによってのみ制限されるニューロン/レイヤー/接続の数に合わせて設計する必要があります+作業の速度は、このネットワークがブレーキにならないように非常に高速でなければなりませんこの層、および各ニューロンの接続が個別にあります(これは、私が見つけた無料のライブラリにはまったくありませんでした)。

このためにリンクリストが選択され、ポインターを使用することが決定されました。 構造のフレームを見ていきましょう。



typedef struct _link{ }LINK; typedef struct _neuron{ struct _neuron *prev,*next; }NEURON; typedef struct _n_layer{ struct _n_layer *prev,*next; }NLAYER;
      
      





今、アイデアはこれをすべて一緒に結ぶ方法ですか?

少し考えてから、私はこれを行うことにしました:1つの通信ユニットは2つのニューロンを接続します->各通信インスタンスは簡単にアクセスでき、2つの特定のニューロンにのみ適用されるはずですが、ニューロンは無制限の数の接続を持つことができます(ソフトウェアの制限なしでライブラリを作成しようとしました)。 ニューロンは、操作を簡単にするためにレイヤーに配置する必要があります。レイヤーは使用できませんが、そのようなニューロンのクラスターでの作業は非常に困難です。 しかし、レイヤーはそれに属するニューロンへのポインターを持っているだけでなく、各ニューロンはそれが配置されているレイヤーへのポインターを持っている必要がありますが、これはネットワークでのより簡単で迅速な技術的作業のためにすでに必要です。



それで、構造は、私には思えるように、より思慮深い別の状態に移行しました。

 typedef struct _link{ void *from,*to; //  LINKL }LINK; typedef struct _link_list{ LINK *link; void *Neuron; //  __ struct _link_list *next,*prev; }LINKL; typedef struct _neuron{ LINKL *in,*out; void *Layer; //  __ struct _neuron *prev,*next; }NEURON; typedef struct _n_layer{ NEURON *first,*end; struct _n_layer *prev,*next; }NLAYER;
      
      





この時点で、リストに項目を削除/追加するハンドラーを作成します。

しかし、再び、この構造は満たされておらず、非常に重要な点が1つ欠けています...

立ち止まって考えてみましょう。どこかを見たときは考えられないのですか?

または、あなたが見ることができない何かを聞くとき? 答えはノーです。

それが、スレッドを作成するというアイデアが浮上した理由です!



これは有料の図書館でも見たことがありません。

これはどのように機能しますか? はい、それは非常に簡単です。メイン構造の各ブランチに1つのパラメーターを追加するだけです。これは状態パラメーターになります。ステータスは、これまたはそのネットワーク要素でさらに作業が可能かどうかを示します。

そして再び、私たちの構造は修正されています。



 #define STATE_NOT_READY 0 #define STATE_READY 1 typedef struct _link{ void *from,*to; }LINK; typedef struct _link_list{ LINK *link; char state; void *Neuron; struct _link_list *next,*prev; }LINKL; typedef struct _neuron{ char state; LINKL *in,*out; void *Layer; struct _neuron *prev,*next; }NEURON; typedef struct _n_layer{ NEURON *first,*end; char state; struct _n_layer *prev,*next; }NLAYER;
      
      







これで、ニューラルネットワークフレームワークの準備が整いました。



次に、よりおいしいパンに移ります。アイドル音にならないように、尊敬されているIlya90の尊敬の助けを借りずに書かれた私の研究用の既製のライブラリを提供します。



NewNeuroLib Tonich



パス:XabraZabra



おわりに


この記事では、「スマートな」ニューラルネットワークを作成するためのアプローチについて説明します。各ブランチに入力する方法を理解する必要があります。おそらくデータタイプdoubleを選択しますが、3つは明確ではなく、理解するまでプロトタイプには光が見えません。

  1. (解決済み)新しい接続が作成される条件、および/またはどのニューロンからどの接続につながるかを選択する方法。
  2. (解決済み)新しいニューロンが作成される条件(作成された内容と理由から)
  3. (部分的に解決)ニューロンはいつ「撃つ」べきですか? すべての結合の重みが配置されているか、または必要ではない場合、その場合、一定数の異なる結合の重みと値で機能する場合、関数はどのようになりますか?


これらの点が次の問題で解決される場合、このネットワークの動作を分析し、完​​全なサンプルコードを提供します。



興味があれば、使用例をレイアウトすることができますが、SaveLoadライブラリはありません(そのため、まだノーベル賞を受賞していません)




コメントへようこそ!



研究資料


もちろん、Habréに関する多くの記事。

最も注目されているFANNライブラリ。

多数の記事を読んだサイト。

私に考えさせられた非常に興味深い記事(:



All Articles