找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 2059|回复: 1

[求助] 自己手写的BP算法,但是误差一直不收敛

1

主题

2

帖子

2

积分

贫民

积分
2
杰森·家乐森 发表于 2019-8-24 13:51:18 | 显示全部楼层 |阅读模式

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import json
import time


# 定义sigmoid函数
def logistic(x):
    return 1 / (1 + np.exp(-x))


# sigmoid导数
def logistic_derivative(x):
    return logistic(x) * (1 - logistic(x))


# 归一化函数
def normal(dataset):
    value_min = dataset.min(0)
    value_max = dataset.max(0)
    m = dataset.shape[0]
    ranges = value_max - value_min
    normal_dataset = (dataset - np.tile(value_min, (m, 1))) / np.tile(ranges, (m, 1))
    return normal_dataset


# SPE函数
def spe(e):
    square_sum = 0
    for k in range(len(e)):
        square_sum += e[k] ** 2
    return np.sqrt(square_sum) / len(e)


class AutoAssociativeNeuralNetwork:
    def __init__(self, layers):
        """
        自联想神经网络构造函数
        :param layers: 神经元层数
        """
        # 初始化权重和偏置
        self.weight = []
        self.bias = []
        self.m = []
        self.v = []
        self.beta = 0.9
        for i in range(1, len(layers)):
            self.weight.append(np.random.randn(layers, layers[i - 1]) * np.sqrt(2 / layers[i - 1]))
            self.bias.append(np.zeros([layers, 1]))
            self.m.append(np.zeros([layers, layers[i - 1]]))
            self.v.append(np.zeros([layers, 1]))

    def train(self, x, epochs=80000, learning_rate=0.001):
        """
        训练神经网络
        :param x: 样本输入
        :param epochs: 训练次数
        :param learning_rate: 学习率
        :return:
        """
        # 确保样本输入为二维
        x = np.atleast_2d(x)
        s = []
        for i in range(epochs):
            # 随机抽取一行
            k = np.random.randint(x.shape[0])
            a = [np.atleast_2d(x[k]).T]
            # 正向更新
            for l in range(len(self.weight)):
                a.append(logistic(np.dot(self.weight[l], a[l]) + self.bias[l]))
            error = a[-1] - a[0]
            deltas = [np.multiply(logistic_derivative(a[-1]), error)]
            s.append(spe(error))
            # 反向更新
            for l in range(len(a) - 2, 0, -1):
                deltas.append(np.multiply(np.dot(self.weight[l].T, deltas[-1]), logistic_derivative(a[l])))
            deltas.reverse()

            for l in range(len(self.weight)):
                self.m[l] = self.beta * self.m[l] + (1 - self.beta) * np.dot(deltas[l], a[l].T)
                self.v[l] = self.beta * self.v[l] + (1 - self.beta) * deltas[l]
                self.weight[l] = self.weight[l] - learning_rate * self.m[l]
                self.bias[l] = self.bias[l] - learning_rate * self.v[l]

        plt.plot(s)
        plt.show()


if __name__ == "__main__":
    data = np.array(pd.read_excel("测试数据.xlsx"))
    normal_data = normal(data)
    layer = [13, 9, 3, 9, 13]
    auto_associative_neural_network = AutoAssociativeNeuralNetwork(layer)
    start = time.time()
    auto_associative_neural_network.train(normal_data)
    model = {"weight": [],
             "bias": []}
    for j in range(len(auto_associative_neural_network.weight)):
        model["weight"].append(auto_associative_neural_network.weight[j].tolist())
        model["bias"].append(auto_associative_neural_network.bias[j].tolist())
    end = time.time()
    print(start, end)
    with open("model.json", 'w', encoding='utf-8') as json_file:
        json.dump(model, json_file, ensure_ascii=False)

回复

使用道具 举报

1

主题

2

帖子

2

积分

贫民

积分
2
杰森·家乐森  楼主| 发表于 2019-8-24 13:54:54 | 显示全部楼层
spe的图居然是振荡的,请问有大佬知道是哪里不对吗?

spe的图居然是这样的

spe的图居然是这样的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表