一、原理:
感知机的“非对偶”还是比较容易理解的,输出的Y只有 +1 和 -1 两个选择。
公式:,其中w是权重,b是偏置
其中sign算是个激活函数:
线性方程: 这个对应空间中的一个超平面
需要知道的几个小内容:
1、点到超平面的距离:
2、误分类数据,具有如下关系成立:
3、误分类点到超平面的总距离:
4、损失函数:
5、参数更新:
二、课本上2.1 的习题
import numpy as np
import random
#定义数据
#define data
#positive point
x1=[3,3]
x2=[4,3]
#negtive point
x3=[1,1]
#定义模型,定义负样本的随机选择(遵从随机梯度下降)
#define model
#f(x)=sign(wx+b)
def sign(y_):
if y_>= 0:
return 1
if y_<0:
return -1
class perceptron_model:
def __init__(self,w,b,lr):
#初始化 Initialization
self.w=w
self.b=b
self.lr=lr
def forward(self,x):
return self.w[0]*x[0]+self.w[1]*x[1]+self.b
def backward(self,x,y):
self.w[0]=self.w[0]+self.lr*y*x[0]
self.w[1]=self.w[1]+self.lr*y*x[1]
self.b=self.b+self.lr*y
def loss(self,preds,labels):
loss_=0
for pred,label in zip(preds,labels):
if -label * pred >= 0:
#loss_+= -label*pred #正统loss
loss_+=1 #非正统
return loss_
def get_preds(model,data):
preds=[]
for x0,x1 in data:
preds.append(model.forward([x0,x1]))
return preds
def stochastic_select_negtive_data(data,preds,labels):
new_data=[]
for point,pred,label in zip(data,preds,labels):
if -label*pred >=0:
new_data.append([point,label])
selected_data=random.sample(new_data,1)
return selected_data
#学习,训练模型
meta=[x1,x2,x3]
labels=[1,1,-1]
model=perceptron_model(w=[0,0],b=0,lr=1)
preds=get_preds(model,meta)
print(preds)
loss_=model.loss(preds,labels)
while loss_>0:
selected_data=stochastic_select_negtive_data(meta,preds,labels)
print(selected_data)
model.backward(selected_data[0][0],selected_data[0][1])
preds=get_preds(model,meta)
loss_=model.loss(preds,labels)
#第一次预测结果
[0,0,0]
#打印出每次选择的负样本
[[[3, 3], 1]]
[[[1, 1], -1]]
[[[1, 1], -1]]
[[[1, 1], -1]]
[[[3, 3], 1]]
[[[1, 1], -1]]
[[[1, 1], -1]]
#查看模型参数与预测结果
print(model.w,model.b)
print(get_preds(model,meta))
([1, 1], -3)
[3, 4, -1]
后期更新C++代码。。。