おひとりさま現役パラレルワーカーフクコろぐ

これからの会社員は、複数の収入源をもとう! 会社に翻弄されずアナタらしく仕事ができる。 そんなパラレルワーカーを広めるフクコのブログです。

【文系プログラミング初心者deE資格】ゼロつくディープラーニング #12

f:id:fukuko-parallel-work:20211111205751j:plain


こんにちは!

現役パラレルワーカー フクコです。

f:id:fukuko-parallel-work:20210212204833p:plain



前回の記事↓に続き

www.fukuko-parallel-work.com



来年の2月の試験に向けてE資格試験勉強中のため


ゼロつくシリーズでおなじみ

オーライリーから出版されている

ディープラーニングの本格的な入門書でよくおススメされる

「ゼロからつくる Deep Learning」本


f:id:fukuko-parallel-work:20211029220008j:plain




この本↑を毎日5ページずつコツコツこなす

約2か月間で今年中に終了するので

来年のE資格試験までにこれで基礎力をつけることにしました。(^^)


ついつい私は何もないとだらけてしまうので(笑)

毎日5ページ終わった後の記録とまとめを書いていこうと思います。


と、まとめに入る前に…

やる気を出すためのコトバをシェアします!!(主に私のやる気を出すために 笑)



「怒れ。 
  許せないという強く純粋な怒りは、
  手足を動かすための揺るぎない原動力になる。」

by 富岡義勇



おなじみ私の大好きな鬼滅の刃から(笑)

水柱・富岡義勇の名言です。


な~んでアメリカに合わせて、私が遅くまでよなよな仕事をしないといけないんだ!

お前たちが合わせろ!

私は夜はプログラミング勉強で忙しいのだ!でも絶対毎日のノルマはこなしてやる!


うーむ、ちょっとテンション違いますかね。。笑


でも、なんかちょっとスッキリ。(^0^)


義勇さん、どうもありがとう! (ナゼか義勇さんは、さんをつけたくなります 笑)

今日もやる気が出てきましたよ! 

よし!! 今日も頑張るぞ~! お~!! 

というコトで、今日も粛々と私はノルマをこなしますよ! 笑


ではでは、いい加減まとめに入ります。笑



その前に本の目次の紹介です。

ゼロつくディープラーニングは、下記↓の合計8章で構成されています。

本の目次

  • 5章 誤差伝播法
  • 6章 学習に関するテクニック


ちなみに…

ゼロつくディープラーニング第1章はPython入門のセクション(20ページ分)なので、

とりあえず今回私は飛ばし、第2章からまとめています。

今回も第4章のつづきからでーす。


第4章 ニューラルネットワークの学習つづき


ニューラルネットワークの学習とは、

訓練データから最適な重みパラメータの値を自動で獲得するようにできるコト

4.3.3 偏微分


つづいて

変数の2つある↓の関数についてみていく。


{ \displaystyle f(x₀ ,x₁) = {x₀^2} +  {x₁^2}}


コレをPythonで実装をすると↓のようになる。

def function_2(x):
    return x[0]**2 + x[1]**2
    #この式でも同じ結果ー> return np.sum(x**2)


この式は、変数が2つある。


そして、

2つ以上の複数の変数からなる関数の微分を、

偏微分という。


偏微分を式にすると…


{ \displaystyle\dfrac{\partial f}{\partial x₀}}

{ \displaystyle\dfrac{\partial f}{\partial x₁}}

のように書く。


x₀=3,x₁=4のときの偏微分{ \displaystyle\dfrac{\partial f}{\partial x₀}}は??

コレをPythonで解くと↓のようになる。

def function_tmp1(x0):
    return x0*x0 + 4.0**2.0

numerical_diff(function_tmp1, 3.0)#答えは、6.00000000000378

x₀=3,x₁=4のときの偏微分{ \displaystyle\dfrac{\partial f}{\partial x₁}}は??

コレをPythonで解くと↓のようになる。

def function_tmp2(x1):
    return 3.0**2.0 + x1*x1

numerical_diff(function_tmp2, 4.0)#答えは、7.999999999999119
4.4 勾配


では

x₀ ,x₁の偏微分をまとめて計算するには、どうすればいいのか?

({ \displaystyle\dfrac{\partial f}{\partial x₀}}, { \displaystyle\dfrac{\partial f}{\partial x₁}})として計算すればイイ。


({ \displaystyle\dfrac{\partial f}{\partial x₀}}, { \displaystyle\dfrac{\partial f}{\partial x₁}})のように

全ての変数の偏微分をベクトルとしてまとめたものを、

「勾配」(gradient)という。


コレをPythonで実装すると↓のようになる。

import numpy as np#おきまりNumPyのインポート

def numerical_gradient (f, x):
    h = 1e-4#0.0001
    grad = np.zeros_like(x)#xと同じ形状の配列を生成,np.zeros_likeはその要素がすべて0の配列を生成  
    
    for idx in range (x.size):
        tmp_val = x[idx]
        #f(x+h)の計算
        x[idx] = tmp_val + h
        fxh1 = f(x)
        
        #f(x-h)の計算
        x[idx] = tmp_val - h
        fxh2 = f(x)
        
        grad[idx] = tmp_val#値を元に戻す
    
    return grad

実際に勾配を、

↑の式を使ってPythonで計算してみる

例えば、

点(0,2)の場合

numerical_gradient(function_2, np.array([0.0, 2.0]))#こたえは、array([0., 2.])


わかりやすいように

勾配の結果にマイナスをつけたベクトル描画をしてみる。

コレをPythonで実装をすると↓のようになる。

#ライブラリインポート
# coding: utf-8
# cf.http://d.hatena.ne.jp/white_wheels/20100327/p3
import numpy as np
import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D

def _numerical_gradient_no_batch(f, x):
    h = 1e-4  # 0.0001
    grad = np.zeros_like(x)
    
    for idx in range(x.size):
        tmp_val = x[idx]
        x[idx] = float(tmp_val) + h
        fxh1 = f(x)  # f(x+h)
        
        x[idx] = tmp_val - h 
        fxh2 = f(x)  # f(x-h)
        grad[idx] = (fxh1 - fxh2) / (2*h)
        
        x[idx] = tmp_val  # 値を元に戻す
        
    return grad

def numerical_gradient(f, X):
    if X.ndim == 1:
        return _numerical_gradient_no_batch(f, X)
    else:
        grad = np.zeros_like(X)
        
        for idx, x in enumerate(X):
            grad[idx] = _numerical_gradient_no_batch(f, x)
        
        return grad

def function_2(x):
    if x.ndim == 1:
        return np.sum(x**2)
    else:
        return np.sum(x**2, axis=1)

def tangent_line(f, x):
    d = numerical_gradient(f, x)
    print(d)
    y = f(x) - d*x
    return lambda t: d*t + y

if __name__ == '__main__':
    x0 = np.arange(-2, 2.5, 0.25)
    x1 = np.arange(-2, 2.5, 0.25)
    X, Y = np.meshgrid(x0, x1)
    
    X = X.flatten()
    Y = Y.flatten()

    grad = numerical_gradient(function_2, np.array([X, Y]).T).T

    plt.figure()
    plt.quiver(X, Y, -grad[0], -grad[1],  angles="xy",color="#666666")
    plt.xlim([-2, 2])
    plt.ylim([-2, 2])
    plt.xlabel('x0')
    plt.ylabel('x1')
    plt.grid()
    plt.draw()
    plt.show()

で、出てきた描画が↓の図。


f:id:fukuko-parallel-work:20211111223248j:plain


↑の描画が示すように


「勾配」が示す方向は

各場所において関数の値を最も減らす方向となる。

コレは重要なポイント!



今日のまとめ


ハイ、今日はここまで!!

ということで、第4章はまだまだつづきます!

引き続き頑張りまっす。


最後まで読んでくださり、ありがとうございます!

フクコ


ディープラーニング入門書おススメ本