Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】How I took a hand-built convolutional network from “it runs” to “it learns reliably” without…

2025年09月24日に「Medium」が公開したITニュース「How I took a hand-built convolutional network from “it runs” to “it learns reliably” without…」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

NumPyで手書き実装した畳み込みニューラルネットワーク(CNN)を、単に動作させるだけでなく、安定してデータから学習できるようにする方法を解説。AIモデルを自作する際の具体的な改善策を紹介する。

ITニュース解説

畳み込みニューラルネットワーク(CNN)は、画像認識や音声処理など、現代の人工知能(AI)を支える重要な技術の一つだ。多くの企業で活用されている顔認証や自動運転技術の根幹にもこのCNNがある。通常、こうしたAIモデルを開発する際には、TensorFlowやPyTorchといった強力な専門ライブラリを使うことが多い。これらのライブラリは、複雑な計算や処理を自動で行ってくれるため、開発者はモデルの設計やデータ分析に集中できる。しかし、今回紹介する記事では、そうした便利なライブラリを一切使わず、Pythonの基本的な数値計算ライブラリであるNumPyだけで、CNNを「手作り」する挑戦が語られている。この記事の著者は、最初に「一応動く」程度のCNNを作り上げたものの、それが「信頼性高く学習できる」ようになるまでの試行錯誤の過程を詳細に記録している。この手作りのプロセスを通じて、ディープラーニングがどのように機能するのか、その核心的なメカニズムを深く理解することができる。システムエンジニアとしてAI技術に関わる上で、表面的な使い方だけでなく、その内部構造を理解することは非常に重要だ。

著者が最初に手作りしたCNNは、MNISTという手書き数字の画像を識別するタスクに挑戦した。しかし、その性能はランダムに数字を推測するのとほとんど変わらない約9%という低い精度だった。プログラムはエラーなく実行されるものの、全く賢くならなかったのだ。なぜこのようなことが起こるのか。ディープラーニングモデルは、正解と不正解の差(誤差)に基づいて、内部のパラメータである「重み」を少しずつ調整していくことで学習を進める。この重みを調整する過程で「勾配」という情報が使われる。勾配は、重みをどの方向に、どれくらいの大きさで変化させれば誤差が減るかを示す指標だ。しかし、初期のCNNでは、この勾配が学習を進めるにつれて非常に小さくなってしまい、最終的にほとんどゼロに近づいてしまった。これを「勾配消失」と呼ぶ。勾配が消失すると、重みはほとんど更新されなくなり、モデルは賢くなることができない状態に陥る。これが、最初に構築したCNNが「動くだけ」で「学習しない」主な原因だった。

著者はまず、重みの初期値に注目した。ディープラーニングモデルの学習は、重みをランダムな小さな値で初期化することから始まるのが一般的だ。もし全ての重みをゼロで初期化してしまうと、全てのニューロンが同じように反応し、勾配も全て同じになってしまうため、モデルは全く学習できない。そこで著者はまず、小さなランダム値で重みを初期化してみた。すると、MNISTデータセットでの精度は一気に90%まで向上し、モデルが学習できるようになったことを確認できた。しかし、さらに精度を向上させるためには、この初期化の方法をより賢くする必要があった。ディープラーニングには、活性化関数という、ニューロンの出力を非線形に変換する関数が使われる。代表的なものにReLU(Rectified Linear Unit)がある。この活性化関数に合わせて重みの初期値を適切に設定することが、勾配消失や勾配爆発(勾配が大きくなりすぎて学習が不安定になる現象)を防ぎ、学習を安定させる上で極めて重要となる。著者はReLU活性化関数に適した「He初期化」という手法を導入した。He初期化では、各層のニューロンの数に基づいて重みの初期値を調整することで、信号が各層を伝播する際にその大きさが適切に保たれるようにする。このHe初期化を適用した結果、精度は96%まで向上し、モデルがより効率的に学習できるようになった。重み初期化は地味な要素に見えるかもしれないが、ディープラーニングの学習の成否を分ける非常に重要な基礎技術なのだ。

次に著者が取り組んだのが「バッチ正規化」だ。これは、ディープラーニングの学習を劇的に安定させ、高速化するための強力な手法として知られている。モデルが学習を進めるにつれて、各層への入力データの分布が常に変化してしまう「内部共変量シフト」という現象が起こる。これにより、前の層が学習しても、次の層はその変化に適応し続ける必要があり、学習が非効率になる問題があった。バッチ正規化は、各層の入力データを、ミニバッチごとに平均が0、分散が1になるように正規化することで、この内部共変量シフトを抑制する。これにより、各層がより独立して学習できるようになり、学習の安定性が向上し、より高い学習率を設定できるようになるため、学習速度も向上する。著者が手作りのCNNにバッチ正規化を組み込んだところ、精度は98%にまで跳ね上がった。この結果は、バッチ正規化がいかにディープラーニングモデルの学習能力を引き出す上で効果的であるかを明確に示している。NumPyでバッチ正規化をゼロから実装することは容易ではないが、その内部のメカニズムを理解し、実際にコードに落とし込むことで、より深い洞察が得られるのだ。

さらに著者は「学習率スケジューリング」という手法を導入した。学習率は、モデルが一度の重み更新でどれくらい大きく重みを変化させるかを決定する重要なハイパーパラメータだ。学習率が高すぎると最適な解を行き過ぎてしまい、学習が不安定になることがある。逆に低すぎると学習が遅くなり、局所的な最適解に陥ってしまう可能性がある。学習率スケジューリングは、学習の進行に合わせて学習率を動的に調整する手法だ。例えば、学習の初期段階では比較的大きな学習率で素早く最適解の近くまで移動し、学習が進んで細かい調整が必要になるにつれて学習率を徐々に小さくしていく、といった方法が取られる。著者は、コサインカーブの形状で学習率を減少させる「コサインアニーリング」という手法を適用した。この学習率スケジューリングを導入することで、モデルの学習はさらに安定し、最終的に99.1%という非常に高い精度を達成することができた。これは、手書き数字の識別のタスクにおいて、人間が見ても間違いに気づかないほどの高い性能と言える。この最終的な精度は、GPUや大規模なデータセット、複雑なアーキテクチャ、そしてAdamのような高度な最適化アルゴリズムに頼ることなく、純粋にNumPyとCPUだけで実現されたものだ。

この記事が示しているのは、ディープラーニングの強力な機能は、実はいくつかの基本的な要素が組み合わさって実現されているということだ。重み初期化、バッチ正規化、学習率スケジューリングといった、一見すると地味に思えるかもしれない要素を、その原理を深く理解した上で適切に適用することが、高度なフレームワークや複雑なアルゴリズムに頼るよりも、時に遥かに効果的な結果をもたらすことがある。著者は、PyTorchやTensorFlowといった高レベルなライブラリや、GPUの高速計算能力、そしてAdamなどの最新の最適化アルゴリズムを使わずに、これらの基本要素をNumPyで「手作り」することにこだわった。これにより、ディープラーニングの各コンポーネントがどのように相互作用し、学習プロセスにどのような影響を与えるのかを、文字通り「手で触れるように」理解できたのだ。システムエンジニアとして、単にツールを使いこなすだけでなく、そのツールの背後にある原理や仕組みを深く理解することは、予期せぬ問題に直面した際に解決策を見つけ出す能力や、新しい技術を応用する能力を高める上で不可欠だ。この手作りCNNの物語は、基礎を固めることの重要性と、深い理解がもたらす問題解決の力を雄弁に語っている。

関連コンテンツ

関連IT用語

関連ITニュース