Python手写神经网络之(一)BP神经网络

目的

  在学习完BP神经网络的推导后,我会用python(不带深度学习框架!)自己手写出一个简单的BP神经网络,以此加深对神经网络的理解,同时欢迎大家指出问题,一起学习与讨论~

设计思路

  本次我只使用了numpy库,为了简明易懂,使用类封装的方法,做了一个含有:四节点输入层,五节点的隐藏层,与一节点输出层的BP神经网络。
  这个神经网络的学习目标是将输入层的前两个数字之和与后两个数字之和相比较,结果为大于则输出1,小于就输出0。(这个学习目标对于神经网络可以说是非常地简单了)
  我首先定义了一个BP神经网络的类,它包含初始化函数,激励函数,前向传播函数以及后向传播函数。然后写了一个数据集生成的函数,为了制造我们所需要的数据和它对应的输出。最后,在主函数中,我们定义好数据大小,batch size,学习率以及最大迭代次数就可以跑起来啦!

代码以及结果

代码实现

import numpy as np

class BP_network(object):
    #The network is like:
    #    l0 -> w1 -> l1 -> w2 -> (l2 == y?)
    def __init__(self):
        # 4 node in input layer
        # 5 node in the hidden layer
        self.w1 = 2*np.random.random((4, 5)) - 1                                     # (4, 5)
        # 1 node for output layer
        self.w2 = 2*np.random.random((5, 1)) - 1                                     # (5, 1)

    def sigmoid(self, x, deriv=False):
        if deriv == True:
            return x * (1-x)
        return 1/(1+np.exp(-x))

    def forward_prop(self, input_data):
        self.l0 = input_data
        self.l1 = self.sigmoid(np.array(np.dot(self.l0, self.w1), dtype=np.float32)) # (batch_sz , 5)
        self.l2 = self.sigmoid(np.array(np.dot(self.l1, self.w2), dtype=np.float32)) # (batch_sz , 1)
        l2_error = label[st_idx:ed_idx] - self.l2                                    # (batch_sz , 1)
        return self.l2, l2_error

    def backward_prop(self, output_error):
        l2_error = output_error
        l2_delta = l2_error * self.sigmoid(self.l2, True)                            # (batch_sz , 1)
        l1_delta = np.dot(l2_delta, self.w2.T) * self.sigmoid(self.l1, True)         # (batch_sz , 5)
        self.w2 += lr * np.array(np.dot(self.l1.T, l2_delta), dtype=np.float32)      # (5 , 1)
        self.w1 += lr * np.array(np.dot(self.l0.T, l1_delta), dtype=np.float32)      # (4 , 5)

# data  :  [x0, x1, x2, x3]
# label :  x0 + x1 - x2 - x3 > 0? 1 : 0
def generate_data(data_size):
    data = np.empty((1, 4), dtype=object);
    label = np.empty((1, 1), dtype=object)
    for i in range(0, data_size):
        x = np.array([np.random.randint(0, 10, size=4)])
        res = int((x[0][0]+x[0][1] -x[0][2]-x[0][3])>0)
        y = np.array([[res]])
        data = np.concatenate((data, x), axis=0)
        label = np.concatenate((label, y), axis=0)
    return data[1:], label[1:]

if __name__ == '__main__':
    # size of data, batch size
    data_size = 100; batch_sz = 10;
    # learning rate, max iteration
    lr = 0.1;      max_iter = 5000;
    data, label = generate_data(data_size)
    NN = BP_network()
    for iters in range(max_iter):
        # starting index and ending index for fetching data
        st_idx = (iters % 10) * batch_sz; ed_idx = st_idx + batch_sz
        input_data = data[st_idx : ed_idx]
        outcome, output_error = NN.forward_prop(input_data)
        if iters % 450 == 0:
            print "The loss is %f" % (np.mean(np.abs(output_error)))
            #print output_error.tolist()
            continue
        NN.backward_prop(output_error)

运行结果

The loss is 0.585963
The loss is 0.095126
The loss is 0.071693
The loss is 0.057002
The loss is 0.047533
The loss is 0.041154
The loss is 0.036482
The loss is 0.032900
The loss is 0.030066
The loss is 0.027768
The loss is 0.025866
The loss is 0.024263
[Finished in 0.6s]

  看,这个loss在不断下降!有兴趣的话大家也可打印出神经网络的输出与真实结果相比较,发现神经网络确实是在不断学习的~
  (下一节,用python手写实现卷积神经网络,请大家敬请期待!)

发布了40 篇原创文章 · 获赞 44 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/Site1997/article/details/79189299