欢迎。今天,我们将介绍如何构建基本的单感知器神经网络。
我想让这篇文章成为我们深入研究一切的系列文章中的第一篇——CNN、迁移学习等。所以一定要为该网站添加书签并继续检查它。另外,这将包括一些数学知识,所以请系好安全带。
什么是感知器?
它是神经网络(NN)的最基本单元。在复杂的神经网络中,所有数据通常同时经过多个神经网络并扮演不同的角色。但我们稍后会讨论这个问题。
现在,什么是感知器?
在监督学习中,感知器是线性分类器的一种形式。因此,任何可以被一条直线划分的数据集都可以使用感知器进行分类,即任何如下所示的数据集:
最后一条不能被认为是线性可分离的,因为它不是可以近似分离数据库的单行。
构建单个感知器神经网络
今天让我们继续构建我们的第一个单感知器神经网络。为此,我们将从创建数据开始。
1. 创建我们的数据集
首先,我们需要数据集,在我们的例子中是一个2D 数组。打开代码编辑器、Jupyter 笔记本或 Google Colab。
import pandas as pd import numpy as np import random |
让我们制作我们的数据。在本例中,我考虑使用 20*20 平面,以保持结果小而简洁。
#Dataset df = pd.DataFrame() df[ 'x' ] = [random.randint( 1 , 20 ) for x in range ( 10 )] df[ 'y' ] = [random.randint( 1 , 20 ) for x in range ( 10 )] df.head() |
现在,我们需要给它们贴上标签。所以我们将根据一条线进行过滤(我认为 y=x)。因此,该线下方的每个点均是 y<x,该线上方的每个点均表示 y>x。
label = [] for i in range (df.shape[ 0 ]): if df.iloc[i, 0 ] < df.iloc[i, 1 ]: label.append( 1 ) else : label.append( - 1 ) df[ 'label' ] = label df |
2. 初始化值的权重
现在我们可以初始化权重。我们不能使用零值,因此我们将采用随机均匀分布的权重:
#weights and bias weights = [np. round (random.uniform( - 0.99 , 0.99 ), 2 ) for i in range ( 2 )] |
然后我们将权重与输入数据点相乘并求和:
w = weights.copy() X = [[df.iloc[i, 0 ],df.iloc[i, 1 ]] for i in range (df.shape[ 0 ])] wx = [X[i][ 0 ] * w[ 0 ] + X[i][ 1 ] * w[ 1 ] for i in range (df.shape[ 0 ])] |
现在,我们有了每个点的权重和输入的总和。
因此,程序是,我们将一次将所有这些值插入到激活函数中,然后根据输出修改权重。
3. 创建激活函数
现在我们来看看激活函数。感知器处理总和并给我们一个标签,我们将其与原始标签进行比较并确定它是否正确。如果不正确,则会发现错误并调整权重,以便我们的解决方案*朝原始方向移动*。
我们将使用signum函数:
如果 wx <=0 ,则输出为 0。否则,输出为 1。
for i in range (df.shape[ 0 ]): if wx[i]< = 0 : pred = 0 else : pred = 1 |
请记住,我们只有两个输入:x 和 y。不是整个数据框。因此,我们将扩展此激活函数以一次接收一个数据点,然后找到误差并调整误差:
for i in range (df.shape[ 0 ]): if wx[i]< = 0 : pred = - 1 else : pred = 1 if pred ! = df[ 'label' ][i] : err = df[ 'label' ][i] - pred w[ 0 ] = w[ 0 ] + err w[ 1 ] = w[ 1 ] + err |
现在效果很好。为了清楚地看到输出,我们将放入一堆打印语句:
for i in range (df.shape[ 0 ]): print ( 'wx : ' ,wx[i]) if wx[i]< = 0 : pred = - 1 else : pred = 1 print ( 'label=' ,df[ 'label' ][i]) print ( 'pred = ' ,pred) if pred ! = df[ 'label' ][i] : err = df[ 'label' ][i] - pred print ( 'err' ,err) print ( 'before' , w[ 0 ],w[ 1 ]) w[ 0 ] = w[ 0 ] + err w[ 1 ] = w[ 1 ] + err print ( 'after' ,w[ 0 ],w[ 1 ]) else : print ( 'w_i' , w[ 0 ],w[ 1 ]) |
现在如果我们运行这个:
一个简单的打印格式声明给了我们最终的权重。
4. 在另一个数据库上测试我们的模型
与我们进行train-test-split 的方式类似,我们将使用不同的数据库进行测试。
#Test Dataset new_df = pd.DataFrame() new_df[ 'x' ] = [random.randint( 1 , 20 ) for x in range ( 100 )] new_df[ 'y' ] = [random.randint( 1 , 20 ) for x in range ( 100 )] new_df.head() |
然后我们根据 y=x 线以及权重*输入的总和生成标签:
label_text = [] for i in range (new_df.shape[ 0 ]): if new_df.iloc[i, 0 ] < new_df.iloc[i, 1 ]: label_text.append( 1 ) else : label_text.append( - 1 ) new_wX = w[ 0 ] * new_df[ 'x' ] + w[ 1 ] * new_df[ 'y' ] |
这是我的:
因此,现在到了关键时刻,我们应用激活函数,然后我们可以将给定标签与预测标签进行比较:
new_df[ 'given label' ] = label_text pred_label_text = [] for i in range (new_df.shape[ 0 ]): if new_wX[i]> = 0 : pred_label_text.append( - 1 ) else : pred_label_text.append( 1 ) new_df[ 'predicted labels' ] = pred_label_text |
正如你所看到的,我们自己做得很好 🙂
结论
恭喜您完成本教程。我希望这能让您对“感知器”有更多的了解。与我们保持联系以阅读我们未来的教程。