大学では、私にとって大きな関心にもかかわらず、ニューラルネットワークのトピックが私の専門分野を首尾よく通過しました。 独学の試みは、科学の要塞の破壊不可能な壁に対する無知な額によって、大学の教科書のあいまいな「スナップ」用語と混乱した説明の形で何度か破壊されました。
この記事(一連の記事ですか?)では、「よく知られた実証済みのパターンに従って動作するパーセプトロンを構成するニューロンの配列」ではなく、単純な例を使用して、単純な例を使用して、初心者の視点からニューラルネットワークのトピックを説明しようとします。
猫の下で興味を持ってください。
目標
ニューラルネットワークとは何ですか?
ニューラルネットワークは学習システムです。 所定のアルゴリズムと式に従って動作するだけでなく、過去の経験にも基づいています。 毎回パズルを組み立て、ミスを少なくするような子供。
そして、ファッショナブルな著者から書くのが慣習であるため、ニューラルネットワークはニューロンで構成されています。
ここで、停止してそれを把握する必要があります。
ニューロンは、多数のインレットと1つのアウトレットを持つ単なる仮想的なブラックボックスであることに同意します。
さらに、着信情報と発信情報の両方が類似している場合があります(ほとんどの場合、類似しています)。
入力のヒープから出力信号がどのように形成されるか-ニューロンの内部アルゴリズムを決定します。
たとえば、ビットマップ画像上のロシア語の文字など、単純な画像を認識する小さなプログラムを作成します。
初期状態では、システムに「空の」メモリがあることに同意します。 戦いの準備ができた一種の新生児の脳。
正しく機能させるために、トレーニングに時間を費やす必要があります。
私に飛んでくるトマトを避けて、Delphiで書くと言います(この記事を書いている時点では手元にありました)。 必要に応じて、例を他の言語に翻訳するお手伝いをします。
また、コードの品質を軽く取るようにお願いします。プログラムは、トピックに対処するためだけに1時間で作成されました。
では、タスクに基づいて、いくつの終了オプションがありますか? そうです、私たちが決定できる数の手紙。 アルファベットには33個しかありません。そこで停止します。
次に、入力データを決定します。あまり気にしないために、30x30ビットマップをビットマップイメージとして入力に送信します。
その結果、33個のニューロンを作成する必要があり、各ニューロンには30x30 = 900の入力があります。
ニューロンのクラスを作成しましょう:
type Neuron = class name: string; // – , input: array[0..29,0..29] of integer; // 3030 output:integer; // , memory:array[0..29,0..29] of integer; // end;
文字数に従ってニューロンの配列を作成します。
For i:=0 to 32 do begin neuro_web[i]:=Neuron.Create; neuro_web[i].output:=0; // neuro_web[i].name:=chr(Ord('A')+i); // end;
問題は、プログラムが機能しない場合、ニューラルネットワークの「メモリ」をどこに保存するかです。
INIや、神の禁じられているデータベースを詳しく調べないために、同じ30x30ラスターイメージに保存することにしました。
たとえば、プログラムを異なるフォントで実行した後のニューロン「K」のメモリ:
ご覧のとおり、最も飽和した領域は最も一般的なピクセルに対応しています。
作成された各メモリに「メモリ」をロードします。
p:=TBitmap.Create; p.LoadFromFile(ExtractFilePath(Application.ExeName)+'\res\'+ neuro_web[i].name+'.bmp')
訓練されていないプログラムの開始時には、各ニューロンのメモリは30x30のホワイトスポットになります。
ニューロンは次のように認識されます。
-最初のピクセルを取る
-メモリ内の1mピクセルと比較します(値0..255があります)
-差を特定のしきい値と比較する
-差がしきい値よりも小さい場合、この時点で文字はメモリ内の文字と似ていると考え、ニューロンの重みに+1を追加します。
そして、すべてのピクセルで。
ニューロンの重みは特定の数(理論上は900まで)であり、処理された情報とメモリに保存されている情報との類似度によって決まります。
認識の最後に、一連のニューロンがあり、それぞれが数パーセント正しいと考えています。 これらの割合は、ニューロンの重量です。 重みが大きいほど、この特定のニューロンが正しい可能性が高くなります。
ここで、プログラムに任意の画像を供給し、各ニューロンを実行します。
for x:=0 to 29 do for y:=0 to 29 do begin n:=neuro_web[i].memory[x,y]; m:=neuro_web[i].input[x,y]; if ((abs(mn)<120)) then // if m<250 then neuro_web[i].weight:=neuro_web[i].weight+1; // , , if m<>0 then begin if m<250 then n:=round((n+(n+m)/2)/2); neuro_web[i].memory[x,y]:=n; end else if n<>0 then if m<250 then n:=round((n+(n+m)/2)/2); neuro_web[i].memory[x,y]:=n; end;
最後のニューロンのサイクルが終了するとすぐに、より大きな重みを持つすべてのニューロンから選択します。
if neuro_web[i].weight>max then begin max:=neuro_web[i].weight; max_n:=i; end;
このmax_nの値を使用して、プログラムは、その意見では、彼女にそれをスリップしたと教えてくれます。
最初は、これは常に正しいとは限らないため、学習アルゴリズムを作成する必要があります。
s:=InputBox('Enter the letter', ' , '+neuro_web[max_n].name, neuro_web[max_n].name); for i:=0 to 32 do begin // if neuro_web[i].name=s then begin // for x:=0 to 29 do begin for y:=0 to 29 do begin p.Canvas.Pixels[x,y]:=RGB(neuro_web[i].memory[x,y],neuro_web[i].memory[x,y], neuro_web[i].memory[x,y]); // end; end; p.SaveToFile(ExtractFilePath(Application.ExeName)+'\res\'+ neuro_web[i].name+'.bmp');
メモリの更新自体は次のように行われます。
n:=round(n+(n+m)/2);
つまり この点がニューロンの記憶にないが、教師がそれがこの手紙にあると言ったら、私たちはそれを覚えていますが、完全ではなく、半分だけです。 さらにトレーニングを行うと、このレッスンの影響度が高まります。
文字Gのいくつかの反復を次に示します。
これで、プログラムの準備ができました。
トレーニング
トレーニングを始めましょう。
手紙の画像を開き、そのエラーを辛抱強くプログラムに指摘します。
しばらくすると、プログラムはそれまで馴染みのない文字でも安定して判断し始めます。
おわりに
プログラムは1つの継続的な欠陥です-私たちのニューラルネットワークは非常に愚かで、トレーニング中のユーザーエラーから保護されておらず、認識アルゴリズムはスティックのように単純です。
ただし、ニューラルネットワークの機能に関する基本的な知識は得られます。
この記事が尊敬されるハブに興味がある場合は、サイクルを継続し、システムを徐々に複雑にし、追加の接続と重みを導入し、人気のあるニューラルネットワークアーキテクチャなどを検討します。
ここでソースと一緒にプログラムをダウンロードすることで、生まれたての知性をあざけることができます 。
シムについては、お辞儀をして、読んでくれてありがとう。
UPD:ニューラルネットワークの空白を取得しました。 これまでのところ、これはまだ彼女ではありませんが、次の記事では、それから本格的なニューラルネットワークを作成しようとします。
コメントをくれたShultcに感謝します。