#わからないこと
「達人データサイエンティストによる理論と実践 Python 機械学習プログラミング第二版」という本でパーセプトロンについて勉強しています。ここ(2.2.1 オブジェクト指向のパーセプトロンAPI、p24~)で、パーセプトロンを実装するときに重みの初期値を0とせず、正規分布に基づく小さな乱数で初期化しています。
Python
1import numpy as np 2class Perceptron(object): 3 """パーセプトロンの分類器 4 5 パラメータ 6 -------------------- 7 eta : float 8 学習率(0.0より大きく0.1以下の値) 9 n_iter : int 10 トレーニングデータのトレーニング回数 11 random_state : int 12 重みと初期化するための乱数シード 13 14 属性 15 -------------------- 16 w_ : 1次元配列 17 適合後の重み 18 errors_ : リスト 19 各エポックでの誤分類(更新)の数 20 21 """ 22 def __init__(self, eta=0.01, n_iter=50, random_state=1): 23 self.eta = eta 24 self.n_iter = n_iter 25 self.random_state = random_state 26 27 def fit(self, X, y): 28 """トレーニングデータに適合させる 29 30 パラメータ 31 -------------------- 32 X : {配列のようなデータ構造}, shape = [n_samples, n_features] 33 トレーニングデータ 34 n_samplesはサンプルの個数、n_featuresは特徴量の個数 35 y : 配列のようなデータ構造, shape = [n_samples] 36 目的変数 37 38 戻り値 39 -------------------- 40 self : object 41 42 """ 43 rgen = np.random.RandomState(self.random_state) 44 """ 45 重みを平均0、標準偏差0.1の正規分布に従う乱数で初期化 46 """ 47 self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1]) 48 self.errors_ = [] 49 50 for _ in range(self.n_iter): # トレーニング回数分トレーニングデータを反復 51 errors = 0 52 for xi, target in zip(X, y): # 各サンプルで重みを更新 53 update = self.eta * (target - self.predict(xi)) 54 self.w_[1:] += update * xi 55 self.w_[0] += update 56 errors += int(update != 0.0) 57 # 反復回数ごとの誤差を格納 58 self.errors_.append(errors) 59 return self 60 61 def net_input(self, X): 62 """総入力を計算""" 63 return np.dot(X, self.w_[1:]) + self.w_[0] 64 65 def predict(self, X): 66 """1ステップ後のクラスラベルを返す""" 67 return np.where(self.net_input(X) >= 0.0, 1, -1)
ここで、重みを0に初期化しない理由として、以下のように書いています。(p26, 27)
次に、重みを0に初期化していないのは、重みが0以外の値に初期化された場合にのみ、学習率η(eta)が分類の結果に影響を与えるからである。すべての重みが0に初期化された場合、学習率etaの影響を受けるのは、重みベクトルの(向きではなく)大きさだけとなる。三角法に詳しい場合はv1=[1 2 3]について考えてみよう。次のコードに示されているように、v1とベクトルv2=0.5 × v1の角度はちょうど0になる。
Python
1>>> v1 = np.array([1, 2, 3]) 2>>> v2 = 0.5 * v1 3>>> np.arccos(v1.dot(v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))) 40.0
(中略)乱数を(一様乱数などではなく)正規分布から抽出し、標準偏差0.01を使用した理由は、恣意的なものである。先に述べたように、すべての重みが0で初期化された場合のベクトルの特性を避けるために。小さな乱数値を使用したかっただけであることを覚えておこう。
この解説が理解できませんでした。もう少し詳しく教えていただけると助かります。よろしくお願いいたします。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/25 06:12
2020/04/26 12:00 編集
2020/04/26 13:09