深度学习

简单神经网络实现

2018-08-21  本文已影响129人  筱黎黎

训练一个神经网络

隐藏层维度可以选择,隐藏层节点越多,实现的功能就越复杂,但是维度过高也是会有代价的。

我们的网络是如何做出预测的呢?

神经网络是通过前向传播做出预测。如果该网络的输入x是二维的,那么我们可以通过以下方法来计算预测值y
z1=xW1+b1

a1=tanh(z1)

z2=a1W2+b2

a2=y=softmax(z2)

Zi表示第i层的输入,ai表示应用激活函数后的输出。Wi,bi表示需要我们通过训练数据来获取的神经网络参数,可以把它们当做网络层与层之间之间用于转化数据的矩阵。

每个神经元有两个单元组成。一个是权重和输入信号。另一个是非线性单元,叫做激励函数。信号e是激励信号。y = f(e) 是非线性单元的输出,即是神经元的输出。


为了训练神经网络,我们需要训练数据。训练数据由输入信号(x1和x2 )和期望输出z组成。网络的训练过程是一个迭代处理的过程。训练数据集用来在每次迭代过程中更新神经元的权重。每次学习过程由来自训练数据的输入信号开始。我们可以得出每一层的输出。下图说明信号在神经网络的传输路线。w(xm)n 是神经元xm 在第n层输入的连接权重。 yn 表示神经元n的输出。
#定义一些变量和参数,用于梯度下降算法
num_examples=len(X)
nn_input_dim=2#input layer dimensionality
nn_output_dim=2#output layer dimensionality

#grandient descent parameters
epsilon=0.01#learning rate for grandient descent学习率
reg_lambda=0.01#regularization strength正则化强度

网络如何做出预测

zi是第i层的输入,ai是该层应用激活函数后的输出i,Wi,bi是需要我们通过训练数据来获取的神经网络参数,你可以把它们当作在网络的层与层之间用于转化数据的矩阵。这些矩阵的维度可以通过上面的矩阵乘法看出来。如果我们在隐藏层上使用500个节点,那么就有 ,隐藏层的规模与可以用在隐藏层的节点数是呈正相关的。

实现基本的三层神经网络

这个公式的功能就是对我们的训练示例进行求和,并加上预测值错误造成的损失。所以,标签值y与预测值

相差越大,损失就越大。

def calculate_loss(model):
    W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
    # Forward propagation to calculate our predictions
    z1 = X.dot(W1) + b1
    a1 = np.tanh(z1)
    z2 = a1.dot(W2) + b2
   
    #计算Softmax
    exp_scores = np.exp(z2)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)

    #计算损失函数 loss
    corect_logprobs = -np.log(probs[range(num_examples), y])#对Softmax取对数
    data_loss = np.sum(corect_logprobs)#损失函数为各输出值的的和

    # Add regulatization term to loss (optional)加入L2正则化项,lambda是正则化参数
    data_loss += reg_lambda/2 * (np.sum(np.square(W1)) + np.sum(np.square(W2)))
    return 1./num_examples * data_loss#?这一句什么意思?

Softmax公式 假设多分类问题,C=4,现行分类模型最后输出层包含四个输出值,分别是 经过Softmax处理后,数值转化成相对概率 Softmax将数值转化成概率,更有利于理解。 L2正则化 其中

是正则项,lambda是正则化参数。

实现一个用于计算输出的辅助函数

def predict(model, x):
    W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
    # Forward propagation
    z1 = x.dot(W1) + b1
    a1 = np.tanh(z1)
    z2 = a1.dot(W2) + b2
    exp_scores = np.exp(z2)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
    return np.argmax(probs, axis=1) #返回最大值

训练神经网络的函数

为了计算这些梯度,我们使用后向传播算法,这种方法通过输出计算梯度效率很高。(后向传播算法可参见http://galaxy.agh.edu.pl/~vlsi/AI/backp_t_en/backprop.html或者https://www.cnblogs.com/charlotte77/p/5629865.html))。

# This function learns parameters for the neural network and returns the model.
# - nn_hdim: Number of nodes in the hidden layer
# - num_passes: Number of passes through the training data for gradient descent
# - print_loss: If True, print the loss every 1000 iterations
num_example=len(X)
def build_model(nn_hdim, num_passes=20000, print_loss=False):
 
    # Initialize the parameters to random values. We need to learn these.
    np.random.seed(0)
    w1 = np.random.randn(nn_input_dim, nn_hdim) / np.sqrt(nn_input_dim)
    b1 = np.zeros((1, nn_hdim))
    w2 = np.random.randn(nn_hdim, nn_output_dim) / np.sqrt(nn_hdim)
    b2 = np.zeros((1, nn_output_dim))
 
    # This is what we return at the end
    model = {}
 
    # Gradient descent. For each batch...
    for i in range(0, num_passes):
 
        # Forward propagation
        z1 = X.dot(w1) + b1
        a1 = np.tanh(z1)
        z2 = a1.dot(w2) + b2
        exp_scores = np.exp(z2)
        probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
 
        # Backpropagation
        delta3 = probs
        delta3[range(num_example), y] -= 1
        dw2 = (a1.T).dot(delta3)
        db2 = np.sum(delta3, axis=0, keepdims=True)
        delta2 = delta3.dot(w2.T) * (1 - np.power(a1, 2))
        dw1 = np.dot(X.T, delta2)
        db1 = np.sum(delta2, axis=0)
 
        # Add regularization terms (b1 and b2 don't have regularization terms)
        dw2 += reg_lambda * w2
        dw1 += reg_lambda * w1
 
        # Gradient descent parameter update参数更新
        w1 += -epsilon * dw1
        b1 += -epsilon * db1
        w2 += -epsilon * dw2
        b2 += -epsilon * db2
 
        # Assign new parameters to the model
        model = { 'w1': w1, 'b1': b1, 'w2': w2, 'b2': b2}
 
        # Optionally print the loss.
        # This is expensive because it uses the whole dataset, so we don't want to do it too often.
        if print_loss and i % 1000 == 0:
            print ("Loss after iteration %i: %f" %(i, calculate_loss(model)))
 
    return model
# Build a model with a 3-dimensional hidden layer
model = build_model(3, print_loss=True)
 
# Plot the decision boundary
plot_decision_boundary(lambda x: predict(model, x))
plt.title("Decision Boundary for hidden layer size 3")
plt.show()

可以参考http://www.mamicode.com/info-detail-1567638.html

上一篇 下一篇

猜你喜欢

热点阅读