说明

本教程将结合经典的神经网络入门案例,通过绘图剖析网络中传播的细节,并附上详细的求导公式,希望能帮助读者更好地理解神经网络的工作过程,本教程需要你了解一些神经网络的基本知识。如果文中有错误,请各位大佬及时指正

案例

在本案例中,我们将随机生成三类样本点,要求使用分类器将这三类样本点进行分类。首先,我们将会使用普通的线性分类器(不带激活函数)来进行分类,再使用神经网络分类器(带激活函数)进行分类,最后对比两者的分类效果。在整个教程中,我会通过绘图来详细剖析分类器各层的含义和作用,再附上代码,阅读代码时,你可以对比着看分类器的结构图

import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = (10.0, 8.0)
# 初始化参数
np.random.seed(0)
N = 100 # 每个类中的样本点
D = 2 # 维度
K = 3 # 类别个数
X = np.zeros((N*K, D)) # (300, 2)
y = np.zeros(N*K, dtype='uint8')
for j in range(K):
    ix = range(N*j, N*(j+1))
    r = np.linspace(0.0, 1, N) # 在0.0到1.0之间返回间隔均匀的N个数字
    t = np.linspace(j*4, (j+1)*4, N) + np.random.randn(N)*0.2
    X[ix] = np.c_[r*np.sin(t), r*np.cos(t)] # 按行连接两个矩阵
    y[ix] = j
plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)

如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用

线性分类器

如何用spss进行神经网络结果使用 spss神经网络模型案例_机器学习_02

神经元

如何用spss进行神经网络结果使用 spss神经网络模型案例_Soft_03

单个神经元的输出

如何用spss进行神经网络结果使用 spss神经网络模型案例_神经网络_04

其中 如何用spss进行神经网络结果使用 spss神经网络模型案例_线性分类器_05 表示样本的第 如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_06 个特征,如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_07 表示连接到该神经元的第 如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_06 个权重,如何用spss进行神经网络结果使用 spss神经网络模型案例_线性分类器_09 表示偏置,如何用spss进行神经网络结果使用 spss神经网络模型案例_Soft_10

以此类推,可得到整个网络的矩阵表示

如何用spss进行神经网络结果使用 spss神经网络模型案例_机器学习_11

梯度

如何用spss进行神经网络结果使用 spss神经网络模型案例_神经网络_12

如何用spss进行神经网络结果使用 spss神经网络模型案例_神经网络_13

Softmax

如何用spss进行神经网络结果使用 spss神经网络模型案例_线性分类器_14

其中 如何用spss进行神经网络结果使用 spss神经网络模型案例_Soft_10 是第 如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_06 个输出单元的输出,如何用spss进行神经网络结果使用 spss神经网络模型案例_线性分类器_17如何用spss进行神经网络结果使用 spss神经网络模型案例_Soft_10 经过 Softmax 转换后得到的概率值,表示样本属于第 如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_06

如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_20

梯度

如何用spss进行神经网络结果使用 spss神经网络模型案例_神经网络_21

如何用spss进行神经网络结果使用 spss神经网络模型案例_机器学习_22

如何用spss进行神经网络结果使用 spss神经网络模型案例_神经网络_23

如何用spss进行神经网络结果使用 spss神经网络模型案例_神经网络_24

交叉熵损失

损失函数

如何用spss进行神经网络结果使用 spss神经网络模型案例_线性分类器_25

如何用spss进行神经网络结果使用 spss神经网络模型案例_Soft_26

其中 如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_06 表示第 如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_06 个类别,若样本的真实类别为 如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_06,则 如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_30

梯度

如何用spss进行神经网络结果使用 spss神经网络模型案例_Soft_31

如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_32

针对分类问题,我们给定的结果 如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_30

如何用spss进行神经网络结果使用 spss神经网络模型案例_机器学习_34

正则化惩罚项

如何用spss进行神经网络结果使用 spss神经网络模型案例_Soft_35

梯度

如何用spss进行神经网络结果使用 spss神经网络模型案例_神经网络_36

矩阵形式

如何用spss进行神经网络结果使用 spss神经网络模型案例_线性分类器_37

其中 如何用spss进行神经网络结果使用 spss神经网络模型案例_机器学习_38

# 单层神经网络
# 初始化参数
W = 0.01 * np.random.randn(D, K) # 随机初始化参数 (2, 3)
b = np.zeros((1, K)) # (1, 3)
step_size = 1e-0 # 1.0,学习率
reg = 1e-3 # 0.001,正则化系数
num_examples = X.shape[0] # 样本个数
# 训练
for i in range(1000):
    
    # 前向传播
    scores = np.dot(X, W) + b # (300, 3)
    
    # softmax
    exp_scores = np.exp(scores)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) # 计算类别概率 (300, 3)
    
    # 交叉熵损失
    corect_logprobs = -np.log(probs[range(num_examples), y])
    data_loss = np.sum(corect_logprobs) / num_examples # 对所有样本的损失进行求和,取均值
    
    # 正则化惩罚项
    reg_loss = 0.5 * reg * np.sum(W*W)
    
    loss = data_loss + reg_loss
    if i % 100 == 0:
        print('iteration %d: loss %f' % (i, loss))
    
    # 计算损失梯度 dL/dz
    dscores = probs
    dscores[range(num_examples), y] -= 1
    dscores /= num_examples # 将一批数据产生的梯度取平均
    
    # 计算在W,b上的梯度
    dW = np.dot(X.T, dscores) # (2, 3)
    db = np.sum(dscores, axis=0, keepdims=True) # (1, 3)
    
    # 加上正则项梯度
    dW += reg * W
    
    # 参数更新
    W += -step_size * dW
    b += -step_size * db

如何用spss进行神经网络结果使用 spss神经网络模型案例_线性分类器_39

scores = np.dot(X, W) + b
predicted_class = np.argmax(scores, axis=1) # 概率最大的类别的下标
print('training accuracy: %.2f' % (np.mean(predicted_class == y))) # 准确率

training accuracy: 0.49

h = 0.02
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                     np.arange(y_min, y_max, h))
Z = np.dot(np.c_[xx.ravel(), yy.ravel()], W) + b # ravel将多维数组降为一维
Z = np.argmax(Z, axis=1) # 取概率最高的类别
Z = Z.reshape(xx.shape)
fig = plt.figure()
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=0.8) # 绘制三维等高线
plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.show()

如何用spss进行神经网络结果使用 spss神经网络模型案例_Soft_40

神经网络分类器

如何用spss进行神经网络结果使用 spss神经网络模型案例_神经网络_41

ReLU 激活单元

如何用spss进行神经网络结果使用 spss神经网络模型案例_机器学习_42

梯度

如何用spss进行神经网络结果使用 spss神经网络模型案例_线性分类器_43

# 两层神经网络
# 初始化参数
h = 100 # 隐层大小(神经元个数)
W = 0.01 * np.random.randn(D, h)
b = np.zeros((1, h))
W2 = 0.01 * np.random.randn(h, K)
b2 = np.zeros((1, K))
step_size = 1e-0 # 学习率
reg = 1e-3 # 正则化系数
num_examples = X.shape[0] # 样本个数
# 训练
for i in range(10000):
    
    # 前向传播
    hidden_layer = np.maximum(0, np.dot(X, W) + b) # 使用 ReLU 激活函数
    scores = np.dot(hidden_layer, W2) + b2

    # softmax
    exp_scores = np.exp(scores)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) # 计算类别概率

    # 交叉熵损失
    corect_logprobs = -np.log(probs[range(num_examples), y])
    data_loss = np.sum(corect_logprobs) / num_examples
    
    # 正则化惩罚项
    reg_loss = 0.5*reg*np.sum(W*W) + 0.5*reg*np.sum(W2*W2)
    
    loss = data_loss + reg_loss
    if i % 1000 == 0:
        print("iteration %d: loss %f" % (i, loss))

    # 计算损失梯度 dL/dz
    dscores = probs
    dscores[range(num_examples), y] -= 1
    dscores /= num_examples

    # 计算在W2,b2上的梯度
    dW2 = np.dot(hidden_layer.T, dscores)
    db2 = np.sum(dscores, axis=0, keepdims=True)
    dhidden = np.dot(dscores, W2.T)
    
    # ReLU 激活函数梯度
    dhidden[hidden_layer <= 0] = 0
    
    # 计算最后在W,b上的梯度
    dW = np.dot(X.T, dhidden)
    db = np.sum(dhidden, axis=0, keepdims=True)

    # 加上正则项梯度
    dW2 += reg * W2
    dW += reg * W

    # 参数更新
    W += -step_size * dW
    b += -step_size * db
    W2 += -step_size * dW2
    b2 += -step_size * db2

如何用spss进行神经网络结果使用 spss神经网络模型案例_机器学习_44

# 计算分类准确度
hidden_layer = np.maximum(0, np.dot(X, W) + b)
scores = np.dot(hidden_layer, W2) + b2
predicted_class = np.argmax(scores, axis=1)
print('training accuracy: %.2f' % (np.mean(predicted_class == y)))

training accuracy: 0.98

h = 0.02
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                     np.arange(y_min, y_max, h))
Z = np.dot(np.maximum(0, np.dot(np.c_[xx.ravel(), yy.ravel()], W) + b), W2) + b2
Z = np.argmax(Z, axis=1)
Z = Z.reshape(xx.shape)
fig = plt.figure()
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.show()

如何用spss进行神经网络结果使用 spss神经网络模型案例_如何用spss进行神经网络结果使用_45

可以看到,神经网络由于引入了激活函数从而提升了分类器的非线性分类能力,由此我们可以感受到神经网络的强大魅力
完结,撒花!