TensorFlow を使い始めるための重要なポイントをここにまとめました。まだ怠ける理由がありますか?

TensorFlow を使い始めるための重要なポイントをここにまとめました。まだ怠ける理由がありますか?

この記事の著者である Steven Dufresne は、初心者が TensorFlow を学習するために必要なコアな知識ポイントと実用的なコンテンツをまとめ、より多くの人が TensorFlow の助けを借りてディープラーニングの世界に参入することを奨励することを目的としています。このチュートリアルは基本的な入門チュートリアルとして、TensorFlow の原理の紹介から始まり、コアとなる概念を 1 つずつ説明します。基礎が弱く、始める方法がない初心者に最適です。

Steven Dufresne: 私は 90 年代にニューラル ネットワーク ソフトウェアを書き始めました。 TensorFlow がオープンソース化されて以来、私は TensorFlow を使って何か面白いものを作りたいと思っていました。

Google の人工知能システムが今、新たな注目を集めています。 Raspberry PiにTensorFlowをインストールできれば、操作がとても簡単になります。私はすぐにバイナリニューラルネットワークを構築しました。この記事では、ニューラル ネットワークをより深く理解したいと考えている他のユーザーがより早く始められるように、私の経験を共有します。

TensorFlow とは何ですか?

TensorFlow の公式 Web サイトを引用すると、TensorFlow は「データ フロー グラフを使用した数値計算用のオープン ソース ソフトウェア ライブラリ」です。この「データフローグラフ」とはどういう意味でしょうか? かなり面白いですね。質問に正式に答える前に、まず単純なニューラル ネットワークの構造について説明しましょう。

ニューラルネットワークの基礎

単純なニューラル ネットワークは、入力ユニット、隠れユニット、バイアス ユニット、および出力ユニットで構成されます。入力層はデータを受信する役割を担います。隠しレイヤーは、ユーザーの視点からは隠されているため、このように呼ばれます。出力層は取得した結果を出力します。その隣にある閾値は、隠れ層と出力層の値を出力するかどうか(つまり閾値を超えたニューロンのみ出力できる)を制御するために使用されます。 2 つの異なるニューロン間の接続は重みであり、これはトレーニングを通じて取得する必要がある数値にすぎません。

ニューラル ネットワークをトレーニングする目的は、重みの最適値を見つけることです。これにより、ニューラル ネットワークは段階的に「インテリジェント」になります。以下の例では、入力ニューロンの値は 2 進数 0,0,0 に設定されています。その後、TensorFlow はその間のすべてを実行し、出力ニューロンには魔法のように 0、0、1 の数字が含まれます。たとえ見逃したとしても、2 進数で 000 の次の数字は 001 であり、001 の次の数字は 010 であり、111 まで続くことはわかっています。重みが適切な値に設定されると、カウント方法がわかります。

ニューラル ネットワークを実行する手順の 1 つは、各重みを対応する入力ニューロンで乗算し、その積を対応する隠しニューロンに格納することです。

これらのニューロンと重みは配列(Python ではリストとも呼ばれます)と考えることができます。数学的な観点から見ると、どちらも行列です。図ではその一部だけをプロットしています。ここでは、入力層行列と重み行列を掛け合わせて、5 要素の隠し層行列 (リストまたはシリーズとも呼ばれます) を取得します。

行列からテンソルへ

TensorFlow では、これらのリストはテンソルと呼ばれます。行列の乗算は演算 (コンピューティング ノードまたは演算とも訳されます) と呼ばれ、プログラマーはこれを op と呼ぶことがよくあります。TensorFlow の公式ドキュメントを読んでいると、よくこの用語に遭遇するでしょう。さらに言えば、ニューラル ネットワークは、テンソルとテンソルを操作する演算の集合であり、これらが組み合わさってニューラル ネットワーク グラフを形成します。

以下の画像は、トレーニング前後のテンソル値の変化を検出するために使用される「グラフを視覚化するツール TensorBoard」という記事から引用したものです。テンソルは図の中の線であり、上の数字はテンソルの次元を表します。テンソルを接続するノードは、さまざまな操作 (op) です。ダブルクリックすると詳細が表示されます。たとえば、次の図は、ダブルクリック後のレイヤー 1 の詳細を示しています。

下の X は、入力テンソルに値を割り当てるプレースホルダー操作です。左上の線に沿って入力テンソルがあります。上記のノードには MatMul 操作というラベルが付けられており、入力テンソルと重みテンソル (MatMul 操作につながるもう 1 つの行) の行列乗算を実行します。

これらはすべて、グラフ、テンソル、および演算をより直感的に示すためのものであり、TensorFlow が「数値計算にデータフロー グラフを使用するオープン ソース ソフトウェア ライブラリ」と呼ばれる理由を誰もがよりよく理解できるようにします。しかし、なぜこのようなグラフを作成するのでしょうか?

なぜグラフを作成するのですか?

現在、TensorFlow には、インタープリタ言語である Python 用の安定した API のみがあります。ニューラル ネットワークには大量の計算が必要です。大規模なニューラル ネットワークには数千、あるいは数百万もの重みが含まれており、各ステップを解釈して計算するのは非常に非効率的です。

したがって、すべての数学演算、さらには変数の初期値を含むテンソルと演算で構成されるグラフを作成することによって、ニューラル ネットワークの構造を記述します。グラフが作成された後のみ、TensorFlow のセッションに読み込むことができます。これは TensorFlow では「遅延実行」と呼ばれます。セッションは効率的なコードを通じて計算グラフを実行します。さらに、行列乗算などの多くの演算を GPU 上で実行できます。さらに、TensorFlow は複数のマシンまたは GPU 上での同時実行もサポートします。

バイナリカウンタグラフの作成

以下は、バイナリ カウンター ニューラル ネットワークを作成するためのスクリプトです。完全なコードは私の GitHub ページにあります。 TensorBoard には他にもコードが保存されていることに注意してください。

次に、これらのコードを使用して、テンソルとオペレーションで構成されるグラフを作成します。

まず「tensorflow」モジュールをインポートし、後で使用するセッションを作成します。同時に、スクリプトを理解しやすくするために、ネットワーク内のニューロンの数を含む変数もいくつか作成します。

次に、入力ニューロンと出力ニューロンのプレースホルダーを作成します。プレースホルダーは、実際の値の後続の入力を容易にする TensorFlow の操作です。ここで、X と y_ はグラフ内の 2 つのテンソルであり、それぞれに関連付けられたプレースホルダー操作があります。

プレースホルダーの形状を、最初の次元が「None」である 2 次元リスト [None, NUM_INPUTS] と [None, NUM_OUTPUTS] として定義するのはなぜかと疑問に思うかもしれません。全体的な観点から見ると、ニューラル ネットワークは、毎回値を入力して、特定の出力値を生成するようにトレーニングするようなものです。しかし、より効率的な方法は、一度に複数の入力/出力ペア、つまりバッチを提供することです。上記の図形の最初の次元は、各バッチ内の入力/出力ペアの数です。バッチを作成する前に、その中にいくつのグループが含まれているかはわかりません。実際、トレーニング、テスト、実際の使用で同じグラフを使用するため、バッチ サイズは毎回同じにはなりません。したがって、最初の次元のサイズを Python プレースホルダー オブジェクト「None」に設定します。

次に、ニューラル ネットワーク グラフの最初のレイヤーを作成します。重みを W_fc1、しきい値 (またはバイアス) を b_fc1、隠しレイヤーを h_fc1 として定義します。ここで「fc」は「完全接続」を意味します。重みによってすべての入力ニューロンがすべての隠しニューロンに接続されるためです。

tf.truncated_normal は、すべての重みを正規化された乱数に割り当てる一連の操作とテンソルを生成します。

Variable の操作により初期化された値 (この場合は乱数) が生成され、後で複数回参照できるようになります。トレーニングが完了したら、ニューラル ネットワークをファイルに保存することも簡単です。

matmul 演算を使用して行列乗算を実行している場所を確認できます。バイアス重みを追加するための追加操作を挿入します。 relu 操作は「活性化関数」を実行します。行列の乗算と加算はどちらも線形演算です。ニューラル ネットワークが線形演算を使用して実行できることはほとんどありません。活性化方程式は、ある程度の非線形性を提供します。ここでの relu 活性化関数は、0 未満の値をすべて 0 に設定し、残りの値は変更されません。信じられないかもしれませんが、これにより、ニューラル ネットワークが学習できるまったく新しい世界が開かれます。

ニューラル ネットワークの 2 番目の層の重みとしきい値は最初の層と同じように設定され、出力層のみが異なります。もう一度行列乗算を行い、今度は重みと隠し層を乗算し、バイアス重みを追加して、活性化関数を次のコード セットに残します。

上記の relu と同様に、Sigmoid も非線形の別の活性化関数です。ここでシグモイド関数を使用するのは、最終出力値が 0 と 1 の間になるため、バイナリ カウンターに最適な選択肢となるためです。この場合、バイナリ 111 を表すために、すべての出力ニューロンが大きな値を持つことができます。これは、1 つの出力ユニットのみを使用して大きな値を出力する画像分類とは異なります。たとえば、画像にキリンが写っている場合、キリンを表す出力ユニットが比較的大きな値を出力するようにする必要があります。この場合、活性化関数としてソフトマックス関数を使用する方が適切です。

前のコードをよく見ると、繰り返しがあるように見えることがわかります。 sigmoid を 2 回挿入しました。実際に行うのは、2 つの異なる並列出力を作成することです。 cross_entropy テンソルはニューラル ネットワークのトレーニングに使用されます。結果テンソルは、トレーニングの目的に関係なく、トレーニングされたニューラル ネットワークを実行するために使用されます。これが現時点で私が考えられる最善の方法です。

まずはトレーニングです。つまり、すべての重みはトレーニング データに基づいて調整されます。覚えておいてください、ここではまだグラフを作成しているだけです。実際の「トレーニング」は、このグラフの実行を開始したときに行われます。

実行プロセス中に選択できるオプティマイザーは多数あります。ここでは tf.train.RMSPropOptimizer を選択しました。シグモイドと同様に、すべての出力値が大きくなる可能性がある状況に適しているためです。画像分類などの分類シナリオでは、tf.train.GradientDescentOptimizer を使用する方が効果的かもしれません。

バイナリカウンタのトレーニングと使用

グラフの作成が完了したら、トレーニングを開始できます。

まず、入力変数 inputvals とターゲット変数 targetvals を含むトレーニング データを準備します。 inputvals には入力値が含まれ、各入力値には対応する targetvals ターゲット値があります。たとえば、inputvals[0]は[0, 0, 0]であり、対応する出力またはターゲット値はtargetvals[0]で、[0, 0, 1]です。

do_training と save_trained はどちらもハードコードして毎回変更することも、コマンドライン引数を使用して設定することもできます。

まず、すべての変数操作がテンソル上で初期化されます。次に、以前に作成されたグラフが下から train_step まで 10001 回以内実行されます。これがグラフに追加される最初のものです。 RMSPropOptimizer を介して、inputvals と targetvals を train_step 操作に渡します。これは、入力値が与えられた場合に出力値が目標値に近づき続けるように重みを調整するステップです。出力値と目標値の間の誤差が、一定の許容範囲内で十分に小さい限り、ループは停止します。

数百または数千の入力/出力ペアがある場合は、一度にサブセット(上記のバッチ)をトレーニングできます。しかし、ここでは合計 8 つのグループしかないため、毎回すべてを入れます。

次回再度トレーニングする必要がないように、トレーニング済みのニューラル ネットワークをファイルに保存することもできます。次回は、トレーニング済みのニューラル ネットワーク ファイルを直接インポートできます。ファイルには、変数操作後のテンソルの値のみが含まれており、グラフ全体の構造は含まれていません。したがって、トレーニング済みのグラフを実行する場合でも、グラフを作成するためのスクリプトが必要になります。 MetaGraphs はグラフをファイルに保存したりインポートしたりできますが、ここではそれを行いません。

グラフの下部から結果テンソルまで実行し、ネットワークをトレーニングしながら結果を繰り返し作成していることに注意してください。

000 を入力すると、001 に近い値が返されると考えられます。次に、返された値を繰り返して再度実行します。これを合計 9 回実行して、000 から 111 までカウントし、再び 000 に戻るのに十分な回数を確保します。

以下はトレーニングが成功した後の出力です。ループ内で200回(ステップ)トレーニングされます。実際には、10001 回トレーニングしてもトレーニング エラーが効果的に削減されないことはほとんどありません。一度トレーニングに成功すれば、何回トレーニングしても問題ありません。


バイナリカウンタの実行

次のステップ

前述したように、ここで説明するバイナリ カウンティング ニューラル ネットワーク コードは、私の Github ホームページで見つけることができます。これらのコードに従って学習を開始したり、TensorFlow 公式 Web サイトで他の入門チュートリアルを視聴したりすることができます。次は、ロボットの物体認識から得たインスピレーションをもとに、ハードウェアの研究に活用していきたいと思っています。

<<:  ディープラーニングによる時系列モデルの評価

>>:  線形回帰の勾配降下アルゴリズムのオクターブシミュレーション

ブログ    
ブログ    

推薦する

TabR: 検索拡張により、深層学習は表形式データで勾配ブースティング モデルを上回るパフォーマンスを発揮できるようになりますか?

これは7月に発表された新しい論文で、深層学習が表形式データにおける勾配強化モデルを上回ることを可能に...

...

ビッグデータの時代では、ソフトウェアエンジニアは徐々に減少し、アルゴリズムエンジニアが増加しています。

[[209263]]ビッグデータは人類の歴史のどの時代にも存在していましたが、テクノロジーが一定の...

最高年収は約56万! 2023年の最新のAIGC雇用動向レポートが発表されました

言うまでもなく、ChatGPT が過去 6 か月間でどれほど人気が​​あったかは誰もが知っています。...

...

OpenAI の Whisper モデルを使用して音声をテキストに変換する

翻訳者 |ブガッティレビュー | Chonglou図1. OpenAI Whisperモデルの動作原...

人工知能の世界を探る: インテリジェントな質問応答システムの構築 - 環境

導入前回の記事では、プロジェクトに必要な知識のポイントについて簡単に説明しました。今日は、プロジェク...

Nvidia 3090が180億パラメータの大規模モデルに単独で挑む。今度は国内オープンソースプロジェクトが大暴れ

この記事はAI新メディアQuantum Bit(公開アカウントID:QbitAI)より許可を得て転載...

...

アルゴリズム: Javascript をエレガントに使用して構造ツリーを再帰的に描画する方法

[[376839]]再帰と末尾再帰簡単に言えば、再帰とは関数が自分自身を呼び出すことです。プログラミ...

ニュースローン賞受賞者 宋 樹蘭: 視覚の観点からロボットの「目」を構築する

この記事はLeiphone.comから転載したものです。転載する場合は、Leiphone.com公式...

ロボット「ソフィア」の現状は普通の人間と変わらず、コミュニケーション障壁もない

ハイテクノロジーの発展により、ロボットは映画に登場するものではなく、現実のものとなりました。人工知能...

Google が暗号化アルゴリズム SHA-1 の廃止を急いでいる理由

[[120276]]ハッシュアルゴリズムのヒルベルト曲線図 (Ian Boyd 提供) Google...

Deeplearning4j: JVM 向けのディープラーニングと ETL

[[410828]]この記事はWeChatの公開アカウント「Java Architecture M...