私たちは、この章ノートに理論的な知識パーセプトロンを導入し、戦略、収束を解決する、知覚機械作品の起源を説明します。このノートでは、我々は現実的な問題を解決するために、独自のコード、パーセプトロンアルゴリズムを記述する必要があります。
分類OR論理を解決するためにパーセプトロンアルゴリズムで、起動する簡単な質問から始めます。
import numpy as np
import matplotlib.pyplot as plt
x = [0,0,1,1]
y = [0,1,0,1]
plt.scatter(x[0],y[0], color="red",label="negative")
plt.scatter(x[1:],y[1:], color="green",label="positive")
plt.legend(loc="best")
plt.show()
サンプルポイントが正しく分類されているかどうかを決定するために使用する関数を定義してみましょう。この例のサンプル点は、二次元であり、したがって、重みベクトルは、2次元の対応、と定義することができるので(\ W =(W_1、W_2))\、リストは、Pythonで使用することができる、例えば、発現されw = [0, 0]
た試料に、超平面の距離が自然ですw[0] * x[0] + w[1] * x[1] +b
。ここでは、完全な機能です。
def decide(data,label,w,b):
result = w[0] * data[0] + w[1] * data[1] - b
print("result = ",result)
if np.sign(result) * label <= 0:
w[0] += 1 * (label - result) * data[0]
w[1] += 1 * (label - result) * data[1]
b += 1 * (label - result)*(-1)
return w,b
コア機能を書き込んだ後、私たちは、それぞれのサンプルポイントを横断する機能を提供ディスパッチ関数を記述する必要があります。
def run(data, label):
w,b = [0,0],0
for epoch in range(10):
for item in zip(data, label):
dataset,labelset = item[0],item[1]
w,b = decide(dataset, labelset, w, b)
print("dataset = ",dataset, ",", "w = ",w,",","b = ",b)
print(w,b)
data = [(0,0),(0,1),(1,0),(1,1)]
label = [0,1,1,1]
run(data,label)
result = 0
dataset = (0, 0) , w = [0, 0] , b = 0
result = 0
dataset = (0, 1) , w = [0, 1] , b = -1
result = 1
dataset = (1, 0) , w = [0, 1] , b = -1
result = 2
dataset = (1, 1) , w = [0, 1] , b = -1
result = 1
dataset = (0, 0) , w = [0, 1] , b = 0
result = 1
dataset = (0, 1) , w = [0, 1] , b = 0
result = 0
dataset = (1, 0) , w = [1, 1] , b = -1
result = 3
dataset = (1, 1) , w = [1, 1] , b = -1
result = 1
dataset = (0, 0) , w = [1, 1] , b = 0
result = 1
dataset = (0, 1) , w = [1, 1] , b = 0
result = 1
后面的迭代这里省略不贴,参数稳定下来,算法已经收敛
レッツ・UCIからのデータセットを見て:PIMA糖尿病データセット、第3章からの例、「機械学習アルゴリズムの視点」
import os
import pylab as pl
import numpy as np
import pandas as pd
os.chdir(r"DataSets\pima-indians-diabetes-database")
pima = np.loadtxt("pima.txt", delimiter=",", skiprows=1)
pima.shape
(768, 9)
indices0 = np.where(pima[:,8]==0)
indices1 = np.where(pima[:,8]==1)
pl.ion()
pl.plot(pima[indices0,0],pima[indices0,1],"go")
pl.plot(pima[indices1,0],pima[indices1,1],"rx")
pl.show()
データの前処理
1.ディスクリートの年齢
pima[np.where(pima[:,7]<=30),7] = 1
pima[np.where((pima[:,7]>30) & (pima[:,7]<=40)),7] = 2
pima[np.where((pima[:,7]>40) & (pima[:,7]<=50)),7] = 3
pima[np.where((pima[:,7]>50) & (pima[:,7]<=60)),7] = 4
pima[np.where(pima[:,7]>60),7] = 5
2. 8回の代わりの8倍以上と女性の妊娠の統一された数
pima[np.where(pima[:,0]>8),0] = 8
3.データの正規化
pima[:,:8] = pima[:,:8]-pima[:,:8].mean(axis=0)
pima[:,:8] = pima[:,:8]/pima[:,:8].var(axis=0)
4.セグメンテーショントレーニングとテストセット
trainin = pima[::2,:8]
testin = pima[1::2,:8]
traintgt = pima[::2,8:9]
testtgt = pima[1::2,8:9]
定義モデル
class Perceptron:
def __init__(self, inputs, targets):
# 设置网络规模
# 记录输入向量的维度,神经元的维度要和它相等
if np.ndim(inputs) > 1:
self.nIn = np.shape(inputs)[1]
else:
self.nIn = 1
# 记录目标向量的维度,神经元的个数要和它相等
if np.ndim(targets) > 1:
self.nOut = np.shape(targets)[1]
else:
self.nOut = 1
# 记录输入向量的样本个数
self.nData = np.shape(inputs)[0]
# 初始化网络,这里加1是为了包含偏置项
self.weights = np.random.rand(self.nIn + 1, self.nOut) * 0.1 - 0.05
def train(self, inputs, targets, eta, epoch):
"""训练环节"""
# 和前面处理偏置项同步地,这里对输入样本加一项-1,与W0相匹配
inputs = np.concatenate((inputs, -np.ones((self.nData,1))),axis=1)
for n in range(epoch):
self.activations = self.forward(inputs)
self.weights -= eta * np.dot(np.transpose(inputs), self.activations - targets)
return self.weights
def forward(self, inputs):
"""神经网路前向传播环节"""
# 计算
activations = np.dot(inputs, self.weights)
# 判断是否激活
return np.where(activations>0, 1, 0)
def confusion_matrix(self, inputs, targets):
# 计算混淆矩阵
inputs = np.concatenate((inputs, -np.ones((self.nData,1))),axis=1)
outputs = np.dot(inputs, self.weights)
nClasses = np.shape(targets)[1]
if nClasses == 1:
nClasses = 2
outputs = np.where(outputs<0, 1, 0)
else:
outputs = np.argmax(outputs, 1)
targets = np.argmax(targets, 1)
cm = np.zeros((nClasses, nClasses))
for i in range(nClasses):
for j in range(nClasses):
cm[i,j] = np.sum(np.where(outputs==i, 1,0) * np.where(targets==j, 1, 0))
print(cm)
print(np.trace(cm)/np.sum(cm))
print("Output after preprocessing of data")
p = Perceptron(trainin,traintgt)
p.train(trainin,traintgt,0.15,10000)
p.confusion_matrix(testin,testtgt)
Output after preprocessing of data
[[ 69. 86.]
[182. 47.]]
0.3020833333333333
この場合、パーセプトロンによって得られた結果の使用が唯一のアルゴリズムを示すための例として、ここでは、比較的貧しい訓練します。
デジタル手書き文字認識アルゴリズムMNISTの使用の例で見納めパーセプトロン。Kaggleに描くカーネルコード。
ステップ1:所望の第1のパケットを導入すること、及びデータパスを設定します
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
train = pd.read_csv(r"DataSets\Digit_Recognizer\train.csv", engine="python")
test = pd.read_csv(r"DataSets\Digit_Recognizer\test.csv", engine="python")
print("Training set has {0[0]} rows and {0[1]} columns".format(train.shape))
print("Test set has {0[0]} rows and {0[1]} columns".format(test.shape))
Training set has 42000 rows and 785 columns
Test set has 28000 rows and 784 columns
ステップ2:データの前処理
作成し
label
、その大きさは(42000 1)であります作成し
training set
、サイズは(42000、784)作成
weights
サイズがあり、(10,784)
それを理解するのは少し難しいかもしれません。我々は、784は784次元の入力サンプル対応するニューロンを表し、それはまた、784次元のドッキングを有する寸法であり、重みベクトルはニューロンの記述であることを知っています。同時に、ニューロンは出力、及びデジタル識別の問題は、我々は、入力データのサンプルを楽しみにして唯一の出力は、10桁にサンプルが最尤のものを数に応じて判断されていること、次に確率を返すことができることを覚えておいてください。そこで、我々は10個のニューロン、必要(10,784)
起源。
trainlabels = train.label
trainlabels.shape
(42000,)
traindata = np.asmatrix(train.loc[:,"pixel0":])
traindata.shape
(42000, 784)
weights = np.zeros((10,784))
weights.shape
(10, 784)
ここでは、サンプル、見た目の感触で見ることができます。元のデータが784次元の配列に圧縮されることに注意してください、私たちは絵に戻ってそれを変更する必要があります28 * 28
# 从矩阵中随便取一行
samplerow = traindata[123:124]
# 重新变成28*28
samplerow = np.reshape(samplerow, (28,28))
plt.imshow(samplerow, cmap="hot")
ステップ3:トレーニング
ここでトレーニングデータセットのサイクル数回、その後は誤り率曲線に焦点を当てます
# 先创建一个列表,用来记录每一轮训练的错误率
errors = []
epoch = 20
for epoch in range(epoch):
err = 0
# 对每一个样本(亦矩阵中的每一行)
for i, data in enumerate(traindata):
# 创建一个列表,用来记录每个神经元输出的值
output = []
# 对每个神经元都做点乘操作,并记录下输出值
for w in weights:
output.append(np.dot(data, w))
# 这里简单的取输出值最大者为最有可能的
guess = np.argmax(output)
# 实际的值为标签列表中对应项
actual = trainlabels[i]
# 如果估计值和实际值不同,则分类错误,需要更新权重向量
if guess != actual:
weights[guess] = weights[guess] - data
weights[actual] = weights[actual] + data
err += 1
# 计算迭代完42000个样本之后,错误率 = 错误次数/样本个数
errors.append(err/42000)
x = list(range(20))
plt.plot(x, errors)
[<matplotlib.lines.Line2D at 0x5955c50>]
15回の反復まで、図からわかるように、エラー率は上昇傾向にあった、とフィット感を生きるために始めています。
パーセプトロンは、現実のシーンにパーセプトロンアルゴリズムを使用することは困難であることを、非常に単純なアルゴリズムです。三つの例はここに引用し、その実装アルゴリズム手、ルックフィールコードを記述することを意図しています。より多くの経験を積んだ読者が疑問に思っている必要があります。なぜ、このパッケージをScikit・ラーン使用しないで、この部分は実際に著者が他の計画を持っていた、我々はソースノートのアルゴリズム書かれたScikit-学び解釈を組み合わせていきます。もちろん、個々のレベルに制限され、本質的に解決することができないかもしれないが、それはに管理し、むしろとして。パートIIは書きます、マルチレイヤパーセプトロン我々だけで簡単に隠されたレイヤーを追加し、それが大幅に分類能力を向上させることができ、あっても、単純な機械知覚を見ることができるアルゴリズムの理論を、。また、あなたがソースマシンSklearn記事の知覚解釈を書く時間を見つけます。ご質問がある、メッセージを議論する歓迎。