美文网首页我爱编程
梯度下降法及多层感知器

梯度下降法及多层感知器

作者: ibunny | 来源:发表于2017-08-16 13:42 被阅读150次

梯度下降

之前我们看到一个权重的更新方法是:

​​
  1. 训练数据中的每一条记录:
  • 通过网络做正向传播,计算输出
  • 计算输出的 error term,
  • 更新权重步长
  1. 更新权重

η 是学习率, m 是数据点个数。 这里我们对权重步长做了平均,为的是降低训练数据中大的变化。

  1. 重复 e 次(epoch)。

你也可以选择每一个记录更新一下权重,而不是把所有记录都训练过之后再取平均。
这里我们还是使用 sigmoid 作为激活函数:

sigmoid 的梯度是:

h 从输入计算的输出,

用 NumPy 来实现

这里大部分都可以用 NumPy 很方便的实现。

首先你需要初始化权重。我们希望它们比较小,这样输入在 sigmoid 函数那里可以在接近 0 的位置,而不是最高或者最低处。很重要的一点是要随机地初始化它们,这样它们有不同的值,是发散且不对称的。所以我们从一个中心为 0 的正态分布来初始化权重。一个好的标准差的值是 1/√​n​​​,这里 n 是输入的个数。这样就算是输入个数变多,进到 sigmoid 的输入还能保持比较小。

weights = np.random.normal(scale=1/n_features**.5, size=n_features)

NumPy 提供了一个可以让两个序列做点乘的函数,它可以让我们方便地计算 h。点乘是把两个序列的元素对应位置相乘之后再相加。

# input to the output layer
output_in = np.dot(weights, inputs)

最后我们更新 Δw​i​​和 w​i​​。

编程练习

接下来,你要实现一个梯度下降,用录取数据(binary.csv)来训练它。你的目标是训练一个网络直到你达到训练数据的最小的均方差mean square error (MSE)。你需要实现:

  • 网络的输出: output
  • 输出误差: error
  • 误差项: error_term
  • 权重更新步长: del_w +=
  • 更新权重: weights +=

你可以任意调节超参数 hyperparameters 来看下它对均方差 MSE 有什么影响。

train_gradient_descent.py

import numpy as np
from data_prep import features, targets, features_test, targets_test

# Practice implementing gradient descent and training the network on
# an admissions dataset. The goal of the exercise is to train the network
# until reaching the minimum mean sqauared error.
#
# Based on an exercise from Udacity.com
###################################################################

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

# Use to same seed to make debugging easier
np.random.seed(42)

n_records, n_features = features.shape
last_loss = None

# Initialize weights
weights = np.random.normal(scale=1 / n_features**.5, size=n_features)

# Neural Network hyperparameters
epochs = 1000
learnrate = 0.5

for e in range(epochs):
    del_w = np.zeros(weights.shape)
    for x, y in zip(features.values, targets):
        # Loop through all records, x is the input, y is the target

        output = sigmoid(np.dot(weights, x))

        error = y - output

        del_w += error * output * (1 - output) * x 

    weights += learnrate * del_w / n_records

    # Printing out the mean square error on the training set
    if e % (epochs / 10) == 0:
        out = sigmoid(np.dot(features, weights))
        loss = np.mean((out - targets) ** 2)
        if last_loss and last_loss < loss:
            print("Train loss: ", loss, "  WARNING - Loss Increasing")
        else:
            print("Train loss: ", loss)
        last_loss = loss

# Calculate accuracy on test data
tes_out = sigmoid(np.dot(features_test, weights))
predictions = tes_out > 0.5
accuracy = np.mean(predictions == targets_test)
print("Prediction accuracy: {:.3f}".format(accuracy))

data_prep.py

import numpy as np
import pandas as pd

admissions = pd.read_csv('binary.csv')

# Make dummy variables for rank
data = pd.concat([admissions, pd.get_dummies(admissions['rank'], prefix='rank')], axis=1)
data = data.drop('rank', axis=1)

# Standarize features
for field in ['gre', 'gpa']:
    mean, std = data[field].mean(), data[field].std()
    data.loc[:,field] = (data[field]-mean)/std

# Split off random 10% of the data for testing
np.random.seed(42)
sample = np.random.choice(data.index, size=int(len(data)*0.9), replace=False)
data, test_data = data.ix[sample], data.drop(sample)

# Split into features and targets
features, targets = data.drop('admit', axis=1), data['admit']
features_test, targets_test = test_data.drop('admit', axis=1), test_data['admit']


多层感知器

实现隐藏层

之前我们研究的是有一个输出节点网络,代码也很直观。但是现在我们有不同的输入,多个隐藏层,他们的权重需要有两个索引 w​ij​​,i 表示输入单位,j 表示隐藏单位。
例如在下面这个网络图中,输入被标注为 x​1​​,x​2​​, x​3​​,隐藏层节点是 h​1​​ 和 h​2​​。


注意:
这里权重的索引在上图中做了改变,与之前图片并不匹配。这是因为,在矩阵标注时行索引永远在列索引之前,所以用之前的方法做标识会引起误导。你只需要了解这跟之前的权重矩阵是一样的,只是做了转换,之前的第一列现在是第一行,之前的第二列现在是第二行。如果用之前的标记,权重矩阵是下面这个样子的:

用之前的标记标注的权重矩阵用之前的标记标注的权重矩阵

切记,上面标注方式是不正确的,这里只是为了让你更清楚这个矩阵如何跟之前神经网络的权重匹配。

矩阵相乘最重要的是他们的维度相匹配。因为它们在点乘时需要有相同数量的元素。在第一个例子中,输入向量有三列,权重矩阵有三行;第二个例子中,权重矩阵有三列,输入向量有三行。如果维度不匹配,你会得到:

# Same weights and features as above, but swapped the order
hidden_inputs = np.dot(weights_input_to_hidden, features)
---------------------------------------------------------------------------
ValueError                  Traceback(most recent call last)
<ipython-input-11-1bfa0f615c45> in <module>()
----> 1 hidden_in = np.dot(weights_input_to_hidden, X)

ValueError: shapes (3,2) and (3,) not aligned: 2 (dim 1) != 3 (dim 0)

3x2 的矩阵跟 3 个元素序列是没法相乘的。因为矩阵中的两列与序列中的元素个数并不匹配。能够相乘的矩阵如下:

这里的规则是,如果是序列在左边,序列的元素个数必须与右边矩阵的行数一样。如果矩阵在左边,那么矩阵的列数,需要与右边向量的行数匹配。

构建一个列向量
看上面的介绍,你有时会需要一个列向量,尽管 NumPy 默认是行向量。你可以用 arr.T 来对序列进行转制,但对一维序列来说,转制还是行向量。所以你可以用 arr[:,None] 来创建一个列向量:

print(features)
> array([ 0.49671415, -0.1382643 , 0.64768854])

print(features.T)
> array([ 0.49671415, -0.1382643 , 0.64768854])

print(features[:, None])
> array([[ 0.49671415], [-0.1382643 ], [ 0.64768854]])

当然,你可以创建一个二维序列,然后用 arr.T 得到列向量。

np.array(features, ndmin=2)
> array([[ 0.49671415, -0.1382643 , 0.64768854]])

np.array(features, ndmin=2).T
> array([[ 0.49671415], [-0.1382643 ], [ 0.64768854]])

编程练习
实现一个 4x3x2 网络的正向传播,用 sigmoid 作为两层的激活函数。
要做的事情:

  • 计算到隐藏层的输入
  • 计算隐藏层输出
  • 计算输出层的输入
  • 计算神经网络的输出
import numpy as np

N_input = 4
N_hidden = 3
N_output = 2

np.random.seed(42)
X = np.random.randn(4)
weights_input_to_hidden = np.random.normal(0, scale=0.1, size=(N_input, N_hidden))
weights_hidden_to_output = np.random.normal(0, scale=0.1, size=(N_hidden, N_output))

hidden_layer_in = np.dot(X, weights_input_to_hidden)
hidden_layer_out = sigmoid(hidden_layer_in)

output_layer_in = np.dot(hidden_layer_out, weights_hidden_to_output)
output_layer_out = sigmoid(output_layer_in)

print out_layer_out

相关文章

  • 梯度下降法及多层感知器

    梯度下降 之前我们看到一个权重的更新方法是: 这里 error term δ 是指 是输出误差,f' (h) 是激...

  • 算法

    1 梯度下降法,找到最优解。2 梯度下降法,适合更大的数据集。3 perceptron 感知器来做分类。

  • 神经网络和深度学习之【神经网络】

    感知器 S型神经元 神经网络的架构 梯度下降法

  • 2020-08-19--梯度下降法01

    梯度下降法简介 多元线性回归中的梯度下降法 随机梯度下降法 梯度下降法 的调试 1.梯度下降法简介 不是一个机器学...

  • 梯度下降法

    梯度下降法 本文主要是为了讲解 梯度下降法 的原理和实践,至于什么是梯度下降法,他能做什么,相信百度一下你就都知道...

  • 学习笔记:两种梯度下降法的思考

    在看梯度下降法的时候最初还真没看明白两种梯度下降法的区别,于是昨天散步的时候认真的思考了一下。 两种梯度下降法分别...

  • 最速梯度下降

    梯度下降法实现简单,当目标函数是凸函数时,梯度下降法的解是全局解。一般情况下,其解不保证是全局最优解,梯度下降法的...

  • 神经网络优化2

    梯度下降 梯度下降法 批梯度下降法(Batch Gradient Descent,BGD)是最常用的梯度下降形式,...

  • 2019-03-17神经网络——optimizer

    神经网络优化算法,通常有三种:小批量梯度下降法,随机梯度下降法和批量梯度下降法。 小批量梯度下降法 适用于训练数据...

  • 2019-11-01第二课二周优化算法

    指数加权平均: 动量梯度下降法: RMSprop:和动量梯度下降法相似 adam优化算法:将动量梯度下降法和RMS...

网友评论

    本文标题:梯度下降法及多层感知器

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