Python实现简单的神经网络1
2018-04-11阅读 4774

我们的训练集由 m = 750 个样本组成。因此,我们的矩阵维度如下:


  • 训练集维度: X = (750,2)

  • 目标维度: Y = (750,1)

  • 640?wx_fmt=png&wxfrom=5&wx_lazy=1&retryload=1维度:(m,nhidden) = (2,6)

  • 640?wx_fmt=png&wxfrom=5&wx_lazy=1维度:(bias vector):(1,nhidden) = (1,6)

  • 640?wx_fmt=png&wxfrom=5&wx_lazy=1维度: (nhidden,noutput)= (6,1)

  • 640?wx_fmt=png&wxfrom=5&wx_lazy=1维度:(bias vector):(1,noutput) = (1,1)


640?wx_fmt=png


损失函数


我们使用与 Logistic 回归算法相同的损失函数:


640?wx_fmt=png

对于多类别的分类任务,我们将使用这个函数的通用形式作为损失函数,称之为分类交叉熵函数。


训练

我们将用梯度下降法来训练我们的神经网络,并通过反向传播法来计算所需的偏导数。训练过程主要有以下几个步骤:


1. 初始化参数(即权重量和偏差量)

2. 重复以下过程,直到收敛:

  • 通过网络传播当前输入的批次大小,并计算所有隐藏和输出单元的激活值和输出值。

  • 针对每个参数计算其对损失函数的偏导数

  • 更新参数


前向传播过程


首先,我们计算网络中每个单元的激活值和输出值。为了加速这个过程的实现,我们不会单独为每个输入样本执行此操作,而是通过矢量化对所有样本一次性进行处理。其中:


  • 640?wx_fmt=png表示对所有训练样本激活隐层单元的矩阵

  • 640?wx_fmt=png表示对所有训练样本输出隐层单位的矩阵


隐层神经元将使用 tanh 函数作为其激活函数:


640?wx_fmt=png


输出层神经元将使用 sigmoid 函数作为激活函数:


640?wx_fmt=png


激活值和输出值计算如下(·表示点乘):


640?wx_fmt=png


反向传播过程


为了计算权重向量的更新值,我们需要计算每个神经元对损失函数的偏导数。这里不会给出这些公式的推导,你会在其他网站上找到很多更好的解释(https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/)。


对于输出神经元,梯度计算如下(矩阵符号):


640?wx_fmt=png


对于输入和隐层的权重矩阵,梯度计算如下:


640?wx_fmt=png


权重更新


640?wx_fmt=png


In [3]:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles
from sklearn.model_selection import train_test_split
np.random.seed(123)
% matplotlib inline

数据集


In [4]:

X, y = make_circles(n_samples=1000, factor=0.5, noise=.1)
fig = plt.figure(figsize=(8,6))
plt.scatter(X[:,0], X[:,1], c=y)
plt.xlim([-1.5, 1.5])
plt.ylim([-1.5, 1.5])
plt.title("Dataset")
plt.xlabel("First feature")
plt.ylabel("Second feature")
plt.show()

640?wx_fmt=png

In [5]:

# reshape targets to get column vector with shape (n_samples, 1)
y_true = y[:, np.newaxis]
# Split the data into a training and test set
X_train, X_test, y_train, y_test = train_test_split(X, y_true)
print(f'Shape X_train: {X_train.shape}')
print(f'Shape y_train: {y_train.shape}')
print(f'Shape X_test: {X_test.shape}')
print(f'Shape y_test: {y_test.shape}')

Shape X_train: (750, 2)

Shape y_train: (750, 1)

Shape X_test: (250, 2)

Shape y_test: (250, 1)