抓住时间的尾巴,在我还有时间学一点其他东西的时候,尽量做点笔记吧,证明我来过。

今天的东西原理很简单,但是要实现起来还是有点小麻烦的,有很多坑,一不小心就会掉下去。通过理解感知机,我们对神经网络也会有更加深刻的认识。因为这就是神经网络的基础。

先来看看感知机长什么样子:

如图所示,它就是一个最最简单的神经网络(虽然只有一个神经元)。我们现在用它来实现逻辑“与”,也就是说当输入为(1,1)时输出为1,当输入中有0时,输出0 。当然也可以实现“或“、”非”逻辑,但是这是重复工作。(注意并非任何逻辑关系都能实现,比如‘或非’,其原因是在直角坐标其中不能将其结果用一条直线分开。)

来看看它是怎么实现这个逻辑的。

首先,总共有2个输入x1和x0,所以权重也有两个w0,w1,还有阈值θ,后面三者是待确定的。但是通常情况下,将θ视为w3,所以输入就有三个(xi与wi为一一对应关系),只是第三个输入恒为-1。最后的结点表达式为:

现在我们的工作是把t带入激活函数中,来判断f(t)。我们选用的激活函数及其图像为:

(大家喜欢把它叫做sigmoid函数。)回到上一步,我们现在需要判断的是f(t)是否大于0.5,若 f(t)>=0.5 就把结果视为1,反之视为0 。

【注】这种做法仅仅是在设计逻辑函数时的做法。

那么其判断原理我们现在就弄清楚了,现在来看看怎么训练数据。

首先需要确定待确定的变量为w1,w2,w3简称wi。在这里,我们希望根据带入wi与xi后算出的f(t)和数据集中原来的值y(实际值)来作比较,根据其误差大小来改变wi因此,引入公式:

其中β称为学习率,在(0,1)之间。现在可以改变wi了,也就是说可以根据数据集来训练wi了。

但是别高兴太早,还有很多坑。根据我的经验,总结了有几点:

1、我们的数据集格式为【1,1,0.9】或【1,0,0.4】或【0,1,0.3】或【1,1,0,76】……你懂我意思吧。

2、数据集尽量分散,也就是不要【1,1】一群【1,0】一群,这样训练来的wi极为不准确(亲测)。

3、最后输出的时候我们要做一下处理,也就是大于0.5时,我们要让他输出1,小于0.5时,我们要让他输出0 。当然这只是在最后验证结果的时候,

在训练的时候还是要带值的。

下面是我的实现过程:

我造的数据为160×3的数据集,其中【1,1】、【1,0】、【0,1】、【0,0】分别占40个。下面是一次训练的结果。

可以看到,验证结果全对!!为了验证这种训练的准确度,我又设计了对程序加了一个循环,让它运行1000次!!!其中,分类正确的有919次,也就是说正确率达到了91.9%。要是我的训练集再特殊一点,算法再设计得好一些的话,正确率还会增加。(顺便说下,运行1000次大约花25秒,比较耗时。)

每天学完东西再听首歌,真实太美了!!!

上期文章:

附件一(单次训练):

f = inline('1/(1+exp(-x))','x');  %sigmoid函数表达式

theta = 0.5;   %学习率

shuju = ones(160,3);%下面几句有关shuju的都是在生成数据集

shuju(41:80,2) = 0;

shuju(81:120,1) = 0;

shuju(121:160,1:2) = 0;

shuju(1:40,3) = rand(40,1)*0.5+0.5;

shuju(41:end,3) = rand(120,1)*0.5;

randindex = randperm(size(shuju,1));%这两句是打乱数据集的顺序

shuju=shuju(randindex,:)

y=shuju(1:end,3);%构造xi

x(1:end,3) = -1;

w = rand(3,1);%生成初始wi

for i=1:160  %训练

t = x(i,:)*w;

loss = theta*(y(i)-f(t));

w(j) = w(j)+x(i,j)*loss

disp('验证') %下面全是验证

disp('带入x=[1,1]')

x1=[1,1,-1];

if f(t)>=0.5

disp('带入x=[0,1]')

x1=[0,1,-1];

if f(t)>=0.5

disp('带入x=[0,0]')

x1=[0,0,-1];

if f(t)>=0.5

disp('带入x=[0,1]')

x1=[0,1,-1];

if f(t)>=0.5

附件二(运行1000次):

f = inline('1/(1+exp(-x))','x');  %sigmoid函数表达式

for k=1:1000

theta = 0.5;   %学习率

shuju = ones(160,3);%下面几句有关shuju的都是在生成数据集

shuju(41:80,2) = 0;

shuju(81:120,1) = 0;

shuju(121:160,1:2) = 0;

shuju(1:40,3) = rand(40,1)*0.5+0.5;

shuju(41:end,3) = rand(120,1)*0.5;

randindex = randperm(size(shuju,1));%这两句是打乱数据集的顺序

shuju=shuju(randindex,:);

y=shuju(1:end,3);%构造xi

x(1:end,3) = -1;

w = rand(3,1);%生成初始wi

for i=1:160  %训练

t = x(i,:)*w;

loss = theta*(y(i)-f(t));

w(j) = w(j)+x(i,j)*loss;

a = 0;%标记

x1=[1,1,-1];

if f(t)>=0.5

x1=[0,1,-1];

if f(t)<0.5

x1=[0,0,-1];

if f(t)<0.5

x1=[0,1,-1];

if f(t)<0.5

disp('1000次中正确的次数')

disp('正确率为:')

最后没关注的小伙伴可以来一波关注哟