神经网络(一)前馈神经网络

导入依赖

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles
from sklearn.model_selection import train_test_split

数据准备

# factor 表示内外圆的衡量因子
# X 表示点集
# y 表示相同索引下点集中的点所在的圆
X, y = make_circles(2000, noise=0.03, factor=0.6)
inner = np.where(y==1)
outer = np.where(y==0)
# 将内外圆的圆心放到 (1,1)上
X += 1
# 绘图
plt.plot(X[inner, 0], X[inner, 1], 'bo')
plt.plot(X[outer, 0], X[outer, 1], 'ro')
plt.show()

双圆
分割数据

# 选取 80% 的数据用来训练
# 选取 20% 的数据用来测试
train_x, test_x, train_y, test_y = train_test_split(X, y, test_size=0.2)

定义阶跃函数

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

阶跃函数
定义超参数

# 输入的自变量是 2D 
# 输出的因变量是 1D
# 隐层节点数目
n_hidden = 50
# 完整训练集的训练次数
n_epochs = 1000
# 学习率
learning_rate = 1

初始化权重矩阵

# 自变量的维度为 train_x.shape[1] 2D
weights_hidden = np.random.normal(0.0, size=(train_x.shape[1], n_hidden))
# 因变量的维度为 1D
weight_output = np.random.normal(0.0, size=(n_hidden))

构建FNN

# 进行 n_epochs 轮训练
for _ in range(n_epochs):

    # 每轮训练累加的误差
    del_w_hidden = np.zeros(weights_hidden.shape)
    del_w_output = np.zeros(weights_output.shape)

    # 训练FNN
    for x_, y_ in zip(train_x, train_y):

        # 信息前向计算
        hidden_input = np.dot(x_, weights_hidden)
        hidden_output = sigmoid(hidden_input)
        output = sigmoid(np.dot(hidden_output, weights_output))

        # 误差后向传播

        # 运算结果与期望结果的误差
        error = y_ - output

        # 输出层的误差
        # output * (1 - output) 表示罚函数
        # 某一个神经元计算得出的实际结果与期望结果偏差越大
        # 该神经元需要纠正(惩罚)的程度就越大
        output_error = error * output * (1 - output)

        # 隐层的误差
        # np.dot(output_error, weights_output)
        # 表示将误差按权重传播
        # output_error 由于只有一个输出节点
        # 因此权重始终为 1
        hidden_error = np.dot(output_error, weights_output) * hidden_output * (1 - hidden_output)

        # 更新误差
        # 权重的更新受两方面影响
        # 自变量数据越大对因变量的影响就越大
        # 神经元之间的权重越大对因变量的影响就越大
        # hidden_output & x_[:, None]
        # 表示自变量数据对误差的影响
        del_w_output += output_error * hidden_output
        del_w_hidden += hidden_error * x_[:, None]

    # 更新权重
    weights_hidden += learning_rate * del_w_hidden / train_x.shape[0]
    weights_output += learning_rate * del_w_output / train_x.shape[0]

测试FNN

# res 记录预测结果
res = np.array([])
for x_, y_ in zip(test_x, test_y):
    hidden_input = np.dot(x_, weights_hidden)
    hidden_output = sigmoid(hidden_input)
    output = sigmoid(np.dot(hidden_output, weights_output))
    res = np.append(res, output)
# round 函数表示四舍五入
# 用来圆整结果
res = np.round(res)
# 记录预测结果与期望结果相同的索引
compare = np.where(res==test_y)
# 预期正确的数据占测试数据的比例
compare[0].shape[0] / test_y.shape[0]
# 0.96

参考书籍
《Python深度学习实战:75个有关神经网络建模、强化学习与迁移学习的解决方案》

猜你喜欢

转载自blog.csdn.net/lolimostlovely/article/details/82528429