机器学习实验4 实现感知机学习算法

  • 实验目的

1. 采用感知机学习算法建立模型

2. 神经元激活函数建议选用sign函数(数据集最后一列的标签请将 0 转换为 -1)

3. 迭代输出每一次更新后的 W 和 θ

4. 数据集线性可分,最好求解出线性超平面

  • 实验内容:
  1. 首先要把数据集里的数据进行处理,使用np.loadtxt()把数据读入ndarray,把前两列和最后一列的标签分开,并且数据集最后一列的标签请将 0 转换为 -1。

  1. 定义Perceptron单层感知机类,参数有四个,分别是学习率lr、迭代次数epochs、权重向量w和偏置项b,lr和epochs提供默认参数值0.01和100。

  1. 训练函数train(),首先初始化w和b,w使用Xavier初始化方法,可以获得更好的训练效果,b初始值设为0。然后两层循环,外层是迭代次数,内层循环每次取一个坐标值和lable,按照进行计算,f()激活函数使用sign函数。根据对w和b进行更新,并输出更新后的w和b的值。

  1. 经过训练之后,使用matplotlib对训练结果进行可视化,通过w和b的值得到超平面。直线的函数表达式为ax + by + c = 0,w的两个参数w[0],w[1]分别是a,b,b是表达式中的c,用plt.plot可以画出。数据集中的点根据其标签值,分为蓝色和红色的点,使用plt.scatter()画出。

实验结果

使用epoch=10,每个x都可以更新一次参数,可以看到10轮之内就可以收敛,达到不错的效果

开始训练时的参数更新情况

收敛

线性超平面为:0.13245762 * x - 0.08317062 * y + 0.5800000000000002 = 0

划分情况可视化

可以看到效果不错

  • 实验原理:

  • 心得体会:

实验中遇到的问题及解决方法:

  1. 权重的初始化对收敛速度等有影响,并且网络训练的过程中, 容易出现梯度消失和梯度爆炸的情况,导致大部分反向传播得到的梯度不起作用或者起反作用。通过查阅资料发现Xavier初始化方法是一种比较常用的且性能优秀的方法,可以尽可能的让输入和输出服从相同的分布,这样就能够避免后面层的激活函数的输出值趋向于0。
  2. 在画图的时候,数据集中的点要使用原来的标签而不是带入线性超平面中求出分类,这样会导致可视化结果中,相同颜色的点一定在直线两侧。

心得体会:

      通过这次实验,我对于感知机模型的原理有了进一步的了解,也通过实验对这一算法进行了实践,加深了印象。虽然实验中用到的模型比较简单,但是学习到了反向传播优化这一思想。通过可视化得出比较好的分类效果也令我备受鼓舞,期望在后面的学习中可以学到更多机器学习相关知识。为以后的学习工作打下坚实的基础。

import numpy as np
import matplotlib.pyplot as plt


class Perceptron:
    def __init__(self, lr=0.01, epochs=100):
        self.lr = lr  # 学习率
        self.epochs = epochs  # 最大迭代次数
        self.w = None  # 权重向量
        self.b = None  # 偏置项

    def train(self, X, lable):
        # self.w = np.zeros(X.shape[1])
        self.w = np.random.randn(X.shape[1]) * np.sqrt(1 / X.shape[1])
        self.b = 0
        for epoch in range(self.epochs):
            for x, y in zip(X, lable):
                # y_hat = np.sign(np.dot(x, self.w) + self.b)
                y_hat = 1 if np.dot(x, self.w) + self.b >= 0 else -1
                self.w += self.lr * (y - y_hat) * x
                self.b += self.lr * (y - y_hat)
                print(self.w, self.b)

    def picture(self, X, lable):
        x1 = []
        x2 = []
        y1 = []
        y2 = []
        for x, y in zip(X, lable):
            if y == 1:
                x1.append(x[0])
                y1.append(x[1])
            else:
                x2.append(x[0])
                y2.append(x[1])
        plt.figure()
        x = [i for i in range(-5, 5)]
        y = [-(self.w[0] / self.w[1]) * i - self.b / self.w[1] for i in x]
        plt.plot(x, y)
        plt.scatter(x1, y1, color='blue')
        plt.scatter(x2, y2, color='red')
        plt.show()


def get_data():
    dataset = np.loadtxt(r"D:\pythonProject\Machine_learning\test4\perceptron_data.txt")
    data = dataset[:, :2]
    lable = dataset[:, -1]
    lable = [-1.0 if i == 0 else i for i in lable]
    return data, lable


data, lable = get_data()
net = Perceptron(0.01, 10)
net.train(data, lable)
# net.train(data, lable)
net.picture(data, lable)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值