クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

小さなニューラルネットワークが学ぶ仕組み

このレッスンのあとで: 小さなニューラルネットワークがどう学ぶかを説明できる。

55分のレッスンコマンド2件JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

だれも書いていない決まり

予約アプリが、土曜日は混むと店に知らせてきました。アプリを作った人は「暖かくて乾いた週末なら」という決まりを書いていません。アプリは意味のない数から始め、過去の日を1日ずつ見て、その数を直していったのです。

この直していくことが、ニューラルネットワークにとっての「学ぶ」です。手で追える計算です。

このレッスンのゴール

メモ

小さなニューラルネットワークがどう学ぶかを説明できる。

キーワード

ことばいみれい
ニューロン重みをかけた入力とバイアスを足し、答えを決めるもの
重み1つの入力がどれだけ効くか
バイアス決め方をずらすために足す数
学習率1回の直しの大きさ0.1
エポック学習データのすべての行を1回通すこと
隠れ層入力と答えのあいだにあるニューロンの列

学生が入力するセルは、このプレビューでは空白です。

パーセプトロンは足してから決める

パーセプトロンは、ニューロン1つです。各入力にその重みをかけて足し、バイアスを足します。

合計が0より大きければ1、ここでは「busy」と答えます。そうでなければ0、「quiet」です。大きなプラスの重みは、その入力を busy の側へ押します。マイナスの重みは quiet の側へ押します。

例: 2日をニューロンに通す

日入力: 気温、雨、週末重み 0.5、-0.9、0.4 とバイアス -1合計答え
暖かい土曜2.0、0.0、11.0 + 0 + 0.4 - 10.41、busy
寒くて雨の火曜0.5、1.0、00.25 - 0.9 + 0 - 1-1.650、quiet

学生が入力するセルは、このプレビューでは空白です。

1回の直しを手で

コード: python
# 忙しかった1日: 気温は10度単位、雨は cm、週末は1です。
day = [2.0, 0.0, 1]
target = 1
weights = [0.0, 0.0, 0.0]
bias = 0.0
rate = 0.1

total = bias
for n in range(3):
    total = total + weights[n] * day[n]
guess = 0
if total > 0:
    guess = 1
error = target - guess
for n in range(3):
    weights[n] = round(weights[n] + rate * error * day[n], 2)
bias = round(bias + rate * error, 2)
print("予測:", guess, "誤差:", error)
print("重み:", weights, "バイアス:", bias)
# 新しい重みとバイアスを、4行目と5行目に写してください。
# もう一度実行します。誤差は0になりましたか。

学ぶとは重みを直すこと

学習は、重みを0にして始めます。行ごとに、パーセプトロンが予測します。誤差は、本当の答えから予測を引いたもので、1、0、-1 のどれかです。

各重みは、学習率 × 誤差 × その入力だけ動きます。すべての行を1回通すのがエポックです。決めた回数のエポックが終わるか、1エポックでほとんど何も変わらなくなったら、学習を止めます。

1年分でパーセプトロンを学ばせる

コマンド
docker exec jupyter python3 steps/perceptron.py

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

1本の直線では足りないことがある

パーセプトロンは、入力を1本のまっすぐな境界で分けます。そのように分けられない形もあります。

よく知られた例が XOR です。2つの入力のうち、ちょうど片方だけが1のときに答えが1になります。1の2行を片側に、0の2行を反対側に置く直線は、1本では引けません。下のノートブックのセルで試します。

例: XORの4行

1つ目の入力2つ目の入力答え
000
011
101
110

学生が入力するセルは、このプレビューでは空白です。

ノートブックに入力: AND、OR、XOR

コード: python
from sklearn.linear_model import Perceptron
from sklearn.neural_network import MLPClassifier

X = [[0, 0], [0, 1], [1, 0], [1, 1]]
# 同じ4つの入力に、3通りの答えをつけます。
for name, y in [["AND", [0, 0, 0, 1]], ["OR", [0, 1, 1, 1]], ["XOR", [0, 1, 1, 0]]]:
    print(name, Perceptron(random_state=0).fit(X, y).score(X, y))
# 隠れ層にニューロンを4つ置きます。
net = MLPClassifier(hidden_layer_sizes=(4,), solver="lbfgs", max_iter=1000, random_state=1).fit(X, [0, 1, 1, 0])
print(net.score(X, [0, 1, 1, 0]))

層と、たくさんの小さな直し

隠れ層は、入力と答えのあいだに並ぶニューロンの列です。それぞれが自分の境界を引き、最後のニューロンがそれらを組み合わせます。XOR はこうして解けます。

ネットワークは、かくっと切りかわる決め方ではなく、なめらかな決め方を使います。だから、誤差が減る向きへ、各重みを少しずつ動かせます。誤差は答えの側から各層へ送り返されます。これを誤差逆伝播法と呼びます。

3つの大きさのネットワーク

コマンド
docker exec jupyter python3 steps/network.py

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

ネットワークは大きいほどよいと考えがちです。ここでは隠れユニットが2つでも8つでも32でも、どれも 0.87 でした。3つの入力の形が単純だからです。ニューロンを増やすと時間がかかり、ノイズまで学ぶことがあります。小さく始め、テストデータで効くとわかったときだけ大きくします。

さらに挑戦: 学習率を変える

ノートブックで、perceptron.py のパーセプトロンを3つの学習率で学ばせてください。eta0=0.01、eta0=1、eta0=10 を使い、回数と正解率を毎回書きとめます。

そのうえで、学習率がモデルによって大事だったりそうでなかったりする理由を、二文で説明しましょう。ヒント: 重みとバイアスをすべて同じ数でかけると、決め方はどうなりますか。

このラボとソースについて: JupyterLab データサイエンスラボ:pandas、Matplotlib、scikit-learn をブラウザーで

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。