BP神经网络聚类分析

概述

    神经网络算法是机器学习和人工智能的基础。在各种神经网络算法中,最简单的是BP神经网络算法。本文将介绍BP神经网络算法基本原理,并提供一个BP神经网络算法完成聚类分析的案例。
    BP神经网络具有输入层、隐含层(一层或多层)和输出层,通过这三层的神经网络可以逼近任意非线性函数。以二维输入样本,三个隐含层神经元为例:

输入层
隐含层计算
隐含层非线性变换
输出层计算
输出层非线性变换
X1
NetX1=W11X1+W12X2+θ11
NetX2=W21X1+W22X2+θ12
NetX3=W31X1+W32X2+θ13
X2
O1=FNetX1
O2=FNetX2
O3=FNetX3
NetY1=V11O1+V12O2+V13O3+θ21
Z1=GNetY1

        参数说明:权值矩阵为W和V,阀值矩阵为θ1和θ2,传递函数为F(X)和G(X)。

当输出值Z1和样本中输入值Y1存在差值时,误差一步步反向回传,分配给权值矩阵和阀值矩阵。经过多次运算后,差值回逐渐趋于0。

流程图

        BP神经网络算法的核心,在于每次计算得到输出值和样本值的误差,并根据误差按负梯度方向反向调整权值和阀值矩阵。流程图如下图示:

开始
计算数据最大值
生成初始权值和阀值矩阵
单次训练
单个样本归一化处理
计算隐含层神经元
计算输出层神经元
计算误差和梯度
权值和阀值更新
所有样本都遍历完
达到跳出条件
输出权值阀值和最大值
结束

代码实现

本文中,隐含层和输出层的传递函数均采用: y=1/(1+exp(-x))。
输入数据如下:样本对(X,Y)中,X为 x∈[-3,3],y∈[-3,3]范围内的随机点位;Y为0或者1,当X在(x-1)(x-1) +y^2 <=2或者(x+1)(x+1)+y^2<=2范围内时,Y=1;其余情况为0。

%% 数据准备,100个样本对,30个测试对
MatrixX=6*rand(100,2)-3*ones(100,2);%%输入值
MatrixY=zeros(100,1);%%输出值
TestMatrixY=zeros(100,1);%%输出值
for i=1:100
    Circle1=(MatrixX(i,1)-1)^2+MatrixX(i,2)^2;
    Circle2=(MatrixX(i,1)+1)^2+MatrixX(i,2)^2;
    if(Circle1<2||Circle2<2)
        MatrixY(i)=1;
    end
end
Max1=max(max(MatrixX));
Max2=max(MatrixY);
Maxt=max(Max1,Max2);


%% 训练
NumHide=50;%%隐含层节点数
Yita1=0.8;%%学习率
Yita2=0.8;%%学习率
W1=2*rand(NumHide,2)-1*ones(NumHide,2);%%权值矩阵W1
W2=2*rand(1,NumHide)-1*ones(1,NumHide);%%权值矩阵W2
Sita1=(2*rand(NumHide,1)-1*ones(NumHide,1))';%%阀值矩阵
Sita2=2*rand(1,1)-1;%%阀值矩阵
Times=1;
TimesLimits=500000;
residual=zeros(TimesLimits,1);%%误差收敛情况
while(Times<=TimesLimits)
    for i=1:100
        DetaW1=zeros(NumHide,2);
        DetaW2=zeros(1,NumHide);
        DetaSita1=zeros(NumHide,1);
        DetaSita2=zeros(1,1);
        X1=MatrixX(i,:)/Maxt; %%归一化
        Y1=MatrixY(i)/Maxt;%%归一化
        %% 计算隐含层神经元
        NetX=X1*W1'+Sita1;%%1行10列 
        FNetX=NetX;
        F1NetX=NetX;%%f'(NetX)
        for j=1:NumHide
            FNetX(j)=1/(1+exp(-NetX(j)));
            F1NetX(j)=FNetX(j)*(1-FNetX(j));
        end  
        %% 计算输出层神经元
        NetY=FNetX*W2'+Sita2; 
        GNetY=1/(1+exp(-NetY));
        G1NetY=GNetY*(1-GNetY);
        residual(Times)=residual(Times)+sqrt((Y1-GNetY)^2); 
        %% 计算梯度
        Deta2=(Y1-GNetY)*G1NetY;%%1行1列  
        Deta1=Deta2*F1NetX.*W2;%%1行10列
        DetaW1=DetaW1+Yita1*Deta1'*X1;%%10行2列
        DetaW2=DetaW2+Yita2*Deta2*FNetX;%%一行十列
        DetaSita1=DetaSita1+Yita1*Deta1';
        DetaSita2=DetaSita2+Yita2*Deta2;
        %% 权值和阀值更新
        W1=W1+DetaW1;
        W2=W2+DetaW2;
        Sita1=Sita1+DetaSita1';
        Sita2=Sita2+DetaSita2;
    end
    Times=Times+1;   
end

%%  结果测试
sitas=0:0.01*pi:2*pi;
Xzixs=sqrt(2)*cos(sitas)-ones(1,201);
Yzixs=sqrt(2)*sin(sitas);
plot(Xzixs,Yzixs,'-');%%画1#圆
hold on;
Xzixs=sqrt(2)*cos(sitas)+ones(1,201);
Yzixs=sqrt(2)*sin(sitas);
plot(Xzixs,Yzixs,'-');%%画2#圆

TestX=6*rand(30,2)-3*ones(30,2);%%输入值
TestY=zeros(30,1);%%输出值
for i=1:30 
    X1=TestX(i,:)/Maxt;
    Net=X1*W1'+Sita1;
    FNet=Net;
    for j=1:NumHide
        FNet(j)=1/(1+exp(-Net(j)));
    end
    Netk=FNet*W2'+Sita2;
    GNet=1/(1+exp(-Netk));
    TestY(i)=GNet;
end
TestY=TestY*Maxt;

% 画测试点
for i=1:30
    if(TestY(i)>0.5)
        plot(TestX(i,1),TestX(i,2),'r*');
        hold on;
    else
        plot(TestX(i,1),TestX(i,2),'r.');
        hold on;
    end
end

实现效果

先画出区域范围,随机生成30个点,区域内的点标记为“*”,区域外的点标记为“.”,程序运行结果如下图示:
在这里插入图片描述
由上图可知,有3个圆圈范围内的点错误地标记为了“.”,其余点标记正确,正确率为90%。如果输入样本增多,就可以进一步提高正确率。

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用BP神经网络进行聚类的Python实现的示例: 首先,我们需要导入必要的库,包括numpy和sklearn: ```python import numpy as np from sklearn.cluster import KMeans ``` 然后,我们定义一个简单的BP神经网络类: ```python class BPNN: def __init__(self, input_size, hidden_size, output_size): self.input_size = input_size self.hidden_size = hidden_size self.output_size = output_size self.weights1 = np.random.randn(self.input_size, self.hidden_size) self.bias1 = np.random.randn(self.hidden_size) self.weights2 = np.random.randn(self.hidden_size, self.output_size) self.bias2 = np.random.randn(self.output_size) def sigmoid(self, x): return 1 / (1 + np.exp(-x)) def forward(self, x): z1 = np.dot(x, self.weights1) + self.bias1 a1 = self.sigmoid(z1) z2 = np.dot(a1, self.weights2) + self.bias2 a2 = self.sigmoid(z2) return a2 def loss(self, x, y): y_hat = self.forward(x) return np.sum((y - y_hat) ** 2) def train(self, x, y, lr): z1 = np.dot(x, self.weights1) + self.bias1 a1 = self.sigmoid(z1) z2 = np.dot(a1, self.weights2) + self.bias2 a2 = self.sigmoid(z2) delta2 = (a2 - y) * a2 * (1 - a2) delta1 = np.dot(delta2, self.weights2.T) * a1 * (1 - a1) self.weights2 -= lr * np.dot(a1.T, delta2) self.bias2 -= lr * np.sum(delta2, axis=0) self.weights1 -= lr * np.dot(x.T, delta1) self.bias1 -= lr * np.sum(delta1, axis=0) ``` 接下来,我们使用KMeans算法生成一些随机数据,并将其标准化: ```python data = np.random.randn(100, 2) data -= np.mean(data, axis=0) data /= np.std(data, axis=0) ``` 然后,我们使用KMeans算法将数据聚类成5个簇: ```python kmeans = KMeans(n_clusters=5) kmeans.fit(data) labels = kmeans.labels_ ``` 接下来,我们将每个数据点的标签转换为一个one-hot向量: ```python one_hot_labels = np.zeros((len(labels), 5)) for i, label in enumerate(labels): one_hot_labels[i, label] = 1 ``` 然后,我们将数据集分成训练集和测试集: ```python train_data = data[:80] train_labels = one_hot_labels[:80] test_data = data[80:] test_labels = one_hot_labels[80:] ``` 最后,我们训练一个BP神经网络并对测试数据进行预测: ```python bpnn = BPNN(input_size=2, hidden_size=10, output_size=5) for i in range(1000): bpnn.train(train_data, train_labels, lr=0.1) predictions = bpnn.forward(test_data) predicted_labels = np.argmax(predictions, axis=1) ``` 完整代码如下: ```python import numpy as np from sklearn.cluster import KMeans class BPNN: def __init__(self, input_size, hidden_size, output_size): self.input_size = input_size self.hidden_size = hidden_size self.output_size = output_size self.weights1 = np.random.randn(self.input_size, self.hidden_size) self.bias1 = np.random.randn(self.hidden_size) self.weights2 = np.random.randn(self.hidden_size, self.output_size) self.bias2 = np.random.randn(self.output_size) def sigmoid(self, x): return 1 / (1 + np.exp(-x)) def forward(self, x): z1 = np.dot(x, self.weights1) + self.bias1 a1 = self.sigmoid(z1) z2 = np.dot(a1, self.weights2) + self.bias2 a2 = self.sigmoid(z2) return a2 def loss(self, x, y): y_hat = self.forward(x) return np.sum((y - y_hat) ** 2) def train(self, x, y, lr): z1 = np.dot(x, self.weights1) + self.bias1 a1 = self.sigmoid(z1) z2 = np.dot(a1, self.weights2) + self.bias2 a2 = self.sigmoid(z2) delta2 = (a2 - y) * a2 * (1 - a2) delta1 = np.dot(delta2, self.weights2.T) * a1 * (1 - a1) self.weights2 -= lr * np.dot(a1.T, delta2) self.bias2 -= lr * np.sum(delta2, axis=0) self.weights1 -= lr * np.dot(x.T, delta1) self.bias1 -= lr * np.sum(delta1, axis=0) data = np.random.randn(100, 2) data -= np.mean(data, axis=0) data /= np.std(data, axis=0) kmeans = KMeans(n_clusters=5) kmeans.fit(data) labels = kmeans.labels_ one_hot_labels = np.zeros((len(labels), 5)) for i, label in enumerate(labels): one_hot_labels[i, label] = 1 train_data = data[:80] train_labels = one_hot_labels[:80] test_data = data[80:] test_labels = one_hot_labels[80:] bpnn = BPNN(input_size=2, hidden_size=10, output_size=5) for i in range(1000): bpnn.train(train_data, train_labels, lr=0.1) predictions = bpnn.forward(test_data) predicted_labels = np.argmax(predictions, axis=1) print("True Labels: ", np.argmax(test_labels, axis=1)) print("Predicted Labels: ", predicted_labels) ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值