Code | 三层神经网络+BP(单样本+批量)

"""
数据
1.58 2.32 -5.8 0
0.67 1.58 -4.78 0
1.04 1.01 -3.63 0
-1.49 2.18 -3.39 0
-0.41 1.21 -4.73 0
1.39 3.16 2.87 0
1.20 1.40 -1.89 0
-0.92 1.44 -3.22 0
0.45 1.33 -4.38 0
-0.76 0.84 -1.96 0
0.21 0.03 -2.21 1
0.37 0.28 -1.8 1
0.18 1.22 0.16 1
-0.24 0.93 -1.01 1
-1.18 0.39 -0.39 1
0.74 0.96 -1.16 1
-0.38 1.94 -0.48 1
0.02 0.72 -0.17 1
0.44 1.31 -0.14 1
0.46 1.49 0.58 1
-1.54 1.17 0.64 2
5.41 3.45 -1.33 2
1.55 0.99 2.69 2
1.86 3.19 1.51 2
1.68 1.79 -0.87 2
3.51 -0.22 -1.39 2
1.40 -0.44 -0.92 2
0.44 0.83 1.97 2
0.25 0.68 -0.99 2
0.66 -0.45 0.08 2
"""

import numpy as np
import matplotlib.pyplot as plt


def tanh(x):
    return (1 - np.exp(-2*x))/(1 + np.exp(-2*x))


def sigmoid(x):
    return 1/(1 + np.exp(-1*x))


"""
     *
*    *    *
*    *    *
*    *    *
     *
"""


class Net():
    def __init__(self, input_num=3, hidden_num=5, output_num=3):
        self.w1 = np.random.randn(hidden_num, input_num)
        self.w2 = np.random.randn(output_num, hidden_num)
        self.h1 = []
        self.out = []
        self.one_hot = np.eye(output_num)

    def forward(self, input):
        self.h1 = tanh(np.matmul(self.w1, np.array(input)))
        self.out = sigmoid(np.matmul(self.w2, self.h1))
        return self.out

    def MSE_loss(self, input, label):
        out = self.forward(input)
        loss = np.square(out-self.one_hot[int(label)])
        return np.sum(loss)

    def grad_prepare(self, input, label):
        self.forward(input)

        # sigmoid' : y(1-y)
        # MSE_loss' :2(out-label)
        # tanh' :1-tanh(x)^2

        delta_out = self.out*(np.ones_like(self.out)-self.out)*2*(self.out-self.one_hot[int(label)])
        delta_hidden = np.matmul(self.w2.T, delta_out)*(1-np.square(tanh(np.matmul(self.w1, input))))
        grad_w2 = np.matmul(delta_out.reshape(-1, 1), self.h1.reshape(1, -1))
        # print("grad_w2.shape:", grad_w2.shape)
        grad_w1 = np.matmul(delta_hidden.reshape(-1, 1), np.array(input).reshape(1, -1))
        # print("grad_w1.shape:", grad_w1.shape)
        return grad_w1, grad_w2

    def single_train_step(self, input, label, lr=1e-3):
        grad_w1, grad_w2 = self.grad_prepare(input, label)
        self.w1 = self.w1 - lr * grad_w1
        self.w2 = self.w2 - lr * grad_w2

    def batch_train_step(self, input, label, lr=1e-3):
        input = np.array(input)
        label = np.array(label)
        grad_w1_b = 0
        grad_w2_b = 0

        for i in range(input.shape[0]):
            # print(input[i])
            grad_w1, grad_w2 = self.grad_prepare(input[i], label[i])
            grad_w1_b += grad_w1
            grad_w2_b += grad_w2

        self.w1 = self.w1 - lr * grad_w1_b
        self.w2 = self.w2 - lr * grad_w2_b

    def eval(self, input, label):
        pred = []
        input = np.array(input)
        label = np.array(label)
        for i in range(input.shape[0]):
            out = self.forward(input[i])
            pred.append(np.argmax(out))
        acc = (pred == label).sum() / len(label)
        print("acc:", acc)
        return acc


if __name__ == "__main__" :

    net = Net()
    x = np.loadtxt('data.txt')
    BATCH_TRAIN = True
    loss_list = []

    for i in range(4000):
        if not BATCH_TRAIN:
            for k in range(len(x)):
                loss = net.MSE_loss(x[k, 0:3], x[k, 3])
                loss_list.append(loss)
                print(i, k, loss)
                net.single_train_step(x[k, 0:3], x[k, 3], lr=1e-2)
        else:
            loss = []
            for j in range(len(x)):
                e = net.MSE_loss(x[j, 0:3], x[j, 3])
                loss.append(e)
            loss_list.append(sum(loss))
            print(i, sum(loss))
            net.batch_train_step(x[:, 0:3], x[:, 3], lr=1e-3)

    net.eval(x[:, 0:3], x[:, 3])
    plt.plot([i for i in range(len(loss_list))], loss_list)
    plt.show()






 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值