手写BP神经网络和反向传播过程拟合一元二次函数

手写BP神经网络和反向传播过程拟合一元二次函数

题目要求

设计一个5层的全连接网络,损失函数自由,激励函数使用sigmoid/tanh/relu,反向传播过程自己写,不能使用pytorch框架的自动求导机制,目标是实现如下函数:
在这里插入图片描述

做法和思路

提示:题目需要五个隐藏层,我这里只画了两个。
在这里插入图片描述

具体实现

import numpy as np
import matplotlib.pyplot as plt


class LinearLayer: #创建线性层,用于初始化w、b,包括向前传播、向后反馈以及参数更新
    def __init__(self, input_D, output_D):
        self._W = 0.1*np.random.random(size=(input_D,output_D)) # 初始化不能为全0
        self._b = 0.1*np.random.random(size=(1, output_D))
        self._grad_W = np.zeros((input_D, output_D))
        self._grad_b = np.zeros((1, output_D))

	 #向前传播函数
    def forward(self, X): 
        return np.matmul(X,self._W) + self._b

	#向后反馈函数
    def backward(self, X, grad):
        self._grad_W = np.matmul(X.T,grad)
        self._grad_b = np.matmul(grad.T,np.ones(X.shape[0]))
        return np.matmul(grad, self._W.T)

	#更新参数
    def update(self, learn_rate):
        self._W = self._W - self._grad_W * learn_rate
        self._b = self._b - self._grad_b * learn_rate
        #print("更新后的w值为",self._W.sum())
        #print("更新后的b值为",self._b.sum())

#这里激活函数使用的是relu
class Relu:
    def __init__(self):
        pass

    def forward(self, X):
        return np.maximum(X,0)  #向前传播的时候如果是负数直接输出0

    def backward(self, X, grad):
        return np.where(X > 0, 1, 0) * grad  #向后反馈的时候如果是负数直接输出0,如果是正数则输出1

# 用训练好的模型预测
def train_model():
    x = np.arange(-5, 5)  #选择了10个数字
    y = x ** 2 + 2 * x - 3
    train_x = x.reshape(-1, 1)
    train_y = y.reshape(-1, 1)

    linear1 = LinearLayer(x.shape[0], 10) #初始化一个线性模块,w1=10*10
    relu1 = Relu()#初始化一个relu模块
    linear2 = LinearLayer(10, 10)#w2=10*10
    relu2 = Relu()
    linear3 = LinearLayer(10, 10)#w3=10*10
    relu3 = Relu()
    linear4 = LinearLayer(10, 10)#w4=10*10
    relu4 = Relu()
    linear5 = LinearLayer(10, x.shape[0])#w5=10*10

    for i in range(5000):
        # 向前传播
        a1 = linear1.forward(train_x.T)
        z1 = relu1.forward(a1)
        a2 = linear2.forward(z1)
        z2 = relu2.forward(a2)
        a3 = linear3.forward(z2)
        z3 = relu3.forward(a3)
        a4 = linear4.forward(z3)
        z4 = relu4.forward(a4)
        a5 = linear5.forward(z4)
        y_predict = a5

        # 获得网络输出,计算损失loss
        loss = 0.5 * np.square(y_predict - train_y.T)
        #print("原始值为",y)
        #print("预测值为",y_predict)


        # 反向传播
        loss = np.array(loss, dtype=float)
        grad = y_predict - train_y.T
        grad5 = linear5.backward(a5, grad)
        grad_5 = relu4.backward(z4, grad5)
        grad4 = linear4.backward(a4, grad_5)
        grad_4 = relu3.backward(z3, grad4)
        grad3 = linear3.backward(a3, grad_4)
        grad_3 = relu2.backward(z2, grad3)
        grad2 = linear2.backward(a2, grad_3)
        grad_2 = relu1.backward(z1, grad2)
        grad1 = linear1.backward(a1,grad_2)

        learn_rate = 1e-3  # 学习率

        # 更新网络中线性层的参数
        linear1.update(learn_rate)
        linear2.update(learn_rate)
        linear3.update(learn_rate)
        linear4.update(learn_rate)
        linear5.update(learn_rate)

        # 判断学习是否完成
        #if i % 10 == 0:  
        print("第",i+1,"轮的loss值为", loss.sum()/x.shape[0])
        if loss.sum()/x.shape[0] < 0.1:
            print("训练完成!")
            plt.scatter(x, y)
            plt.scatter(x,y_predict)
            plt.show()
            break

#开始训练
train_model()



#训练结果:
/homework1.py 
第 1 轮的loss值为 40.2350687060102252 轮的loss值为 40.1380553771679943 轮的loss值为 40.039741636955494 轮的loss值为 39.940010763706045 轮的loss值为 39.838734860458536 轮的loss值为 39.735773059413897 轮的loss值为 39.6309695384547858 轮的loss值为 39.5241513146189059 轮的loss值为 39.41512577221415410 轮的loss值为 39.3036778743862811 轮的loss值为 39.18956699596300612 轮的loss值为 39.07252330174850413 轮的loss值为 38.9522435773976814 轮的loss值为 38.828386398609615 轮的loss值为 38.70056649738603516 轮的loss值为 38.5683481498391917 轮的loss值为 38.4312373662774718 轮的loss值为 38.2886726080615919 轮的loss值为 38.1400136829630420 轮的loss值为 37.9845283759599221 轮的loss值为 37.821376248002522 轮的loss值为 37.6495888707909323 轮的loss值为 37.4680455464004824 轮的loss值为 37.2754432660667525 轮的loss值为 37.07025926335090626 轮的loss值为 36.85070397132055627 轮的loss值为 36.61466144068210628 轮的loss值为 36.3596132275217929 轮的loss值为 36.08254028522189630 轮的loss值为 35.779795301884231 轮的loss值为 35.4469349231275832 轮的loss值为 35.0784969557773733 轮的loss值为 34.6677013057492634 轮的loss值为 34.2060440796479635 轮的loss值为 33.6827405169121936 轮的loss值为 33.083952131172737 轮的loss值为 32.3917038715016538 轮的loss值为 31.5823553732123639 轮的loss值为 30.62443594653300540 轮的loss值为 29.47559658358701341 轮的loss值为 28.07842396871256342 轮的loss值为 26.35507511432583543 轮的loss值为 24.20166917099426544 轮的loss值为 21.4763462115089645 轮的loss值为 18.03379560783444246 轮的loss值为 13.79263093303413347 轮的loss值为 8.94033861219261548 轮的loss值为 4.2957741032547949 轮的loss值为 1.252142770010065650 轮的loss值为 0.252725582862237451 轮的loss值为 0.1030361686538888352 轮的loss值为 0.06051268329541225
训练完成!

Process finished with exit code 0

请添加图片描述
参考博客的链接:BP算法实现 作者:LifeBackwards

存在的问题

当输入层的个数是10个的时候,必须设置每一层隐藏层神经元的个数也是10个,否则在更新参数时会出现维度不匹配的问题。目前还没有想出很好的解决方案。哪位大佬能教教我,感谢!请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值