kaeken(嘉永島健司)のTech探究ブログ

主に情報科学/情報技術全般に関する知見をポストします。(最近は、特にData Science、機械学習、深層学習、統計学、Python、数学、ビッグデータ)

『Pythonからはじめる数学入門』4章 SymPyで代数と式を計算する

f:id:kaeken:20171203090308p:plainPythonからはじめる数学入門』

4章 SymPyで代数と式を計算する

の解説です。

いままでは、数値計算でしたが、

xやyといった代数においては、

式の計算(symbolic math)が必要です。

Pythonでは、SymPyを使って式の計算をおこないます。

以下は、SymPyのリファレンスです。

SymPy

また、ブラウザ上で、SymPyの動作を確認できます。

SymPy Live

表示された数式を右クリックすると、Tex記法などに変換できます。

f:id:kaeken:20171203090224p:plain f:id:kaeken:20171203090308p:plain

4.1 式の記号と記号演算を定義する

SymPyでは、以下のとおり、記号を使って数式を表現します。

from sympy import Symbol
x = Symbol('x') #文字列xを用いてSymbolクラスのオブジェクトを作成
print(x + x + 1)

from sympy import symbols
x,y,z = symbols('x,y,z')
print((x+2)*(y+3)*(z+4))

結果

2*x + 1
(x + 2)*(y + 3)*(z + 4)

4.2 式を扱う

4.2.1 式の因数分解と展開

因数分解はfactor()を使い、展開はexpand()を使います。

from sympy import symbols
x,y = symbols('x,y')

from sympy import factor, expand
expr = x**2 - y**2

factors = factor(expr)
print('factors:{0}'.format(factors))

expand_result = expand(factors)
print('expand:{0}'.format(expand_result))

結果

factors:(x - y)*(x + y)
expand:x**2 - y**2

4.2.2 プリティプリント

式をみやすく出力したい場合は、pprint()を使います。

expr = x*x + 2*x*y + y*y
print('expr:{0}'.format(expr))

from sympy import pprint
pprint(expr, use_unicode=True)

結果

expr:x**2 + 2*x*y + y**2
 2            2
x  + 2⋅x⋅y + y 

4.2.3 値に代入する

式に値を代入するには、subs()を使います。

from sympy import symbols
x,y = symbols('x,y')
expr = x*x + x*y + x*y + y*y
res = expr.subs({x:1, y:2})
print(res)

結果

9

項の中の記号を別の式で表すこともできます。

from sympy import symbols
x,y = symbols('x,y')
expr = x*x + x*y + x*y + y*y
res = expr.subs({x:y-1})
print(res)

結果

y**2 + 2*y*(y - 1) + (y - 1)**2

4.2.4 文字列を数式に変換する

input()で入力された文字列を数式に変換する方法です。

from sympy import sympify
expr = input('input: ')
input: (入力した式)y**2 + 2*y*(y - 1) + (y - 1)**2
expr =sympify(expr)
print(2*expr)

結果

2*x**3 + 2*x**2 + 10*x

4.3 方程式を解く

4.3.1 2次方程式を解く

4.3.2 1変数を他の変数について解く

4.3.3 連立方程式を解く

4.4 SymPyを使ってプロットする

4.4.1 ユーザが入力した式をプロットする

4.4.2 複数の関数をプロットする

『Pythonからはじめる数学入門』3章 データを統計量で記述する

f:id:kaeken:20171203085006p:plainPythonからはじめる数学入門』

3章 データを統計量で記述する

の解説です。

機械学習では、

統計がよく出てくるので、

ここでは、統計の基本をPythonで学びます。

3.1 平均を求める

まずは、平均値を求める関数です。

def calculate_mean(numbers):
  s = sum(numbers) #合計
  N = len(numbers) #要素数
  mean = s/N #平均
  
  return mean

if __name__ == '__main__':
  datalist = [100,60,70,900,100,200,500,500,503,600,1000,1200]
  mean = calculate_mean(datalist)
  N = len(datalist)
  print('要素数:{0}, 平均:{1}'.format(N, mean))

結果

要素数:12, 平均:477

3.2 中央値を求める

昇順にならべたリストの中央の要素が中央値です(リストが偶数個なら中央2要素の平均)。

中央値を求める関数です。

def calculate_median(numbers): #中央値計算
  N = len(numbers) #要素数
  numbers.sort() #昇順に並び替え
  
  if N % 2 == 0:
    m1 = int(N/2) - 1 # 整数に変換して位置合わせ
    m2 = int((N/2) + 1) -1
    median = (numbers[m1] + numbers[m2])/2
  else:
    m = (N+1)/2
    m = int(m) - 1
    median = numbers[m]
  
  return median

if __name__ == '__main__':
  datalist = [100,60,70,900,100,200,500,500,503,600,1000,1200]
  median = calculate_median(datalist)
  N = len(datalist)
  print('N:{0}, 中央値:{1}'.format(N, median))
  datalist.sort()
  print(datalist)

結果

N:12, 中央値:500
[60, 70, 100, 100, 200, 500, 500, 503, 600, 900, 1000, 1200]

3.3 最頻値を求め度数分布表を作る

最頻値は、もっとも多く出現する値です。

3.3.1 一番多い要素を見つける

要素の個数が多い順にリストを返すmost_common()を使います。

datalist = [4,2,1,2,3,4,2]
from collections import Counter
c = Counter(datalist)
print(c.most_common()) #要素の個数が多い順に表示
print(c.most_common(2)) #上位2番目までの要素のみ表示

結果

[(2, 3), (4, 2), (1, 1), (3, 1)]
[(2, 3), (4, 2)]

3.3.2 最頻値を探す

最頻値を返す関数です。

from collections import Counter

def calculate_mode(numbers):
  c = Counter(numbers)
  mode = c.most_common(1)
  return mode[0][0]

if __name__ == '__main__':
  scores = [7,8,6,7,5,3,3,3,5,6,1,9,1,1,2,4,0,2,3,5,2]
  mode = calculate_mode(scores)
  print('最頻値:{0}'.format(mode))

結果

最頻値:3

3.3.3 度数分布表を作る

数のリストの度数分布表の求め方です。

from collections import Counter

def frequency_table(numbers):
  table = Counter(numbers)
  print('Number | Frequency')
  for number in table.most_common():
    print('{0} | {1}'.format(number[0], number[1]))

if __name__ == '__main__':
  scores = [7,8,6,7,5,3,3,3,5,6,1,9,1,1,2,4,0,2,3,5,2]
  mode = frequency_table(scores)

結果

Number | Frequency
3 | 4
1 | 3
2 | 3
5 | 3
6 | 2
7 | 2
0 | 1
4 | 1
8 | 1
9 | 1

3.4 散らばりを測る

散らばり(dispersion)とは、 データセットで数がどれだけ 平均から離れているかの統計値です。

3.4.1 数集合の範囲を決める

数集合の範囲を求める処理です。

def find_range(numbers):
  lowest = min(numbers)
  highest = max(numbers)
  r = highest - lowest
  return lowest, highest, r

if __name__ == '__main__':
  dataset = [100,60,70,900,100,200,500,500,503,600,1000,1200]
  lowest, highest, r = find_range(dataset)
  print('Lowest:{0} Highest:{1} Range:{2}'.format(lowest, highest, r))

結果

Lowest:60 Highest:1200 Range:1140

3.4.2 分散と標準偏差を求める

分散(variance)とは、値の散らばり度合いです。

分散が大きければ、値が平均から大きく離れて、小さければ、値が平均近くにかたまっています。

def calculate_mean(numbers):
  s = sum(numbers) #合計
  N = len(numbers) #要素数
  mean = s/N #平均
  
  return mean

def find_differences(numbers):
  mean = calculate_mean(numbers)
  diff = []
  
  for num in numbers:
    diff.append(num - mean)
  return diff

def calculate_variance(numbers): #分散
  diff = find_differences(numbers)
  squared_diff = []
  for d in diff:
    squared_diff.append(d**2)
  sum_squared_diff = sum(squared_diff)
  variance = sum_squared_diff / len(numbers)
  return variance

if __name__ == '__main__':
  datalist = [100,60,70,900,100,200,500,500,503,600,1000,1200]
  variance = calculate_variance(datalist) #分散
  print('variance:{0}'.format(variance))
  
  std = variance**0.5 #標準偏差
  print('std:{0}'.format(std))

結果

variance:141047
std:375.562245174

3.5 2つのデータセットの相関を計算する

相関とは、2つのデータセットの関係性です。

相関係数とは、線形的な関係性を-1から1の範囲で示す統計量です。非線形関係については、別の測度が必要です。

相関係数0:線形相関がない

相関係数+1:強い正の線形相関がある

相関係数−1:強い負の線形相関がある

3.5.1 相関係数を計算する

相関係数を計算するためには、2つのデータセットの対応する要素の対を返すzip()関数を使います。

dataset1 = [1,2,3]
dataset2 = [4,5,6]
for x, y in zip(dataset1,dataset2):
  print(x,y)

結果

(1, 4)
(2, 5)
(3, 6)

相関係数の計算式は、以下を参照してください。

相関係数 - Wikipedia

相関係数を求める処理は以下の通りです。

def find_corr_x_y(x,y):
  n = len(x)
  prod = []
  for xi,yi in zip(x,y):
    prod.append(xi*yi)
  sum_prod_x_y = sum(prod)
  sum_x = sum(x)
  sum_y = sum(y)
  squared_sum_x = sum_x**2
  squared_sum_y = sum_y**2
  x_square = []
  for xi in x:
    x_square.append(xi**2)
  x_square_sum = sum(x_square)
  y_square = []
  for yi in y:
    y_square.append(yi**2)
  y_square_sum = sum(y_square)
  
  numerator = n*sum_prod_x_y - sum_x*sum_y
  denominator_term1 = n*x_square_sum - squared_sum_x
  denominator_term2 = n*y_square_sum - squared_sum_y
  denominator = (denominator_term1*denominator_term2)**0.5
  correlation = numerator/denominator
  
  return correlation

if __name__ == '__main__':
  data1 = [1,2,3]
  data2 = [1,2,3]
  corr = find_corr_x_y(data1,data2)
  print('data1 data2 correlation:{0}'.format(corr))

  data3 = [1,2,3]
  data4 = [3,2,1]
  corr = find_corr_x_y(data3,data4)
  print('data3 data4 correlation:{0}'.format(corr))

  data5 = [-93831,29999,8188]
  data6 = [-1,-2,1]
  corr = find_corr_x_y(data5,data6)
  print('data5 data6 correlation:{0}'.format(corr))

結果

data1 data2 correlation:1.0
data3 data4 correlation:-1.0
data5 data6 correlation:0.0243875472264

3.5.2 高校の成績と大学入試の点数

2つのデータセットのプロットを散布図で表現すれば、ビジュアルで理解できます。

3.6 散布図

散布図は以下のように表示します。

x = [10,20,30,40]
y = [20,40,60,80]
import matplotlib.pyplot as plt
plt.scatter(x,y)
plt.show()

f:id:kaeken:20171203081027p:plain

『Pythonからはじめる数学入門』2章 データをグラフで可視化する

Pythonからはじめる数学入門』

2章 データをグラフで可視化する

の解説です。 www.oreilly.co.jp

f:id:kaeken:20171201232820p:plain 機械学習で数値データを提示する際には、

グラフを用いることが多いです。

今回は、

Pythonでグラフを使う方法についてご説明します。

2章 データをグラフで可視化する

2.1 デカルト座標平面を理解する

デカルト座標平面とは、いわゆるx-y平面のことです。

高校数学で出てくるので、用語のみ記載します。

座標coordinates
原点origin
集合set
プロットplot
グラフgraph

2.2 リストとタプルの操作

リスト:可変的な要素のかたまり(あとで変更できる)

タプル:固定された要素のかたまり(あとで変更できない)

2.2.1 リストやタプルで繰り返す

リストやタプルはfor文で繰り返すことができます。

>>> list = [1,2,3]

>>> for item in list:
...     print(item)
...
1
2
3

>>> for index, item in enumerate(list):
...     print(index, item)
...
(0, 1)
(1, 2)
(2, 3)

2.3 matplotlibでグラフを作る

matplotlibは、Pythonのグラフ描画パッケージです。

インストール方法は、次のコマンドでインストールするか、 別途「matplotlib インストール」などで検索してみてください。

pip install matplotlib

さっそく以下のコードを打ち込んでいきますが、

#点(1,2), (2,4), (3,6)をプロット
x = [1,2,3]
y = [2,4,6]

from pylab import plot, show
plot(x, y)
show()

以下は、説明でにグラフ描画を表示するため、 コマンドラインではなく、 Jupyter Notebookを使って実行していきます。

上記の実行結果です。 f:id:kaeken:20171201221735p:plain

2.3.1 グラフで点を作る

プロットを明示する場合です。

plot(x, y, marker='o')

実行結果です。 f:id:kaeken:20171201222133p:plain

マーカーのみ表示する場合は、以下のように記載します。

plot(x, y, 'o')

f:id:kaeken:20171201222458p:plain

2.3.2 ニューヨーク市の年間平均気温をグラフ化する

複数のプロットをしていけば、データの傾向をつかめます。

nyc_temp=[53.9,56.3,56.4,53.4,54.5,55.8,56.8,55.0,55.3,54.0,56.7,56.4,57.3]
plot(nyc_temp, marker='o')

f:id:kaeken:20171201222912p:plain

x軸に年など特定の値を設定する方法です。

years = range(2000,2013)
plot(years, nyc_temp, marker='o')

f:id:kaeken:20171201223134p:plain

2.3.3 ニューヨーク市の月間気温傾向を比較する

複数のグラフを重ね合わせる方法です。

#データはダミー
y2000=[53.9,56.3,56.4,53.4,54.5,55.8,56.8,55.0,55.3,54.0,56.7,56.4]
y2006=[56.9,56.1,46.4,51.4,56.5,65.8,56.8,55.3,59.3,44.0,59.7,56.1]
y2012=[51.9,59.3,51.4,52.4,53.5,59.8,51.8,52.0,57.3,53.0,56.2,66.4]
months = range(1,13)
plot(months, y2000, months, y2006, months, y2012, marker='o')

from pylab import legend
legend([2000,2006,2012])

f:id:kaeken:20171201224222p:plain legend()で、凡例の指定ができます。

細かい引数の指定方法は、以下を参照してください。

legend and legend_handler — Matplotlib 2.1.0 documentation

2.3.4 グラフのカスタマイズ

タイトル、X軸名、Y軸名など、

他にカスタマイズする方法は、以下のとおりです。

y2000=[53.9,56.3,56.4,53.4,54.5,55.8,56.8,55.0,55.3,54.0,56.7,56.4]
y2006=[56.9,56.1,46.4,51.4,56.5,65.8,56.8,55.3,59.3,44.0,59.7,56.1]
y2012=[51.9,59.3,51.4,52.4,53.5,59.8,51.8,52.0,57.3,53.0,56.2,66.4]
months = range(1,13)
plot(months, y2000, months, y2006, months, y2012, marker='o')

from pylab import legend
legend([2000,2006,2012])

from pylab import title, xlabel, ylabel
#title
title('matplotlib title')

#xlabel
xlabel('Month')

#ylabel
ylabel('Temp')

f:id:kaeken:20171201225039p:plain

また、

axis()によって、軸の最小値、最大値を指定できます。

Y軸の最小値を0にした場合です。

y2000=[53.9,56.3,56.4,53.4,54.5,55.8,56.8,55.0,55.3,54.0,56.7,56.4]
y2006=[56.9,56.1,46.4,51.4,56.5,65.8,56.8,55.3,59.3,44.0,59.7,56.1]
y2012=[51.9,59.3,51.4,52.4,53.5,59.8,51.8,52.0,57.3,53.0,56.2,66.4]
months = range(1,13)
plot(months, y2000, months, y2006, months, y2012, marker='o')

from pylab import legend
legend([2000,2006,2012])

from pylab import title, xlabel, ylabel
title('matplotlib title')
xlabel('Month')
ylabel('Temp')

from pylab import axis
axis(ymin=0)

f:id:kaeken:20171201232626p:plain

また、

X軸の最小値・最大値、Y軸の最小値・最大値を以下の通り指定できます。

y2000=[53.9,56.3,56.4,53.4,54.5,55.8,56.8,55.0,55.3,54.0,56.7,56.4]
y2006=[56.9,56.1,46.4,51.4,56.5,65.8,56.8,55.3,59.3,44.0,59.7,56.1]
y2012=[51.9,59.3,51.4,52.4,53.5,59.8,51.8,52.0,57.3,53.0,56.2,66.4]
months = range(1,13)
plot(months, y2000, months, y2006, months, y2012, marker='o')

from pylab import legend
legend([2000,2006,2012])

from pylab import title, xlabel, ylabel
title('matplotlib title')
xlabel('Month')
ylabel('Temp')

from pylab import axis
axis([0,13,0,100])

f:id:kaeken:20171201232820p:plain

最後に、対話シェルではなく、プログラムの一部として、グラフを使う場合は、

pylabではなくpyplotを使います。

import matplotlib.pyplot as plt
def create_graph():
    x  = [1,2,3]
    y = [2,4,6]
    plt.plot(x,y)

if __name__ == '__main__':
  create_graph()

f:id:kaeken:20171201233326p:plain

2.3.5 プロットの保存

グラフを保存するには、savefig()を使います。

from pylab import plot,savefig
x = [1,2,3]
y = [2,4,6]
plot(x,y)
savefig('mygraph.png')

2.4 式をプロットする

今までのご説明は、

すでにプロットするデータがあった場合ですが、

数式からプロットする方法があります。

2.4.1 ニュートン万有引力の法則

詳細説明は省略しますが、イメージとして以下のようなグラフを描画できます。

import matplotlib.pyplot as plt

def draw_graph(x,y):
  plt.plot(x, y, marker='o')
  plt.xlabel('Distance in meters')
  plt.ylabel('Gravitational force in newtons')
  plt.title('Gravitational force and distance')
  plt.show()

def generate_F_r():
  r = range(100, 1001, 50)
  F = []
  G = 6.674*(10**-11)
  m1 = 0.5
  m2 = 1.5
  for dist in r:
    force = G*(m1*m2)/(dist**2)
    F.append(force)
  draw_graph(r, F)

if __name__=='__main__':
  generate_F_r()

f:id:kaeken:20171201234548p:plain

2.4.2 投射運動

以上、

Pythonからはじめる数学入門』2章 データをグラフで可視化する

の解説でした。

1章 数を扱う / まずは基本的な演算と数の種類を把握『Pythonからはじめる数学入門』

機械学習を学ぶ際に、Pythonでの数式表現でつまづくことがある。

そこで、

Pythonからはじめる数学入門』

をコツコツ通読&コマンドを打つことで、

数式表現に慣れていく。

まずは、

基本的な演算と数の種類を把握。

数値処理に強いPythonっぽいメソッドもある。

9. 数値と数学モジュール — Python 3.6.3 ドキュメント

1章 数を扱う
    1.1 基本数学演算
    1.2 ラベル:名前に数を割り当てる
    1.3 さまざまな種類の数
        1.3.1 分数を扱う
        1.3.2 複素数
    1.4 ユーザ入力を受け取る
        1.4.1 例外と不当入力の処理
        1.4.2 分数と複素数を入力
    1.5 数学を行うプログラムを書く
        1.5.1 整数の因数を計算する
        1.5.2 乗算表を生成する
        1.5.3 測定単位を変換する
        1.5.4 2次方程式の解を求める
    1.6 学んだこと
    1.7 プログラミングチャレンジ
        問題1-1 奇数偶数自動判別プログラム
        問題1-2 乗算表生成器の拡張
        問題1-3 単位変換プログラムの拡張
        問題1-4 分数電卓
        問題1-5 ユーザに脱出能力を与える

1章 数を扱う 1.1 基本数学演算 加算/減算/乗算/除算

>>> 3 + 2
5

>>> 3 - 2
1

>>> 3 * 2
6

>>> 3 / 2
1.5

小数点以下を除いた整数のみ返す 整除除算。負数の場合に注意。

>>> 3 // 2
1

>>> -3 // 2
-2

余りだけ返す 剰余

>>> 9 % 2
1

指数演算

>>> 2 ** 10
1024

9の平方根
>>> 9 ** (1/2)
3.0

8の立方根
>>> 8 ** (1/3)
2.0

1.2 ラベル:名前に数を割り当てる

変数のことをこの書籍だけは「ラベル」と呼ぶらしい。特殊すぎるので無視。

1.3 さまざまな種類の数

数の種類をtype()関数で表示

>>> type(3)
<class 'int'>
>>> type(3.0)
<class 'float'>

int()とfloat()で相互変換

>>> int(3.0)
3
>>> float(3)
3.0

1.3.1 分数を扱う

分数を扱うには、fractionsモジュールが必要。

9.5. fractions — 有理数 — Python 3.6.3 ドキュメント

>>> from fractions import Fraction
>>> f = Fraction(3,4)
>>> f
Fraction(3, 4)

>>> Fraction(3,4) + Fraction(3,4)
Fraction(3, 2)
>>> Fraction(3,4) + Fraction(1,4)
Fraction(1, 1)

1.3.2 複素数

Python複素数を扱う場合は、以下のように記述

3 + 2i(実部3 +虚部2)」の記述方法

>>> a = 3 + 2j
>>> type(a)
<class 'complex'>

>>> b = complex(3,2)
>>> type(b)
<class 'complex'>

>>> a + b
(6+4j)

>>> x = 2 +3j
>>> x.real //実部
2.0
>>> x.imag //虚部
3.0
>>> x.conjugate() //共役複素数
(2-3j)

>>> (x.real ** 2 + x.imag ** 2 ) ** 0.5 // 複素数の大きさ
3.605551275463989

>>> abs(x) // 複素数の大きさ
3.605551275463989

その他複素数関連はcmathモジュールにある

9.3. cmath — 複素数のための数学関数 — Python 3.6.3 ドキュメント

>>> import cmath
>>> dir(cmath)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cos', 'cosh', 'e', 'exp', 'isclose', 'isfinite', 'isinf', 'isnan', 'log', 'log10', 'phase', 'pi', 'polar', 'rect', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']

複素数を使うケースはどれくらいあるのか不明だが、

一応演算できるということを理解しておく。

データサイエンティスト(DS)になるためのスキルチェックシート

一般社団法人データサイエンティスト協会 という団体からデータサイエンティスト(以下DS)になるための目安となる スキルチェックシートが提供されている。

DSスキルチェック | Data Scientist Society Journal DSスキルチェック | Data Scientist Society Journal

概要を抜粋

活用シーン

データサイエンティストのスキルレベルを把握したいときに 就職や転職時に求められているスキルを把握したいときに 大学や職場での学習・教育内容を決めるときに

機能

スマートフォンを使って、いつでもどこでもスキルチェックを行うことができます データサイエンス力(サイエンス)・データエンジニアリング(エンジニア)・ビジネス力(ビジネス)の3領域を棟梁レベル・独り立ちレベル・見習いレベルの3レベルごとに回答できます 全国平均などから、他者との相対的なスキルレベルが確認できる結果やデータサイエンティスト協会のフォーマット(Excel形式)でダウンロードできます 過去のチェック結果を保存。いつでもオンライン上で見直すことができます

以下にPDF版がある。

http://www.datascientist.or.jp/common/docs/skillcheck.pdf

カテゴリだけ抜粋

データサイエンス力
(項目数:180)
1   統計数理基礎
2   予測
3   検定/判断
4   グルーピング
5   性質・関係性の把握
6   サンプリング
7   データ加工
8   Data visualization
9   機械学習
10  時系列分析
11  言語処理
12  画像処理
13  音声処理
14  パターン発見
16  グラフィカルモデル
17  統計数理応用
18  シミュレーション/データ同化
19  最適化


データエンジニアリング力
(項目数:119)
1   環境構築
2   データ収集
3   データ構造
4   データ蓄積
5   データ加工
6   データ共有
7   プログラミング
8   ITセキュリティ

ビジネス力
(項目数:123)
1   行動規範
2   論理的思考
3   プロセス
4   データの理解・検証
5   データ入手
6   意味合いの抽出、洞察
7   解決
8   事業に実装する
9   活動マネジメント

例えば、統計数理基礎 レベル1では、

1+4+9+16+25+36をΣを用いて表せる

といった基礎レベルから、機械学習レベル3では、

機械学習 バイアスとバリアンスの関係を理解し、モデル選定を適切に行える

といった抽象的かつ包括的な表現のチェックもある。

これは課題が具体的で取り組みやすい。

また、 データサイエンス力(以下D/sci)・データエンジニアリング(以下D/eng)・ビジネス力(以下D/biz)の3領域 レベル1-3(以下L1-L3)でクロスした表を作成して、定量的に把握してみた。

cate L1 L2 L3 all
D/sci 54 68 58 180
D/eng 39 43 37 119
D/biz 30 49 44 123
all 123 160 139 422

レベル1から取り組み、可能なかぎり、Pythonや実装レベルに落とし込んで理解する。

データを処理するスキルがなければ、人工知能は構築できない。

それでは、レベル1からスタート。

「新しい人工知能の教科書」は教科書ではなくカタログ

まずは先に人工知能の全体像を確認。

「新しい人工知能の教科書」を通読したが、この本は教科書というより知識のカタログ。

各知識の概要紹介と、参照資料をもとに、自分で深堀していく必要がある。

www.shoeisha.co.jp

【目次】
CHAPTER1 人工知能の過去と現在と未来

CHAPTER2 ルールベースとその発展型
01 ルールベース
02 知識ベース
03 エキスパートシステム
04 レコメンドエンジン

CHAPTER3 オートマトンと人工生命プログラム
01 人工生命シミュレーション
02 有限オートマトン
03 マルコフモデル
04 ステート駆動エージェント

CHAPTER4 重み付けと最適解探索
01 線形問題と非線形問題
02 回帰分析
03 重みを付けた回帰分析
04 類似度の計算

CHAPTER5 重み付けと最適化プログラム
01 グラフ理論
02 グラフ探索と最適化
03 遺伝的アルゴリズム
04 ニューラルネットワーク

CHAPTER6 統計的機械学習(確率分布とモデリング)
01 統計モデルと確率分布
02 ベイズ統計学とベイズ推定
03 MCMC法
04 HMMとベイジアンネットワーク

CHAPTER7 統計的機械学習(教師なし学習と教師あり学習)
01 教師なし学習
02 教師あり学習

CHAPTER8 強化学習と分散人工知能
01 アンサンブル学習
02 強化学習
03 転移学習
04 分散人工知能

CHAPTER9 深層学習
01 ニューラルネットワークの多層化
02 制限付きボルツマンマシン(RBM)
03 Deep Neural Network(DNN)
04 Convolution Neural Network(CNN)
05 Recurrent Neural Network(RNN)

CHAPTER10 画像や音声のパターン認識
01 パターン認識
02 特徴抽出の方法
03 画像認識
04 音声認識

CHAPTER11 自然言語処理と機械学習
01 文章の構造と理解
02 知識獲得と統計的意味論
03 構造解析
04 テキスト生成

CHAPTER12 知識表現とデータ構造
01 データベース
02 探索
03 意味ネットワークとセマンティックWeb

CHAPTER13 分散コンピューティング
01 分散コンピューティングと並列コンピューティング
02 ハードウェアからのアプローチ
03 ソフトウェアからのアプローチ
04 機械学習プラットフォームと深層学習プラットフォーム

CHAPTER14 大規模データ・IoTとのかかわり
01 肥大化するデータ
02 IoTと分散人工知能
03 脳機能の解明とロボット
04 創発システム

かなり多岐にわたる内容。広く浅く、人工知能の射程範囲の輪郭だけ把握。

こんなカタログレベルでも数学がバンバン出てくるので、1日でも早く昔のカンを取り戻す。

機械学習プロフェッショナルシリーズ一覧

機械学習プロフェッショナルシリーズというシリーズ本がある。

機械学習プロフェッショナルシリーズ | 書籍情報 | 株式会社 講談社サイエンティフィク

以下、既刊本。出版時期ごとに勝手にナンバリング。

1-1  機械学習のための確率と統計 978-4-06-152901-4
1-2 深層学習    978-4-06-152902-1
1-3 オンライン機械学習 978-4-06-152903-8
1-4 トピックモデル   978-4-06-152904-5
2-1 統計的学習理論   978-4-06-152905-2
2-2 サポートベクトルマシン   978-4-06-152906-9
2-3 確率的最適化  978-4-06-152907-6
2-4 異常検知と変化検知 978-4-06-152908-3
3-1 劣モジュラ最適化と機械学習 978-4-06-152909-0
3-2 スパース性に基づく機械学習 978-4-06-152910-6
3-3 生命情報処理における機械学習 多重検定と推定量設計 978-4-06-152911-3
4-1 ヒューマンコンピュテーションとクラウドソーシング    978-4-06-1529137
4-2 変分ベイズ学習   978-4-06-1529144
4-3 ノンパラメトリックベイズ 点過程と統計的機械学習の数理   978-4-06-1529151
4-4 グラフィカルモデル 978-4-06-1529168
5-1 バンディット問題の理論とアルゴリズム  978-4-06-152917-5
5-2 ウェブデータの機械学習   978-4-06-152918-2
5-3 データ解析におけるプライバシー保護 978-4-06-152919-9
6-1 機械学習のための連続最適化 978-4-06-152920-5
6-2 関係データ学習   978-4-06-152921-2
6-3 オンライン予測   978-4-06-152922-9
7-1 統計的因果探索   978-4-06-152925-0
7-2 画像認識    978-4-06-152912-0
7-3 深層学習による自然言語処理 978-4-06-152924-3

あまり細部にこだわらず、研究分野の概要を知る意味でも、ひととおり学習していく。

Deep Learning用語 日本語一覧

続いて、Deep Learning用語 日本語一覧。

こうして一覧にしてみると、うまく説明できない用語もあったり、スキップしたワンポイントコラム記事で言及されていた用語もあり、まだ復習が必要だ。

余談だが、最近は、だんだん人工知能視点になってきた。

「どこまでつぶれた文字を認識できるのか、歪み率をハイパーパラメータで導入できるのではないか。先行研究を要調査」

「歩いている人の数をカウントするアルバイト要員は、動的人間認識機能をもつ監視カメラで代替できるのではないか。要調査」

など自然に考えるようになってきた。

もっと専門的な分析ができるようにしていく。

アクティベーション
アフィン変換
アンサンブル学習
鞍点
閾値いきち
インセプション構造
エッジ
エポック
演算精度
オーバーフロー
重み
重み付き和
重みの初期値
カーネル
回帰問題
過学習
学習係数の減衰
学習率
確率的勾配降下法
隠れ層
荷重減衰
画像キャプション生成
画像スタイル変換
画像生成
逆伝播
強化学習
教師あり学習
教師データ
教師なし学習
局所的正規化
局所的計算
グリッドサーチ
訓練データ
計算グラフ
検証データ
交差エントロピー誤差
合成関数
高速化
恒等関数
勾配
勾配確認
勾配降下法
勾配消失
勾配上昇法
勾配法
誤差逆伝播法
再学習
最適化
サブサンプリング
シグモイド関数
指数移動平均
自動運転
出力層
出力特徴マップ
受容野
順伝播
順番付ディクショナリ
順方向伝播
乗算レイヤ
数値微分
スキップ構造
ステップ関数
ストライド
正規化
正則化
積和演算
セグメンテーション
全加算器
線形
全結合
前方差分
双曲線関数
ソフトマックス関数
損失関数
多次元配列
多層パーセプトロン
畳み込み演算
畳み込み層
畳み込みニューラルネットワーク
単純パーセプトロン
単調増加
チャンネル
中間層
中心差分
データ駆動
データ転送
デコンボリューション
テストデータ
転移学習
テンソル
特徴マップ
特徴量
ドット積
内積
入力層
入力特徴マップ
ニューロン
ネイピア数
ノード
パーセプトロン
パーセプトロンの収束定理
バイアス
バイアス補正
排他的論理和
ハイパーパラメータ
白色化
バス帯域
バッチ
パディング
半加算器
半精度浮動小数点数
非線形
非線形関数
ビッグデータ
微分
汎化能力
フィルター
フィルター演算
ブーリアン
プーリング層
物体検出
プラトー
ブロードキャスト
ブロブ
分散学習
分類問題
ベイズ最適化
ベクトル
偏微分
前処理
丸め誤差
ミニバッチ学習
ランダムサンプリング
連鎖律

Deep Learning用語一覧(英語)

『ゼロから作るDeep Learning』で深層学習を学び、自分自身の物理ニューラルネットワーク=脳を訓練中だが、一通り用語を一覧にした。

理論、実装、その他さまざまな用語が混ざっているが、これらを見ながら説明できない用語をピックアップして、本書を復習していく。

なお、Pythonの基本的な文法など、分かっているものは省いた。

まずは、英語編。

activation function
AdaGrad
Adam
AddLayer
Affine
AlexNet
ALU
AND gate
argmax()
Averageプーリング


batch
Batch Normalization

CNN
CNTK
Convolution
crop処理
cross entropy error
CUDA
cuDNN

Data Augmentation
DCGAN
Deep Belief Network
Deep Boltzman Machine
Deep Q-Network
DQN
Dropout

end-to-end

Faster R-CNN
CFN
fine tuning
flip処理
forward propagation
fully-connected

GAN
GoogLeNet
GPUコンピューティング
gradient
gradient ascent method
gradient descent method

half float
Heの初期値
HOG

identity_function()
ILSVRC
im2col
Image.fromarray()
ImageNet

KNN

L1ノルム
L2ノルム

learning rate
LeNet
load_mnist()
loss function
LRN

matrix
Maxノルム
Maxプーリング
mean squared error
MNIST
Momentum
MulLayer

nan
NAND gate
NIC
np.arange()
np.argmax()
np.array
np.dot()
np.exp()
np.int
np.maximum()
np.mdim()
np.random.choice()
np.random.randn()
np.sum()
np.zeros_like()
numerical differentiation
numerical_gradient()
N次元配列

one-hot表現
optimizer
OrderedDict
ORgate
overfitting

padding
pickle
PIL
plt.plot()
plt.show()
plt.title()
plt.xlabel()
plt.ylabel()

R-CNN
range()
relu()
ReLU関数
reshape()
ResNet
RMSProp
RNN

SegNet
SGD
SIFT
sigmoid()
SimpleConvNet
softmax()
Softmax-widh-Loss
step_function()
stochastic gradient descent
stride
SURF
SVM

tanh関数
TensorFlow
transpose
TwoLayerNet

VGG
Weight decay

Xavierの初期値
XOR gate

y.astype()

CS231n: Convolutional Neural Networks for Visual Recognition

『ゼロから作るDeep Learning』で何度も言及されていたスタンフォード大学の講義資料を参照する。

CS231n: Convolutional Neural Networks for Visual Recognition

cs231n.github.io

http://cs231n.stanford.edu/syllabus.html

英語は日常的に使っていないが、

キーワードの意味を押さえたうえで、

いったん日本語で概念をある程度把握しておけば、

比較的理解しやすい。

非常に図像が多用されたスライドが見ているだけでも面白い。

SVMなど、いわゆる既存の機械学習系のテーマは詳細不明だが、

backpropagationなどかなり共通しているので分かりやすい。

これから、『ゼロから作るDeep Learning』が参照している資料や、

よく分からなかった領域を深掘りしていくことにする。

やはり、英語圏の一次情報が多いので、分からないながらも、毎日英語で学習していくことにする。

8章 ディープラーニングDL『ゼロから作るDeep Learning』

本書の最後の8章は、現在のDLを俯瞰した説明なので、目次に合わせてメモ書き。

8章 ディープラーニング
    8.1 ネットワークをより深く
        8.1.1 よりディープなネットワークへ
        8.1.2 さらに認識精度を高めるには

これまで論文発表された手法の認識精度ランキング
http://rodrigob.github.io/are_we_there_yet/build/classification_datasets_results.html

さらに認識精度を高めるには、データ拡張などが必要。

データ拡張Data Augmentation:入力画像を回転やタテ・ヨコ方向の微小な移動などで、人工的に拡張する。

画像の一部を切り取るcrop処理や、左右反転するflip処理、輝度変更や、拡大・縮小などで増やす。

#TODO:あとで実装


        8.1.3 層を深くすることのモチベーション

層を深くするメリット:パラメータ数を少なくできる

「犬」画像をまとめて一度に学習するのは大変だが、

プリミティブな特徴を学習する浅い層から、徐々に多層化して抽象度を上げていくことができる。



    8.2 ディープラーニングの小歴史
        8.2.1 ImageNet

100万枚を超える画像データ・セット。

毎年ILSVRCという画像認識コンペティションが開催されている。

2015年のResNetは、エラー率3.5%となり、人間の認識能力を上回った。


        8.2.2 VGG
        8.2.3 GoogLeNet

「インセプション構造」と呼ばれるNNの「横方向の深さ(広がり)」を使っているのが特徴

        8.2.4 ResNet

「スキップ構造」と呼ばれる入力データの畳み込み層を跨いで出力に合算する構造をもつことで、

層を深くした際の減衰を回避している。

移転学習を行い、学習済の重みを別のNNにコピーして再学習fine tuningをさせている。

    8.3 ディープラーニングの高速化
        8.3.1 取り組むべき問題

畳み込み層の処理が一番かかっているので、大量の積和演算を以下に高速化するかが重要になっている。

        8.3.2 GPUによる高速化

もともとグラフィック処理用のGPUを使って大量の並列演算ができるので、CPUよりパフォーマンスが出る。


        8.3.3 分散学習

複数のGPUを並列で使うと、56倍の高速化が実現できた事例がある。


        8.3.4 演算精度のビット削減

通常、64bit/32bitで表現されている数値を16bitの半精度浮動小数点数half floatに落としても、問題なく学習ができるので、メモリやバス帯域の節約になる。

NVIDIAのMaxwell世代GPUでは演算自体16bitで行われていなかったが、次世代のPascalアーキテクチャでは16bitで行い、2倍の高速化が期待できる。

    8.4 ディープラーニングの実用例
        8.4.1 物体検出

物体検出には、R-CNN手法が使われる。

        8.4.2 セグメンテーション

FCN fully convolutional networkが提案されている

        8.4.3 画像キャプション生成

NIC neural image captionモデル

RNN recurrent neural network 再帰的なネットワークであり、自然言語や時系列データなど連続性のあるデータで使われる

マルチモーダル処理:画像や言語といった複数の種類の情報を組み合わせて処理


    8.5 ディープラーニングの未来
        8.5.1 画像スタイル変換

例えば、ゴッホ的なスタイルの画像に変換する

        8.5.2 画像生成

DCGAN Deep Convolutional Generative Adversarial Networkという手法で、画像が自動生成される。

GeneratorとDiscriminatorを対決させて精度を上げる


        8.5.3 自動運転

SegNet

        8.5.4 Deep Q-Network(強化学習)


強化学習reinforcement learning:エージェントが自律的によりよい報酬を目指して学習する

    8.6 まとめ

省略

これでひととおり本書を学び終えたが、まだまだ理解が十分ではないので、何度も読み返しながら、プログラミングして深く理解していく。

人工知能の領域はかなり広いので、一分野である機械学習のさらに一分野である深層学習をまずは徹底的に学び、学習領域を広げて実装につなげていく。

7章 畳み込みニューラルネットワークCNN 畳み込み層とプーリング層の実装『ゼロから作るDeep Learning』

f:id:kaeken:20161113170416p:plain

f:id:kaeken:20161113170431p:plain

7章 CNNの実装について。

畳み込み演算では、4次元データを処理する必要がある。

(batch_num, channel, hegiht, width)

そこでフィルタにとって都合の良い入力データを展開する関数im2colを使用する

def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
    """

    Parameters
    ----------
    input_data : (データ数, チャンネル, 高さ, 幅)の4次元配列からなる入力データ
    filter_h : フィルターの高さ
    filter_w : フィルターの幅
    stride : ストライド
    pad : パディング

    Returns
    -------
    col : 2次元配列
    """
    N, C, H, W = input_data.shape
    out_h = (H + 2*pad - filter_h)//stride + 1
    out_w = (W + 2*pad - filter_w)//stride + 1

    img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
    col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))

    for y in range(filter_h):
        y_max = y + stride*out_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]

    col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
    return col

実際に使ったサンプルコード

# coding: utf-8
import sys, os
sys.path.append(os.pardir)
import numpy as np
from common.util import im2col

x1 = np.random.rand(1,3,7,7)
col1 = im2col(x1,5,5,stride=1,pad=0)
print(col1.shape) #=>(9, 75)

x2 = np.random.rand(10,3,7,7)
col2 = im2col(x2,5,5,stride=1,pad=0)
print(col2.shape) #=>(90, 75)

続いてconvolution layerの順伝播と逆伝播。

class Convolution:
    def __init__(self, W, b, stride=1, pad=0):
        self.W = W
        self.b = b
        self.stride = stride
        self.pad = pad

        # 中間データ(backward時に使用)
        self.x = None
        self.col = None
        self.col_W = None

        # 重み・バイアスパラメータの勾配
        self.dW = None
        self.db = None

    def forward(self, x):
        FN, C, FH, FW = self.W.shape
        N, C, H, W = x.shape
        out_h = 1 + int((H + 2*self.pad - FH) / self.stride)
        out_w = 1 + int((W + 2*self.pad - FW) / self.stride)

        col = im2col(x, FH, FW, self.stride, self.pad)
        col_W = self.W.reshape(FN, -1).T

        out = np.dot(col, col_W) + self.b
        out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)

        self.x = x
        self.col = col
        self.col_W = col_W

        return out

    def backward(self, dout):
        FN, C, FH, FW = self.W.shape
        dout = dout.transpose(0,2,3,1).reshape(-1, FN)

        self.db = np.sum(dout, axis=0)
        self.dW = np.dot(self.col.T, dout)
        self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW)

        dcol = np.dot(dout, self.col_W.T)
        dx = col2im(dcol, self.x.shape, FH, FW, self.stride, self.pad)

        return dx

続いて、Pooling layerの順伝播と逆伝播

class Pooling:
    def __init__(self, pool_h, pool_w, stride=1, pad=0):
        self.pool_h = pool_h
        self.pool_w = pool_w
        self.stride = stride
        self.pad = pad

        self.x = None
        self.arg_max = None

    def forward(self, x):
        N, C, H, W = x.shape
        out_h = int(1 + (H - self.pool_h) / self.stride)
        out_w = int(1 + (W - self.pool_w) / self.stride)

        col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)
        col = col.reshape(-1, self.pool_h*self.pool_w)

        arg_max = np.argmax(col, axis=1)
        out = np.max(col, axis=1)
        out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)

        self.x = x
        self.arg_max = arg_max

        return out

    def backward(self, dout):
        dout = dout.transpose(0, 2, 3, 1)

        pool_size = self.pool_h * self.pool_w
        dmax = np.zeros((dout.size, pool_size))
        dmax[np.arange(self.arg_max.size), self.arg_max.flatten()] = dout.flatten()
        dmax = dmax.reshape(dout.shape + (pool_size,))

        dcol = dmax.reshape(dmax.shape[0] * dmax.shape[1] * dmax.shape[2], -1)
        dx = col2im(dcol, self.x.shape, self.pool_h, self.pool_w, self.stride, self.pad)

        return dx

続いて、CNNの可視化について。

1層目のフィルタを画像として表示。

最も小さな値は黒(0)、最も大きな値は白(255)に正規化して表示

学習前 f:id:kaeken:20161113170416p:plain

学習後 f:id:kaeken:20161113170431p:plain

「エッジedge(色が変化する境目)」や「ブロブblob(局所的に塊のある領域)」などのプリミティブな情報を抽出し、反応するフィルタであることが分かる。

階層が増えていくことで抽象度が上がり、テクスチャやパーツや対象のクラスなどに反応していくようになる。

最後に、代表的なCNNについて。

・LeNet:CNNの元祖で1998年提案された。シグモイド関数が使われ、サブサンプリングで中間データのサイズ縮小が行われる。

・AlexNet:DLブームの火付け役となったCNNで2012年に提案された。ReLU関数が使われ、LRN(Local Response Normalization)という局所的正規化を行う層を用いており、Dropoutを使用する。

また、環境的な変化として、大量データ=ビッグデータを扱える環境になり、大量の並列計算を得意とするGPUが普及すること、この2点がDL発展に寄与。

7章まとめ問題

・CNNは、既存の全結合層のNNに対して、◯◯と◯◯が加わる
・◯◯と◯◯は、◯◯関数を用いることで効率化する
・CNNの可視化で、層が深くなるにつれて◯◯が分かる
・代表的なCNNは、◯◯と◯◯である
・DL発展には、◯◯と◯◯が大きく貢献

畳み込み演算を図解するライブラリconv_arithmetic

f:id:kaeken:20161113135857p:plain

7章のCNNで畳み込み演算を図解するツールを探していたら以下を見つけた。

github.com

パディングやストライドの条件を指定できる。

texを使って記述するようだが、texはそれほど詳しくないので、必要に応じて調べておく。

文章や数式だけでは理解しづらい場合は、図解することで理解を促す。

7章 畳み込みニューラルネットワーク 畳み込み層Convolution layerとプーリング層Pooling layer『ゼロから作るDeep Learning』

f:id:kaeken:20161113135225g:plain

さて、いよいよ畳み込みニューラルネットワークConvolution Neural Network, CNNまで来た。

最新の画像認識・音声認識でほぼ使われているCNNをじっくり理解していく。

CNNでは、今までのレイヤに、

畳み込み層Convolution layer

プーリング層Pooling layer

の2つを追加する。プーリング層は省略されることがある。

今までのNNでは、全結合層Affine layer

で隣接する層のすべてのニューロン同士が結合されていた。

全結合層の問題点として、

データの空間的情報が消えてしまう問題がある。

具体的には、MNISTデータ・セットのように、

入力画像の3次元構造(チャンネル、縦、横)が、

1次元構造にされてAffine layerに入力される。

空間的に近接したピクセル同士の関係情報が消えてしまう。

ここで、

畳み込み層Convolution layerを使えば、空間情報が維持される。

なお、

畳み込み層の入出力データを特徴マップfeature mapとも言う。

入力特徴マップinput feature map

出力特徴マップoutput feature map

続いて、畳み込み演算(画像処理ではフィルター演算)について。

畳み込み演算は、縦・横の形状をした入力データに対して、フィルターを適用する。

以下、(height, width)として、フィルタのウィンドウを一定間隔で移動させながら、積和演算を行い、対応する出力場所へ格納する。

入力データ:(4,4)
1230
0123
3012
2301

フィルターサイズ:(3,3)
201
012
102

出力サイズ:(2,2)
  1x2 + 0x0 + 3x1
+ 2x0 + 1x1 + 0x0
+ 3x1 + 2x2 + 1x2
= 15→出力左上
以下同様
15 16
 6 15

イメージ図のとおり、入力データにフィルタをスライドさせながら積和演算し出力する。

f:id:kaeken:20161113135225g:plain

畳み込み演算のフィルタは、重みに相当し、(1,1)のバイアスも付加してデータを出力する。

また、

パディングpaddingとは、畳み込み演算前に入力データの周囲に固定データ(0など)を埋める処理。

パディングを使う理由は、出力サイズが1になって演算が適用できなくならないように調整するため。

例えば、入力データ(5,5)に幅1のパディングを適用すると、

入力データが(7,7)に変わり、

(5,5)フィルタをかけると以下のとおり、スライド位置が増えて、(5,5)の出力となる。

f:id:kaeken:20161113135257g:plain

続いて、ストライドについて。

ストライドstrideとは、フィルタを適用する位置間隔。

今までの説明ではストライド1だったが、ストライド2にすると、ウィンドウが2要素ごと移動する。

f:id:kaeken:20161113135455g:plain

ストライドを大きくすると、出力サイズは小さくなり、

パディングを大きくすると、出力サイズは大きくなる。

以下関係式。

入力サイズ(H,W)
フィルタサイズ(FH,FW)
出力サイズ(OH,OW)
パディングP
ストライドS

OH(OW) = 1 + { H(W) + 2P - FH(FW) } / 2

※HとWは読み替える
※H(W) + 2P - FH(FW) の値は割り切れるように設定する

次に、3次元畳み込み演算について。

3次元畳み込み演算:2次元にチャンネルを追加したデータの畳み込み演算

(channel, height, width)

※必ず、入力データのチャンネル数とフィルタのチャンネル数は一致させる必要がある。

フィルタが複数個ある場合は、output_channelを追加した4次元データにする。

(output_channel, input_channel, height, width)

バッチ処理の場合も、バッチ数を追加した4次元データにする。

(batch_num, input_channel, height, width)

最後に、プーリング層について。

プーリングpoolingとは、縦・横方向の空間を小さくする演算。

(2,2)サイズ領域を、一定のルールで(1,1)サイズにするなど。

Maxプーリング:対象領域の最大値を残して集約する手法。(以下ではプーリング=Maxプーリングとする)

Averageプーリング:対象領域の平均を算出する手法。

プーリング層の特徴3つ

1.学習するパラメータがない

2.チャンネル数は変化しない

3.微小な位置変化に対してロバスト(必ずしも保証されない)

以上、Convolution / Poolingレイヤの説明で、

次は、実装に入る。