要了解单层感知器,必须了解人工神经网络(ANN)。人工神经网络是一个信息处理系统,其机制受到生物神经回路功能的启发。人工神经网络有许多相互连接的计算单元。人工神经网络的原理图如下:
该图显示,隐藏实体与外部层进行交流。而输入和输出单元则只通过网络的隐藏层进行交流。
与节点的连接模式、层的总数、输入和输出之间的节点层次以及每层的神经元数量,定义了神经网络的架构。
有两种类型的架构。这些类型侧重于功能的人工神经网络,如下所示:
- 单层感知器
- 多层感知器
单层感知器
单层是最早提出的神经模型。神经元的局部存储器的内容由权重向量组成。单层的计算,是通过将每个值的输入向量之和乘以权重向量的相应元素来完成。输出中显示的值是激活函数的输入。
单层感知器**(SLP**)是一个基于阈值传递函数的前馈网络。SLP是最简单的人工神经网络类型,只能对具有二进制目标(1 , 0)的线性可分离情况进行分类。
激活函数和它的意义
激活函数是神经网络的决策单元。它们计算一个神经节点的净输出。在这里,Heaviside阶梯函数是神经网络中最常见的激活函数之一。该函数产生二进制输出。这就是为什么它也被称为二进制步骤函数的原因。当输入通过阈值限制时,该函数产生1(或真),而当输入没有通过阈值时,它产生0(或假)。这就是为什么它们对二元分类研究非常有用。
它是一种非线性转换,我们在将输入发送到下一层神经元或最终确定为输出之前,对其进行非线性转换。一个神经元的激活函数决定了它是否应该被打开或关闭。非线性函数通常将神经元的输出转化为0到1或-1到1之间的数字。激活函数的目的是在神经元的输出中引入非线性。
海维塞德阶跃函数通常只在单层感知器中有用,这是一种早期的神经网络类型,在输入数据是线性可分离的情况下可用于分类。
激活函数的类型
算法
单层感知器没有先验知识,所以初始权重是随机分配的。SLP对所有加权的输入进行求和,如果求和高于阈值(一些预定的值),则称SLP被激活(输出=1)。
输入值被提交给感知器,如果预测的输出与期望的输出相同,那么性能被认为是令人满意的,不需要对权重进行改变。然而,如果输出与期望输出不一致,那么就需要改变权重以减少误差。
因为SLP是一个线性分类器,如果案例不是线性可分离的,那么学习过程将永远不会达到所有案例都被正确分类的程度。最著名的例子是XOR问题,说明感知器无法解决具有线性不可分离的情况的问题。
实现单层感知器的完整代码----
import numpy as np
import pandas as pd
data=pd.read_csv('iris.csv')
data.columns=['Sepal_len_cm','Sepal_wid_cm','Petal_len_cm','Petal_wid_cm','Type']
# I am using Sigmoid function as the activation function
def activation_func(value): #Tangent Hypotenuse
#return (1/(1+np.exp(-value)))
return ((np.exp(value)-np.exp(-value))/(np.exp(value)+np.exp(-value)))
def perceptron_train(in_data,labels,alpha):
X=np.array(in_data)
y=np.array(labels)
weights=np.random.random(X.shape[1])
original=weights
bias=np.random.random_sample()
for key in range(X.shape[0]):
a=activation_func(np.matmul(np.transpose(weights),X[key]))
yn=0
if a>=0.7:
yn=1
elif a<=(-0.7):
yn=-1
weights=weights+alpha*(yn-y[key])*X[key]
print('Iteration '+str(key)+': '+str(weights))
print('Difference: '+str(weights-original))
return weights
# Testing and Score
def perceptron_test(in_data,label_shape,weights):
X=np.array(in_data)
y=np.zeros(label_shape)
for key in range(X.shape[1]):
a=activation_func((weights*X[key]).sum())
y[key]=0
if a>=0.7:
y[key]=1
elif a<=(-0.7):
y[key]=-1
return y
def score(result,labels):
difference=result-np.array(labels)
correct_ctr=0
for elem in range(difference.shape[0]):
if difference[elem]==0:
correct_ctr+=1
score=correct_ctr*100/difference.size
print('Score='+str(score))
# Main code
divider = np.random.rand(len(data)) < 0.70
d_train = data[divider]
d_test = data[~divider]
# Dividing d_train into data and labels/targets
d_train_y = d_train['Type']
d_train_X = d_train.drop(['Type'], axis=1)
# Dividing d_train into data and labels/targets
d_test_y = d_test['Type']
d_test_X = d_test.drop(['Type'], axis=1)
# Learning rate
alpha = 0.001
# Train
weights = perceptron_train(d_train_X, d_train_y, alpha)
# Test
result_test = perceptron_test(d_test_X, d_test_y.shape, weights)
# Calculate score
score(result_test, d_test_y)