美文网首页
Chapter 03 神经网络

Chapter 03 神经网络

作者: 蜜糖_7474 | 来源:发表于2019-02-26 17:28 被阅读0次

    略去一些有关神经网络和激活函数的相关概念,本人在读这本书的时候已有一定的基础。

    简单的阶跃函数的实现

    def step_function(x):
        if x > 0:
            return 1
        else:
            return 0
    

    显然上述函数不能接受形如np.array数组作为参数,需加以改造

    def step_function(x):
        x = x > 0
        return x.astype(np.int)
    
    x=np.array([-2,1,3,-9])
    print(step_function(x))
    print(x)
    

    [0 1 1 0]
    [-2 1 3 -9]

    一步步看这个函数做了什么

    x=np.array([-2,1,3,-9])
    x=x>0
    print(x)
    x=x.astype(np.int)
    print(x)
    

    [False True True False]
    [0 1 1 0]

    画一个阶跃函数的图形

    def step_function(x):
        return (x > 0).astype(np.int)
        #return np.array(x>0, dtype=np.int)  这样写也可以
    
    x = np.arange(-5, 5, 0.1)
    y = step_function(x)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.title('step_function')
    plt.ylim(-0.1, 1.1)
    plt.plot(x, y)
    plt.show()
    
    阶跃函数

    sigmoid函数实现并绘制

    def sigmoid(x):
        return 1.0 / (1 + np.exp(-x))
    
    y1 = step_function(x)
    y2 = sigmoid(x)
    plt.xlabel('x')
    plt.ylabel('y')
    plt.title('sigmoid & step')
    plt.ylim(-0.1, 1.1)
    plt.plot(x, y1,label='step',linestyle='--')
    plt.plot(x, y2,label='sigmoid')
    plt.show()
    
    sigmoid函数

    ReLU函数是近年来的常用激活函数

    def ReLU(x):
        #np.maximum函数会从输入的数值中选择较大的那个值进行输出
        return np.maximum(0,x)
    
    y=ReLU(x)
    plt.plot(x,y)
    plt.show()
    
    ReLU函数

    有关多维数组的基本概念

    A = np.array([1, 2, 3, 4, 5])
    B = np.array([[5, 6], [7, 7], [9, 0]])
    print(A.shape)  #返回一个元组
    print(np.ndim(A))  #获取A的维度
    print(A.shape[0])
    print(np.ndim(B))
    print(B.shape[1])  #查看元组的第二个元素
    

    (5,)
    1
    5
    2
    2

    有关矩阵乘法

    C = np.array([[3, 1, 1], [5, 6, 7]])
    print(C.shape)
    print(np.dot(B, C))
    print(np.dot(C, B))
    

    (2, 3)
    [[45 41 47]
    [56 49 56]
    [27 9 9]]
    [[ 31 25]
    [130 72]]

    实现一个如下图所示三层神经网络

    3层神经网络:输入层(第0层)有2个神经元,第1个隐藏层(第1层)有3个神经元,第2个隐藏层(第2层)有2个神经元,输出层(第3层)有2个神经元
    X = np.array([1.0, 0.5])
    
    W1 = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
    B1 = np.array([0.1, 0.2, 0.3])
    
    A1 = np.dot(X, W1) + B1
    Z1 = sigmoid(A1)
    
    W2 = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
    B2 = np.array([0.1, 0.2])
    
    A2 = np.dot(Z1, W2) + B2
    Z2 = sigmoid(A2)
    
    W3 = np.array([[0.1, 0.3], [0.2, 0.4]])
    B3 = np.array([0.1, 0.2])
    A3 = np.dot(Z2, W3) + B3  #这个例子A3即为输出
    
    print(A3)
    

    [0.31682708 0.69627909]

    整理代码,只把权重记为大写字母,偏置量或中间结果用小写字母表示

    def identity_function(x):  #将“恒等函数”作为输出层的激活函数
        return x
    
    def init_network():
        network = {}  #新建空字典
        network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
        network['b1'] = np.array([0.1, 0.2, 0.3])
        network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
        network['b2'] = np.array([0.1, 0.2])
        network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])
        network['b3'] = np.array([0.1, 0.2])
        return network
    
    def forward(network, x):  #接受一个网络结构和输入
        W1, W2, W3 = network['W1'], network['W2'], network['W3']
        b1, b2, b3 = network['b1'], network['b2'], network['b3']
        a1 = np.dot(x, W1) + b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, W2) + b2
        z2 = sigmoid(a2)
        a3 = np.dot(z2, W3) + b3
        y = identity_function(a3)
        return y
    
    network = init_network()
    x = np.array([1.0, 0.5])
    y = forward(network, x)
    print(y)
    

    [0.31682708 0.69627909]

    之前用了恒等函数作为输出层的激活函数,现在看一下另一种函数——softmax

    def softmax(y):
        exp_y = np.exp(y)
        exp_sum = np.sum(exp_y)
        return exp_y / exp_sum
    
    a = np.array([0.3, 2.9, 4.0])
    print(softmax(a))
    

    [0.01821127 0.24519181 0.73659691]

    softmax的指数运算可能发生数据溢出,可改进如下

    def softmax(y):
        c = np.max(y)
        exp_y = np.exp(y - c)
        exp_sum = np.sum(exp_y)
        return exp_y / exp_sum
    

    手写体识别数据集mnist

    #我将本程序与mmnis.py放入同一文件夹内
    from mnist import load_mnist
    #flatten为True意味着28*28的图像展开为一维数组,为False则输入图像为1×28×28的三维数组
    (x_train, y_train), (x_test, y_test) = load_mnist(
        flatten=True, normalize=False)
    print(x_train.shape)
    print(y_train.shape)
    print(x_test.shape)
    print(y_test.shape)
    

    (60000, 784)
    (60000,)
    (10000, 784)
    (10000,)

    显示数据集的第一张图片

    from PIL import Image
    
    def img_show(img):
        #把numpy数组的图像数据转换为PIL用的数据对象
        pil_img = Image.fromarray(np.uint8(img))
        pil_img.show()
    
    img = x_train[0]
    label = y_train[0]
    print(label)
    print(img.shape)
    img = img.reshape(28, 28)
    print(img.shape)
    
    img_show(img)
    

    5
    (784,)
    (28, 28)


    我们假设已经完成模型的训练,参数存储在sample_weight.pkl这个随书附赠的文件中,我们直接调用这个文件

    import pickle
    
    def get_data():
        (x_train, y_train), (x_test, y_test) = load_mnist(
            flatten=True, normalize=True, one_hot_label=False)
        return x_test, y_test
    
    
    def init_network():
        f = open('sample_weight.pkl', 'rb')
        network = pickle.load(f)
        return network
    
    
    def predict(network, x):
        W1, W2, W3 = network['W1'], network['W2'], network['W3']
        b1, b2, b3 = network['b1'], network['b2'], network['b3']
        a1 = np.dot(x, W1) + b1
        z1 = sigmoid(a1)
        a2 = np.dot(z1, W2) + b2
        z2 = sigmoid(a2)
        a3 = np.dot(z2, W3) + b3
        y = softmax(a3)
        return y
    

    查看模型准确率

    x, y = get_data()
    network = init_network()
    acc_cnt = 0
    y_pred = predict(network, x)
    print(y_pred.shape)
    y_pred = np.argmax(y_pred, axis=1)  #获取每一行的最大值索引
    print('图像识别成功率' + str(np.sum(np.array(y_pred == y, dtype=np.int)) / len(y)))
    

    (10000, 10)
    图像识别成功率0.9352

    批处理在后续参数调优时有重大意义,这里简单介绍一下批处理

    x, y = get_data()
    network = init_network()
    
    batch_size = 100 #一次批量处理100张图片
    acc_cnt=0
    
    for i in range(0,len(x),batch_size):
        x_batch = x[i:i+batch_size]
        y_batch = predict(network,x_batch)
        p=np.argmax(y_batch,axis=1)
        acc_cnt += np.sum(p==y[i:i+batch_size])
    
    print('图像识别成功率:' + str(acc_cnt / len(x)))
    

    图像识别成功率:0.9352

    相关文章

      网友评论

          本文标题:Chapter 03 神经网络

          本文链接:https://www.haomeiwen.com/subject/xrnbyqtx.html