神经网络(vanilla ver.) in numpy

写在最前

vanilla neural network 学习材料有好多
前年年都是用MATLAB写的,写的还挺丑,后来用tensorflow写把底层细节都盖住了。
这里是一个只用numpy实现的版本

学习材料的话。MATLAB推荐王小川的 45个神经网络案例 第一章
数学推导推荐吴恩达的Ufldl 反向传导算法

这个推荐用jupyter玩,把train和inference分开,可以用同样的parameter测着玩

细节

activation function 的求导比较有技巧

sigmoid : 1/(1-exp(-x))
导数是fx*(1-fx)
fx是正向传播解出来的矩阵,为了高效计算,直接使用这个结果

tanh导数 1-(fx*fx)同理

要处理的问题就是逻辑:(a xor b) and c
也可以根据自己开心随便改,就是把改train_x 搞成相应的真值表。

traininference之间还可以加上文件读写来save parameter, 再load一部分回来做transfer learning(当然这已经是deep learning的套路了这个小网络没必要)

代码

import numpy as np

train_x = np.array([
    [0,0,1],
    [0,1,1],
    [1,0,1],
    [1,1,1],
    [0,0,0],
    [0,1,0],
    [1,0,0],
    [1,1,0]
])
train_y = np.array([
    [0],
    [1],
    [1],
    [0],
    [0],
    [0],
    [0],
    [0]
])

def _sigmoid(x,der = False):

    if der == True:
        return x*(1-x)

    return 1/(1+np.exp(-x))

def _tanh(x,der = False):

    if der == True:
        return 1-(x*x)

    return np.tanh(x)

def _relu(x,der = False):

    if der ==True:
        return 1*(x>0)

    return x*(x>0)


def train():

    i = 3
    o = 1

    # hyperparameter
    num = 50000
    h = 4

    #parameter
    syn0 = 2*np.random.random((i,h))-1
    syn1 = 2*np.random.random((h,o))-1

    for epoch in range(num):

        # feed forward
        l0 = train_x                             # (4,i)
        l1 = _sigmoid(l0.dot(syn0))              # (4,h)
        l2 = _sigmoid(l1.dot(syn1))              # (4,o)

        #loss
        loss = 1/2*(train_y - l2)**2

        # back propagate
        l2_err = train_y - l2                    # (4,o)
        l2_delta = l2_err*_sigmoid(l2,der=True)  # (4,o)
        l1_err = l2_delta.dot(syn1.T)            # (4,h)
        l1_delta = l1_err*_sigmoid(l1,der=True)  # (4,h)

        ## update parameter
        syn1 += l1.T.dot(l2_delta)
        syn0 += l0.T.dot(l1_delta)

        if epoch%1000 == 0:
            print(np.mean(loss))

    return syn0,syn1

def inference(syn0,syn1,x):

        l0 = x                                   # (4,i)
        l1 = _sigmoid(l0.dot(syn0))              # (4,h)
        l2 = _sigmoid(l1.dot(syn1))              # (4,o)

        return l2

test_x = np.array([0,1,1])

syn0,syn1 = train()
pre_y = inference(syn0,syn1,test_x)
print(pre_y)

你可能感兴趣的:(深度学习,python,机器学习)