ニューラルネットワーク入門のLogistic回帰(分類問題)
Logistic回帰(分類問題)
このチュートリアルでは、次の部分について説明します.
Logistic分類モデル前回のチュートリアルでは、入力と出力が1つしかない簡単なモデルを示しました.このチュートリアルでは、入力パラメータが2つの変数である2分類モデルを構築します.このモデルは統計的にLogistic回帰モデルと呼ばれ,ネットワーク構造は以下のように記述できる.
Logistic回帰モデル
まず、チュートリアルで使用するパッケージをインポートします.
クラス分布の定義
チュートリアルでは、ターゲット分類
red vs. blue classes in the input space
Logistic関数とクロスエントロピー損失関数
Logistic関数
我々が設計したネットワークの目的は、入力された
Logistic関数
もし、Logistic関数とその導関数がまだはっきりしていない場合は、このチュートリアルを参照してください.詳しく説明しています.
クロスエントロピー損失関数
この分類問題の損失関数最適化については,各訓練サンプル
各サンプル
訓練サンプル全体のクロスエントロピー誤差を計算するには、各サンプルの値を加算するだけでよい.
クロスエントロピー誤差関数
クロスエントロピー誤差関数の詳細については、このチュートリアルを参照してください.
Cost function surface
勾配降下最適化損失関数
勾配降下アルゴリズムの動作原理は、損失関数
パラメータ
Δw
各トレーニングサンプル
損失関数のウェイトに対する導関数
ここで、
損失関数の重みに対する導関数を詳細に導く前に,このチュートリアルでいくつかの導出を抽出した.
段階的に導く.
上記のステップの導出を参照すると、以下の詳細な導出を得ることができます.
詳細な導出
したがって、各重みについての更新
各ウェイトの更新
バッチ処理では、
バッチ更新
勾配降下アルゴリズムを開始する前に、パラメータにランダムな数値付与プロセスを行い、収束するまで勾配降下アルゴリズムを使用してパラメータを更新する必要があります.
勾配降下更新
訓練セット
weight updates on the error surface
トレーニング結果の可視化
次のコードでは、トレーニングの結果を可視化します.
トレーニング結果の可視化
このチュートリアルでは、次の部分について説明します.
Logistic分類モデル前回のチュートリアルでは、入力と出力が1つしかない簡単なモデルを示しました.このチュートリアルでは、入力パラメータが2つの変数である2分類モデルを構築します.このモデルは統計的にLogistic回帰モデルと呼ばれ,ネットワーク構造は以下のように記述できる.
Logistic回帰モデル
まず、チュートリアルで使用するパッケージをインポートします.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import colorConverter, ListedColormap
from matplotlib import cm
クラス分布の定義
チュートリアルでは、ターゲット分類
t
は、2つの独立した分布から生成され、t=1
の場合、青色で表される.t=0
の場合、赤色で表される.入力パラメータX
はN*2
の行列であり、目標分類t
はN * 1
のベクトルである.より直感的な表現は、下図を参照してください.# Define and generate the samples
nb_of_samples_per_class = 20 # The number of sample in each class
red_mean = [-1,0] # The mean of the red class
blue_mean = [1,0] # The mean of the blue class
std_dev = 1.2 # standard deviation of both classes
# Generate samples from both classes
x_red = np.random.randn(nb_of_samples_per_class, 2) * std_dev + red_mean
x_blue = np.random.randn(nb_of_samples_per_class, 2) * std_dev + blue_mean
# Merge samples in set of input variables x, and corresponding set of output variables t
X = np.vstack((x_red, x_blue))
t = np.vstack((np.zeros((nb_of_samples_per_class,1)), np.ones((nb_of_samples_per_class,1))))
# Plot both classes on the x1, x2 plane
plt.plot(x_red[:,0], x_red[:,1], 'ro', label='class red')
plt.plot(x_blue[:,0], x_blue[:,1], 'bo', label='class blue')
plt.grid()
plt.legend(loc=2)
plt.xlabel('$x_1$', fontsize=15)
plt.ylabel('$x_2$', fontsize=15)
plt.axis([-4, 4, -4, 4])
plt.title('red vs. blue classes in the input space')
plt.show()
red vs. blue classes in the input space
Logistic関数とクロスエントロピー損失関数
Logistic関数
我々が設計したネットワークの目的は、入力された
x
からターゲットt
を予測することである.x = [x1, x2]
、重みw = [w1, w2]
、予測目標t = 1
が入力されると仮定する.では、確率P(t = 1|x, w)
は、ニューラルネットワーク出力のy
、すなわちy = σ(x∗wT)
である.ここで、σ
はLogistic
を表し、定義は以下の通りである.Logistic関数
もし、Logistic関数とその導関数がまだはっきりしていない場合は、このチュートリアルを参照してください.詳しく説明しています.
クロスエントロピー損失関数
この分類問題の損失関数最適化については,各訓練サンプル
i
について,交差エントロピー誤差関数を以下のように定義する交差エントロピー誤差関数を用いて解決した.各サンプル
i
のクロスエントロピー誤差関数訓練サンプル全体のクロスエントロピー誤差を計算するには、各サンプルの値を加算するだけでよい.
クロスエントロピー誤差関数
クロスエントロピー誤差関数の詳細については、このチュートリアルを参照してください.
logistic(z)
関数はLogistic
関数,cost(y, t)
関数は損失関数,nn(x, w)
はニューラルネットワークの出力結果,nn_predict(x, w)
はニューラルネットワークの予測結果を実現した.# Define the logistic function
def logistic(z):
return 1 / (1 + np.exp(-z))
# Define the neural network function y = 1 / (1 + numpy.exp(-x*w))
def nn(x, w):
return logistic(x.dot(w.T))
# Define the neural network prediction function that only returns
# 1 or 0 depending on the predicted class
def nn_predict(x,w):
return np.around(nn(x,w))
# Define the cost function
def cost(y, t):
return - np.sum(np.multiply(t, np.log(y)) + np.multiply((1-t), np.log(1-y)))
# Plot the cost in function of the weights
# Define a vector of weights for which we want to plot the cost
nb_of_ws = 100 # compute the cost nb_of_ws times in each dimension
ws1 = np.linspace(-5, 5, num=nb_of_ws) # weight 1
ws2 = np.linspace(-5, 5, num=nb_of_ws) # weight 2
ws_x, ws_y = np.meshgrid(ws1, ws2) # generate grid
cost_ws = np.zeros((nb_of_ws, nb_of_ws)) # initialize cost matrix
# Fill the cost matrix for each combination of weights
for i in range(nb_of_ws):
for j in range(nb_of_ws):
cost_ws[i,j] = cost(nn(X, np.asmatrix([ws_x[i,j], ws_y[i,j]])) , t)
# Plot the cost function surface
plt.contourf(ws_x, ws_y, cost_ws, 20, cmap=cm.pink)
cbar = plt.colorbar()
cbar.ax.set_ylabel('$\\xi$', fontsize=15)
plt.xlabel('$w_1$', fontsize=15)
plt.ylabel('$w_2$', fontsize=15)
plt.title('Cost function surface')
plt.grid()
plt.show()
Cost function surface
勾配降下最適化損失関数
勾配降下アルゴリズムの動作原理は、損失関数
ξ
が各パラメータを導出し、次いで負の勾配方向に沿ってパラメータ更新を行うことである.パラメータ
w
は、一定の学習率に従って負の勾配方向に更新される、すなわちw(k+1)=w(k)−Δw(k+1)
であり、Δw
は、以下のように表すことができる.Δw
各トレーニングサンプル
i
∂ξi/∂w
について、以下のように計算される.損失関数のウェイトに対する導関数
ここで、
yi=σ(zi)
はニューロンのLogistic
出力であり、zi=xi∗wT
はニューロンの入力である.損失関数の重みに対する導関数を詳細に導く前に,このチュートリアルでいくつかの導出を抽出した.
段階的に導く.
上記のステップの導出を参照すると、以下の詳細な導出を得ることができます.
詳細な導出
したがって、各重みについての更新
Δwj
は、各ウェイトの更新
バッチ処理では、
N
サンプルの勾配を加算する必要があります.すなわち、バッチ更新
勾配降下アルゴリズムを開始する前に、パラメータにランダムな数値付与プロセスを行い、収束するまで勾配降下アルゴリズムを使用してパラメータを更新する必要があります.
gradient(w, x, t)
関数は、∂ξ/∂w
delta_w(w_k, x, t, learning_rate)
関数の勾配を実現し、Δw
を実現する.# define the gradient function.
def gradient(w, x, t):
return (nn(x, w) - t).T * x
# define the update function delta w which returns the
# delta w for each weight in a vector
def delta_w(w_k, x, t, learning_rate):
return learning_rate * gradient(w_k, x, t)
勾配降下更新
訓練セット
X
の上で10
回実行して予測を行い、下図には前の3回の結果が描かれており、図中の青い点はk
回目、w(k)
の値を示している.# Set the initial weight parameter
w = np.asmatrix([-4, -2])
# Set the learning rate
learning_rate = 0.05
# Start the gradient descent updates and plot the iterations
nb_of_iterations = 10 # Number of gradient descent updates
w_iter = [w] # List to store the weight values over the iterations
for i in range(nb_of_iterations):
dw = delta_w(w, X, t, learning_rate) # Get the delta w update
w = w-dw # Update the weights
w_iter.append(w) # Store the weights for plotting
# Plot the first weight updates on the error surface
# Plot the error surface
plt.contourf(ws_x, ws_y, cost_ws, 20, alpha=0.9, cmap=cm.pink)
cbar = plt.colorbar()
cbar.ax.set_ylabel('cost')
# Plot the updates
for i in range(1, 4):
w1 = w_iter[i-1]
w2 = w_iter[i]
# Plot the weight-cost value and the line that represents the update
plt.plot(w1[0,0], w1[0,1], 'bo') # Plot the weight cost value
plt.plot([w1[0,0], w2[0,0]], [w1[0,1], w2[0,1]], 'b-')
plt.text(w1[0,0]-0.2, w1[0,1]+0.4, '$w({})$'.format(i), color='b')
w1 = w_iter[3]
# Plot the last weight
plt.plot(w1[0,0], w1[0,1], 'bo')
plt.text(w1[0,0]-0.2, w1[0,1]+0.4, '$w({})$'.format(4), color='b')
# Show figure
plt.xlabel('$w_1$', fontsize=15)
plt.ylabel('$w_2$', fontsize=15)
plt.title('Gradient descent updates on cost surface')
plt.grid()
plt.show()
weight updates on the error surface
トレーニング結果の可視化
次のコードでは、トレーニングの結果を可視化します.
# Plot the resulting decision boundary
# Generate a grid over the input space to plot the color of the
# classification at that grid point
nb_of_xs = 200
xs1 = np.linspace(-4, 4, num=nb_of_xs)
xs2 = np.linspace(-4, 4, num=nb_of_xs)
xx, yy = np.meshgrid(xs1, xs2) # create the grid
# Initialize and fill the classification plane
classification_plane = np.zeros((nb_of_xs, nb_of_xs))
for i in range(nb_of_xs):
for j in range(nb_of_xs):
classification_plane[i,j] = nn_predict(np.asmatrix([xx[i,j], yy[i,j]]) , w)
# Create a color map to show the classification colors of each grid point
cmap = ListedColormap([
colorConverter.to_rgba('r', alpha=0.30),
colorConverter.to_rgba('b', alpha=0.30)])
# Plot the classification plane with decision boundary and input samples
plt.contourf(xx, yy, classification_plane, cmap=cmap)
plt.plot(x_red[:,0], x_red[:,1], 'ro', label='target red')
plt.plot(x_blue[:,0], x_blue[:,1], 'bo', label='target blue')
plt.grid()
plt.legend(loc=2)
plt.xlabel('$x_1$', fontsize=15)
plt.ylabel('$x_2$', fontsize=15)
plt.title('red vs. blue classification boundary')
plt.show()
トレーニング結果の可視化