【超入門】ディープラーニングの「中身」わかりますか?ニューラルネットワークの概念を副業エンジニアが噛み砕く

目次

数学アレルギーだった私が、AIの「中身」を理解するまで

正直に告白すると、私は20代の頃、一度AIの勉強に挫折している。

あれはたしか、第3次AIブームが叫ばれ始めた頃だったか。「これからはエンジニアもAIの知識が必要だ!」と意気込んで、分厚い専門書を買ってきたんだ。タイトルは『ゼロから作る…』みたいなやつ。名著と言われている本だ。

意気揚々とページを開いた私を待っていたのは、容赦ない数式の嵐だった。
シグマ(Σ)、偏微分(∂)、行列の積…。

「あ、これ無理なやつだ」

高校時代、数学のテストで赤点を回避することだけに全力を注いでいた私にとって、それは未知の言語だった。そっと本を閉じ、本棚の奥に封印した。「ま、ライブラリ使えば中身なんて知らなくても動くでしょ」と言い訳をして。

でも、エンジニアを20年もやっていると、どうしても避けられない壁にぶつかる。
クライアントから「AIで画像認識やりたいんだけど、精度が上がらないんだよね」と相談された時、「ライブラリのパラメータいじってみます」だけじゃ太刀打ちできなかった。

「なぜ精度が出ないのか?」「どこで判断を間違えているのか?」
それを知るには、やっぱりブラックボックスの中身――つまり「ニューラルネットワーク」の仕組みを理解する必要があったんだ。

重い腰を上げて再挑戦した私が気づいたのは、「数式の厳密な証明は数学者に任せておけばいい」ということ。エンジニアに必要なのは、数式そのものではなく、それが「どういう動きをしているか」というイメージ(概念)だった。

この記事では、かつての私のような「数学アレルギー」のエンジニアや初学者に向けて、ディープラーニングの基礎である「ニューラルネットワーク」を、数式を極力使わずに解説していく。

「AIの中身って、実はただの〇〇だったんだ」

読み終わった頃には、そんな風にブラックボックスに対する恐怖心が消えているはずだ。副業案件でAI関連の仕事を取りたい人、KerasやPyTorchを使っているけど裏側で何が起きているか不安な人。ぜひ最後まで付き合ってほしい。

数式だらけの専門書を開いて頭を抱え、絶望している若い頃の男性エンジニアの線画イラスト

そもそも「ニューラルネットワーク」って何者?

よく「人間の脳を模倣した」とか言われるけど、これだけだと抽象的すぎてピンとこないよね。

私らが普段書いている従来のプログラム(ルールベース)と何が違うのか。
従来のプログラムは、「料理のレシピ」だ。
「AならばBせよ」「もし塩が足りなければ小さじ1杯足せ」と、人間が全てのルールを記述する。

対してニューラルネットワークは、「味見係の修行」に近い。
最初は何も知らない新人に、とりあえず料理を作らせる。当然、激マズの料理ができる。
そこで師匠(正解データ)が「しょっぱすぎる!」「もっと甘く!」と怒る。
新人は「次は塩を減らそう…」と調整する。
これを数万回繰り返すうちに、人間が細かい分量を指示しなくても、勝手に美味しい料理(正解)を作れるようになる。

この「勝手に調整して賢くなっていく仕組み」のモデルが、ニューラルネットワークだ。

脳の神経細胞(ニューロン)をマネする

生物の授業で習ったかもしれないけど、人間の脳には「ニューロン」という神経細胞がある。
こいつの働きは単純だ。

  1. 他の細胞から電気信号を受け取る。
  2. 受け取った信号の合計が、ある一定のレベル(閾値)を超えたら、「ビビビッ!」と興奮(発火)して、次の細胞へ信号を送る。
  3. 超えなければ、無視する(送らない)。

たったこれだけ。
「受け取って、判断して、送る」。この単純な装置が、脳内に1000億個以上あって、複雑に絡み合っているから、私らは「今日の晩御飯どうしよう」とか「この記事長いな」とか高度な思考ができる。

ニューラルネットワークは、このニューロンの動きを数式で再現したものだ。

パーセプトロン:AIの最小単位

ニューロンを人工的に再現した一番シンプルな形を「パーセプトロン」と呼ぶ。
これがニューラルネットワークの構成要素、いわば「レゴブロックの1ピース」だ。

構造はシンプル。
「入力」→「計算(重みづけ)」→「活性化」→「出力」
という流れだ。

例えば、「週末にバーベキューに行くかどうか」を判断するパーセプトロンを考えてみよう。
判断材料(入力)は2つあるとする。

  1. 天気は良いか?(x1)
  2. ビールはあるか?(x2)

ここで重要なのが「重み(Weight)」だ。これは「その入力情報をどれくらい重要視するか」というパラメータだ。

「俺は雨でもビールがあれば行くぜ!」という酒好きの人なら、「ビールの有無」の重み(w2)は大きくなり、「天気」の重み(w1)は小さくなる。
逆に「雨の中で肉焼くとかありえない」という人なら、「天気」の重み(w1)が大きくなる。

入力された情報に、この「重み」を掛け算して、合計する。
さらに、個人の性格(「そもそも出不精」とか「フットワーク軽い」とか)を表す「バイアス(Bias)」を足す。

その合計値が、ある基準を超えたら「行く(1)」、超えなければ「行かない(0)」と出力する。
これがパーセプトロンの正体だ。

つまり、AIの中身っていうのは、魔法の箱じゃなくて、「入力データに対して、適切な『重み』と『バイアス』を見つけ出し、掛け算と足し算をしている計算機」なんだ。

ホワイトボードに描かれた単純なパーセプトロンの図を指差して解説するメンターの線画イラスト

ディープラーニングの核心:「層」を重ねるとなぜ賢くなる?

パーセプトロン単体だと、単純なこと(線形分離可能な問題)しか解決できない。「天気」と「ビール」くらいならいいけど、「画像に写っているのが猫か犬か」なんて複雑な判断は無理だ。

そこで考え出されたのが、「パーセプトロンをたくさん並べて、層にする」というアイデア。

  • 入力層(Input Layer): データを最初に受け取る層。画像の画素値とかが入ってくる。
  • 中間層(Hidden Layer / 隠れ層): 入力層と出力層の間にある層。ここで複雑な特徴を抽出する。
  • 出力層(Output Layer): 最終的な判断(猫である確率80%、とか)を出す層。

この「中間層」を2層、3層、100層…と深く(Deep)していったものが、ディープラーニング(深層学習)だ。

「伝言ゲーム」で考える情報の抽象化

なぜ層を深くすると賢くなるのか?
これを私はよく「社内の意思決定」に例えて説明する。

1. 入力層(平社員たち)
現場の生データを見る。「ここが黒い」「ここが丸い」「耳っぽい形がある」といった細かい断片的な情報しか見ない。

2. 中間層の浅い部分(係長クラス)
平社員からの報告をまとめる。「黒くて丸い部分があるなら、それは目かもしれない」「三角なら耳かもしれない」。少し情報がまとまる(エッジの検出など)。

3. 中間層の深い部分(部長クラス)
係長からの報告を統合する。「目があって、耳があって、ヒゲがあるなら、これは動物の顔だな」。より抽象的で高度な概念になる。

4. 出力層(社長)
部長からの報告を受けて最終決定する。「これは猫だ!」。

層が深くなればなるほど、最初はただの「点の集まり」だったデータが、段階的に意味のある「特徴」へと変換されていく。これがディープラーニングの凄さだ。昔の機械学習は、この「特徴(ここが目だ、とか)」を人間が指定してあげる必要があったけど、ディープラーニングは層を重ねることで、勝手に特徴を見つけ出す能力を手に入れたんだ。

学習の仕組み:AIはどうやって「間違い」を修正するのか?

ニューラルネットワークの構造はわかった。
じゃあ、どうやって「猫」と「犬」を正しく見分けられるようになるのか?
ここで登場するのが「学習」というフェーズだ。

学習とは一言で言えば、「最適な『重み(w)』と『バイアス(b)』の値を、自動調整すること」だ。

最初は、この重みとバイアスは完全にランダムな数字が入っている(これを初期化という)。だから、猫の写真を見せても「うーん、飛行機!(確率50%)」とかデタラメな答えを出す。

ここから賢くなるために、以下の2つのステップを何万回も繰り返す。

  1. フォワードプロパゲーション(順伝播):入力から出力へ計算を進めて、予測値を出す。
  2. バックプロパゲーション(誤差逆伝播法):正解とのズレ(誤差)を計算し、原因を遡って修正する。

誤差逆伝播法:責任のなすりつけ合い大会

ここがディープラーニング最大の難所であり、一番面白いところだ。
バックプロパゲーションを直感的に理解しよう。

イメージしてほしい。
あるプロジェクト(猫判定プロジェクト)が大失敗したとする。
社長(出力層)が「おい!猫なのに飛行機って判定したぞ!大赤字だ(大きな誤差が発生)!」と激怒する。

社長は、直属の部下である部長(中間層の最後)を問い詰める。
「お前の報告が間違ってたからだ! どれくらい間違ってたか修正しろ!」

部長は言い訳をする。「いや、係長(一つ前の中間層)からのデータが変だったんです…」と言って、係長の責任を追及し、係長の持っているパラメータ(重み)を少し修正させる。

係長はさらにその部下の平社員(入力層に近い層)を問い詰める。「お前が変なデータ渡すからだ! お前の重みも修正しろ!」

こうして、「出力(ゴール)側から入力(スタート)側に向かって、誤差(責任)を逆流させながら、全員の重みを少しずつ修正していく」
これが誤差逆伝播法だ。

数学的には「微分(偏微分)」を使う。
「損失関数(どれくらい間違ったかの指標)」を「重み」で微分することで、「重みを増やせば誤差が減るのか、減らせば誤差が減るのか」という傾きがわかる。その傾きの方向に、少しだけパラメータを動かす。これを「勾配降下法」と呼ぶ。

これを何万回も繰り返すと、組織全体(ネットワーク)の連携が取れてきて、誰もミスをしない(誤差が最小になる)完璧な重みの組み合わせが出来上がる。これが「学習完了」の状態だ。

黒板の前でチョークを持ち、誤差が後ろへ伝わっていく様子を図解している様子の線画イラスト

重要な脇役たち:活性化関数と損失関数

ニューラルネットワークを語る上で、外せない脇役がいる。これらを知っていないと、自分でモデルを組む時に必ず迷うことになる。

活性化関数:スパイスを加える

ニューロンの説明で「入力の合計がある値を超えたら発火する」と言ったけど、この「どう発火するか」を決めるのが活性化関数だ。

もし活性化関数がなかったらどうなるか?
実は、ただの掛け算と足し算(線形変換)の連続になってしまい、どんなに層を重ねても、複雑な表現ができなくなる(単層パーセプトロンと同じ能力しか出ない)。
活性化関数が「非線形」な性質を与えることで、ニューラルネットワークは複雑な境界線を引けるようになるんだ。

代表的なものは以下の3つ。

  1. Sigmoid(シグモイド)関数
    • 出力を0から1の間に押し込める。
    • 昔はよく使われたけど、「勾配消失問題(層が深くなると誤差が伝わらなくなる)」が起きやすいため、今は中間層ではあまり使われない。出力層で確率(0~1)を出したい時に使う。
  2. ReLU(レル)関数
    • 入力が0以下なら0、0より大きければそのまま出力する。
    • シンプルすぎて不安になるけど、現在の中間層のデファクトスタンダード。計算が速く、学習が安定しやすい。迷ったらとりあえずReLUを使っておけば間違いない。
  3. Softmax(ソフトマックス)関数
    • 出力層で使う。複数の出力の合計が「1(100%)」になるように調整してくれる。
    • 「猫:80%、犬:15%、鳥:5%」みたいに確率を出したい多クラス分類の必需品。

損失関数(Loss Function):成績表の付け方

AIがどれくらい間違っているか、その「間違いの大きさ」を定義する関数。
学習の目的は、この損失関数の値を「0」に近づけることだ。

  • 二乗和誤差(Mean Squared Error):回帰問題(家賃予測など数値を当てる)で使う。
  • 交差エントロピー誤差(Cross Entropy Error):分類問題(猫か犬か)で使う。

メンターとして受講生のコードを見ていると、この「活性化関数」と「損失関数」の組み合わせがチグハグでエラーになっているケースが非常に多い。
「2値分類(0か1か)なら、出力層はSigmoidで損失関数はBinary Cross Entropy」
「多クラス分類なら、出力層はSoftmaxで損失関数はCategorical Cross Entropy」
この定石セットは覚えておこう。

【実践】Python(NumPy)で理解する「重み」の更新

概念ばかりだと眠くなるので、実際にコードを見てみよう。
KerasやPyTorchなどのライブラリを使うと、model.fit() の1行で終わってしまう学習プロセスを、あえてNumPyだけを使って書いてみる。

これが「ブラックボックスを開ける」ということだ。
ここでは、非常に単純な「AND回路(両方1なら1、それ以外は0)」を学習させてみよう。

import numpy as np

# シグモイド関数(活性化関数)
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

# シグモイド関数の微分(バックプロパゲーション用)
def sigmoid_derivative(x):
    return x * (1 - x)

# 入力データ(AND回路の入力:00, 01, 10, 11)
inputs = np.array([[0,0], [0,1], [1,0], [1,1]])

# 正解データ(AND回路の出力:0, 0, 0, 1)
expected_output = np.array([[0], [0], [0], [1]])

# 重みとバイアスの初期化(ランダム)
inputLayerNeurons = 2
hiddenLayerNeurons = 2
outputLayerNeurons = 1

# 重み(ランダムな値でスタート)
hidden_weights = np.random.uniform(size=(inputLayerNeurons, hiddenLayerNeurons))
output_weights = np.random.uniform(size=(hiddenLayerNeurons, outputLayerNeurons))

# 学習率(どれくらいのペースで修正するか)
lr = 0.1 
epochs = 10000 # 学習回数

# 学習ループ
for _ in range(epochs):
    # 1. フォワードプロパゲーション(順伝播)
    hidden_layer_activation = np.dot(inputs, hidden_weights)
    hidden_layer_output = sigmoid(hidden_layer_activation)

    output_layer_activation = np.dot(hidden_layer_output, output_weights)
    predicted_output = sigmoid(output_layer_activation)

    # 2. バックプロパゲーション(誤差逆伝播)
    # 誤差の計算
    error = expected_output - predicted_output

    # 出力層の勾配(傾き)
    d_predicted_output = error * sigmoid_derivative(predicted_output)

    # 中間層の誤差
    error_hidden_layer = d_predicted_output.dot(output_weights.T)
    d_hidden_layer = error_hidden_layer * sigmoid_derivative(hidden_layer_output)

    # 重みの更新(学習)
    output_weights += hidden_layer_output.T.dot(d_predicted_output) * lr
    hidden_weights += inputs.T.dot(d_hidden_layer) * lr

print("学習後の出力(予測値):")
print(predicted_output)

このコードを実行すると、最初はランダムだった出力が、学習後には [0.02, 0.01, 0.03, 0.98] のように、正解(0, 0, 0, 1)に近い値になっているはずだ。

注目してほしいのは、np.dot(行列の積)と +=(更新)の繰り返しだということ。
ディープラーニングの実体は、巨大な行列の掛け算と、微調整の繰り返しに過ぎない。
これを知っているだけで、AIに対する「得体の知れないもの」という感覚は消えるはずだ。

自宅のデスクでモニターに映るPythonコードを見つめ、納得した表情を浮かべる30代男性の線画イラスト

エンジニア副業で「中身の理解」がどう役立つ?

「理屈はわかったけど、実務ではライブラリ使うんでしょ? 意味あるの?」
そう思うかもしれない。私もそう思ってた。

でも、副業で案件を受けるようになって、この知識の重要性を痛感した。その理由をいくつか挙げよう。

1. エラーの原因特定(デバッグ)が早くなる

モデルが学習しない(Lossが下がらない)時、中身を知らないと「データが悪いのかな?」と当てずっぽうに対処するしかない。
でも仕組みを知っていれば、
「あ、これは学習率(Learning Rate)が大きすぎて発散してるな」
「活性化関数にReLUを使ってるのに、入力データの正規化をしてないから死んだニューロン(Dead ReLU)が発生してるかも」
といった仮説が立てられる。これはプロの現場で必須のスキルだ。

2. ファインチューニングの精度が変わる

最近の案件では、ゼロからモデルを作るより、学習済みのモデル(VGG16とかBERTとか)を持ってきて、自分のデータに合わせて再学習させる「転移学習」「ファインチューニング」が主流だ。
この時、「どの層の重みを固定(フリーズ)して、どの層だけ再学習させるか」という判断が必要になる。ニューラルネットワークの階層構造(浅い層は汎用的な特徴、深い層は専門的な特徴)を理解していないと、この調整ができない。

3. クライアントへの説明責任

副業で一番怖いのは、納品後に「なんでAIはこの判断をしたんですか?」と聞かれることだ。
「AIがそう言ってるんで…」ではプロ失格。
「このモデルはこういう特徴量に重きを置く傾向があります」とか「データセットにこういうバイアス(偏り)があったため、推論結果にも影響が出ています」と、論理的に説明できるかどうか。これが単価を分ける。

オンラインミーティングでクライアントに対してAIの挙動を論理的に説明している様子の線画イラスト

よくある質問(FAQ)

ここからは、メンターとしてよく聞かれる質問に答えていく。

Q1. 数学(微分・線形代数)はどこまで勉強すべき?

A. 「概念」だけ掴めばOK。計算はPCがやる。
実務レベルで手計算で微分することはまずない。ただ、「微分=傾き=学習の方向を決めるもの」「行列=データをまとめて計算するための表」というイメージだけは持っておこう。G検定(ジェネラリスト検定)のテキストを一通り読むくらいで十分だ。

Q2. GPUってやっぱり必要なの?

A. 学習させるなら必須。推論だけならCPUでもいける。
ディープラーニングの計算(行列演算)は、CPUよりGPUの方が圧倒的に速い。画像データを学習させる場合、GPUがないと数日かかるものが数時間で終わる。Google Colabを使えば無料でGPUが使えるので、まずはそこから始めよう。副業で本格的にやるなら、ゲーミングPCを買うか、AWSなどのクラウドを使うことになる。

Q3. どのフレームワークから覚えるべき?

A. 初心者はPyTorchがおすすめ。
以前はKeras(TensorFlow)が簡単で人気だったけど、最近の研究論文やGitHubのコードはPyTorchが主流になりつつある。PyTorchはPythonの書き方に近くて直感的(デバッグもしやすい)。これから覚えるならPyTorch一択だと私は思う。

Q4. 独学でニューラルネットワークを理解するには?

A. コードを写経するのが一番早い。
本を読むだけで理解するのは天才じゃないと無理。おすすめは、今回紹介したような「NumPyだけで作る」系の記事や本(『ゼロから作るDeep Learning』など)のコードを、1行ずつ写経して動かすこと。変数の値(行列の形)を print(x.shape) で確認しながら進めると、データがどう流れているかが見えてくる。

まとめ:ブラックボックスを開ける勇気を持とう

長々と語ってきたけど、ニューラルネットワークの概念、なんとなく掴めただろうか?

  • ニューロン=入力を判断して次に送る単純なスイッチ
  • 層を重ねる=情報を抽象化して賢くなる仕組み
  • 学習=先生(正解)に怒られながら、重み(パラメータ)を微調整する伝言ゲーム
  • 正体=巨大な行列の掛け算

AIは決して魔法じゃない。先人たちが「どうすれば脳の動きを数式で表せるか」と試行錯誤して積み上げた、泥臭い計算の塊だ。

副業エンジニアとしてAI案件に関わる時、この「中身」を知っているかどうかが、君のエンジニアとしての「重み(信頼度)」を大きく変えることになる。

最初は難しく感じるかもしれない。数式を見て頭が痛くなるかもしれない。
でも、大丈夫。私もそうだった。
コードを書いて、エラーを出して、形(shape)を確認して。そうやって泥臭く手を動かした分だけ、ブラックボックスの中身はクリアになっていく。

さあ、次は君が手を動かす番だ。PythonとNumPyを開いて、自分だけの小さな「脳みそ」を作ってみよう。そこには、ただのAPI利用だけでは見えない、面白い世界が広がっているはずだから。

朝日が差し込む部屋で、ノートPCを開いて新しいAIモデルの実装に挑戦しようとしている後ろ姿の線画イラスト
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いたエンジニア

渡辺 一誠のアバター 渡辺 一誠 バックエンドスペシャリスト

バックエンドに長く携わるスペシャリストで、高負荷環境での最適化が得意。論理的かつストイックだが仲間へのサポートは手厚い。クラシック音楽が好きで、集中したい時はよく流している。確かな技術でプロジェクトを支える存在。

目次