<jupyter_start><jupyter_text>NICO2AI 第5回 勾配法と誤差逆伝搬法 (7/15) 基礎演習 到達目標- 基本的な勾配降下法のアルゴリズムを理解する- ロジスティック回帰における勾配法を実装できる- フィードフォワードニューラルネットワーク及び誤差逆伝播法の仕組みを理解する- 誤差逆伝播法の実装を体験する キーワード- 勾配降下法- クロスエントロピー誤差- フィードフォワードニューラルネットワーク- 誤差逆伝播法- 確率的勾配降下法 (SGD)` CODE HERE ` と記載されている部分にコードを埋めていく<jupyter_code>%matplotlib inline
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from IPython.display import display, clear_output
import seaborn as sns

sns.set_style('ticks')<jupyter_output><empty_output><jupyter_text>つくってみよう1課題: 線形モデルの二乗誤差最小化を解析解と勾配法の2つで実装する※1 データは以下の式から生成する$$y = Xw + \epsilon \\X_{ij}, w_i \sim \mathcal{N} (0.0, 1.0) \\\epsilon_i \sim \mathcal{N} (0.0, 4.0)$$※2 データ数N: 100, 次元数D: 20<jupyter_code>## データの生成

np.random.seed(111)
N = 100
D = 20
X = np.random.normal(loc=0.0, scale=1.0, size=N*D).reshape(N, D)
w = np.random.normal(loc=0.0, scale=1.0, size=D)
y = X.dot(w) + np.random.normal(loc=0.0, scale=2.0, size=N)
## 解析解による解の導出
w_ls = ### CODE HERE ###
## 勾配法を用いた解の導出
T = 100
eta = 0.01
w_gd = np.random.normal(loc=0.0, scale=0.1, size=D)
for t in range(T):
  print('\r[{}/{}]'.format(t, T), end='')
  w_gd = ### CODE HERE ###
## エラーチェック

assert w_ls.shape == (D,), 'w_ls.shape must be {}. result: {}'.format((D,), w_ls.shape)
assert w_gd.shape == (D,), 'w_gd.shape must be {}. result: {}'.format((D,), w_gd.shape)
## 解析解と勾配法の結果の比較

y_ls = X.dot(w_ls)
y_gd = X.dot(w_gd)

fig = plt.figure(figsize=(4,4))
plt.plot([-15, 15], [-15, 15], '--', color='gray')
plt.plot(y, y_ls, 'o', label='Least Square')
plt.plot(y, y_gd, '.', label='Gradient Descent')

plt.legend()
plt.xlabel('$y$')
plt.ylabel('$\hat{y}$')<jupyter_output><empty_output><jupyter_text>つくってみよう2課題1. シグモイド関数 $\sigma(z)$ を実装する2. クロスエントロピー誤差関数 $\mathrm{H}(y, a)$ を実装する3. 1次元のロジスティック回帰モデルのクロスエントロピー誤差最小化を勾配法で実装する<jupyter_code>## シグモイド関数の実装
def sigmoid(z):
  return ### CODE HERE ###
## エラーチェック

result = sigmoid(np.random.normal(size=80).reshape(2, 40))
assert result.shape == (2, 40), \
  'crossentropy(d, y).shape must be as same as y.shape. result: {}'.format(result.shape)
## シグモイド関数の確認
fig = plt.figure(figsize=(4,3))
z = np.linspace(-5, 5, 100)
plt.plot(z, sigmoid(z), color='black')
plt.xlabel('$z$')
plt.ylabel('$\sigma(z)$')
## クロスエントロピー誤差の実装
def crossentropy(d, y):
  epsilon = 1e-8
  y = np.clip(y, epsilon, 1-epsilon)
  return ### CODE HERE ###
## エラーチェック

result = crossentropy(0.7, np.random.normal(size=80).reshape(2, 40))
assert result.shape == (2, 40), \
  'crossentropy(d, y).shape must be as same as y.shape. result: {}'.format(result.shape)
## クロスエントロピー誤差の確認
fig = plt.figure(figsize=(5, 3))
d = 0.7
y = np.linspace(0.0, 1.0, 100)
plt.plot(y, crossentropy(d, y), color='black')
plt.plot([0.7, 0.7], [0, 15], '--', color='gray')
plt.text(0.4, 6, '$p(d=1)=0.7$')
plt.ylim(0, 10)
plt.xlabel('$q(x=1)$')
plt.ylabel('Cross entropy')
## データの生成
np.random.seed(111)
N = 100
w = 3.0
x = np.random.normal(loc=0.0, scale=2.0, size=N)
d = np.array([sigmoid(w*x) >= np.random.uniform(size=N)], dtype=int).flatten()
p_true = sigmoid(w*np.linspace(-6, 6, 100))
## 勾配法を用いた解の導出
T = 100
eta = 0.01
w_gd = 0.0
for t in range(T):
  print('\r[{}/{}]'.format(t, T), end='')
  y = ### CODE HERE ###
  w_gd = ### CODE HERE ###
## エラーチェック

assert y.shape == (N,), 'w_gd.shape must be {}. result: {}'.format((N,), y.shape)
assert w_gd.shape == (), 'w_gd.shape must be {}. result: {}'.format((), w_gd.shape)
## 推定結果の確認
p_hat = sigmoid(w_gd*np.linspace(-6, 6, 100))

plt.figure(figsize=(6, 4))
plt.plot(x, d, 'o', label='Observation')
plt.plot(np.linspace(-6, 6, 100), p_true, label='True ($w={:.2f}$)'.format(w))
plt.plot(np.linspace(-6, 6, 100), p_hat, label='Estimated ($w={:.2f}$)'.format(w_gd))
plt.legend(loc='upper left')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.21862456515921863, 'fraction_numerical': 0.04468825260904469, 'mean_word_length': 5.078048780487805, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '634325', 'license': 'MIT', 'n_tokens_mistral': 2142, 'n_tokens_neox': 2055, 'n_words': 332, 'path': 'lecture5/nico2ai_lecture5_exercise.ipynb', 'repo_name': 'wbap/NICO2AI_basic_2018', 'size': '3737'}