基础神经网络

神经网络

构建一个最简单的包括输入层,一层隐藏层和输出层的基础神经网络模型
1.准备数据,使用sklearn.datasets.make_moons这个数据集来测试:

np.random.seed(1)
X,Y = sklearn.datasets.make_moons(n_samples=200,noise=.2)
X,Y = X.T, Y.reshape(1, Y.shape[0])
m = X.shape[1]   #样本个数
dim = X.shape[0]  #特征维度

2.参数初始化

def initialize_parameters(n_x, n_h, n_y):
    """
    函数输出
    :param n_x: 输入层维度
    :param n_h: 隐藏层神经元个数
    :param n_y: 输出层神经元个数
    :return:
    :params: 存储参数的字典, W1, b1, W2, b2
    """
    np.random.seed(0)
    W1 = np.random.randn(n_h, n_x)
    b1 = np.zeros((n_h, 1))
    W2 = np.random.randn(n_y, n_h)
    b2 = np.zeros((n_y, 1))
    parameters = {
        'W1': W1,
        'b1': b1,
        'W2': W2,
        'b2': b2
    }
    return parameters

3.前向传播

def sigmoid(x):
    """
    函数输入:
        -x: sigmoid 函数输入
    函数输出:
        -y: sigmoid 函数输出
    :param x:
    :return:
    """
    y = 1/(1+np.exp(-x))
    return  y
#定义神经网络的前向传播
def forward_propagation(X, parameters):
    """
    函数输出
    :param X: 神经网络输入
    :param parameters: 神经网络参数
    :return:
    -A2:神经网络输出
    -cache: 缓存,存储中间变量,Z1, A1, Z2, A2
    """
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    # 输入层 ---> 隐藏层
    Z1 = np.dot(W1, X) + b1
    A1 = np.tanh(Z1)
    # 隐藏层 ---> 输出层
    Z2 = np.dot(W2, A1) + b2
    A2 = sigmoid(Z2)
    cache = {
        'Z1': Z1,
        'A1': A1,
        'Z2': Z2,
        'A2': A2
    }
    return A2, cache

4.交叉熵损失部分

def compute_loss(A2, Y):
    """
    函数输入
    :param A2: 神经网络输出
    :param Y:  样本真实标签
    :return:
    -cost:神经网络交叉熵损失
    """
    m = Y.shape[1]
    cross_entropy = -(Y*np.log(A2)+(1-Y)*np.log(1-A2))
    cost = 1.0/m*np.sum(cross_entropy)
    return  cost

5.反向传播部分

def back_propagation(X, Y, parameters, cache):
    """
    函数输入
    :param X: 神经网络输入
    :param Y: 样本真实标签
    :param parameters: 网络参数
    :param cache: 缓存cache,存储中间变量Z1, A1, Z2, A2
    :return:
    - grade: 神经网络参数梯度
    """
    # 样本个数
    m = X.shape[1]
    #神经网络参数
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    # 中间变量
    Z1 = cache['Z1']
    A1 = cache['A1']
    Z2 = cache['Z2']
    A2 = cache['A2']
    #计算梯度
    dZ2 = A2 - Y
    dW2 = 1.0/m*np.dot(dZ2, A1.T)
    db2 = 1.0/m*np.sum(dZ2, axis=1, keepdims=True)
    dZ1 = np.dot(W2.T, dZ2)*(1 - np.power(A1, 2))
    dW1 = 1.0/m*np.dot(dZ1, X.T)
    db1 = 1.0/m*np.sum(dZ1,axis=1, keepdims=True)
    grads = {
        'dW1': dW1,
        'db1': db1,
        'dW2': dW2,
        'db2': db2
    }
    return grads

6.梯度下降更新参数

def updates_parameters(parameters, grads, learning_rate = 0.1):
    """
    函数输入
    :param parameters: 网络参数
    :param grads: 神经网络参数梯度
    :param learning_rate: 学习率
    :return:
    -parameters:网络参数
    """
    #神经网络参数
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    #神经网络参数梯度
    dW1 =grads['dW1']
    db1 = grads['db1']
    dW2 = grads['dW2']
    db2 = grads['db2']
    #梯度下降算法
    W1 = W1 - learning_rate*dW1
    b1 = b1 - learning_rate*db1
    W2 = W2 - learning_rate*dW2
    b2 = b2 - learning_rate*db2
    parameters = {
        'W1': W1,
        'b1': b1,
        'W2': W2,
        'b2': b2
    }
    return  parameters

7.构建网络模型

def nn_model(X, Y, n_h, num_iterations = 200, learning_rate=0.1):
    """
    函数输入
    :param X:神经网络输入
    :param Y: 样本真实标签
    :param n_h: 隐藏层神经元个数
    :param num_iterations: 训练次数
    :param learning_rate: 学习率
    :return:
    -parameters:训练完的网络参数
    """
    #定义网络
    n_x = X.shape[0]
    n_y = 1
    parameters = initialize_parameters(n_x, n_h, n_y)
    #迭代次数
    for i in range(num_iterations):
        A2, cache = forward_propagation(X, parameters)
        cost = compute_loss(A2, Y)
        grads = back_propagation(X, Y, parameters, cache)
        parameters = updates_parameters(parameters, grads, learning_rate)
        if (i+1)%20 == 0:
            print('Iteration: %d, cost = %f' % (i+1, cost))
    return parameters

8.预测与训练

parameters = nn_model(X, Y, n_h=3, num_iterations=50000, learning_rate=0.1)
#预测
def predict(X, parameters):
    """
    函数输入
    :param X: 神经网络输入
    :param parameters: 训练完的网络参数模型
    :return:
     -Y_pred: 预测样本标签
    """
    W1 = parameters['W1']
    b1 = parameters['b1']
    W2 = parameters['W2']
    b2 = parameters['b2']
    # 输入层 --> 隐藏层
    Z1 = np.dot(W1, X) + b1
    A1 = np.tanh(Z1)
    # 隐藏层 -->输出层
    Z2 = np.dot(W2, A1) + b2
    A2 = sigmoid(Z2)
    # 预测标签
    Y_pred = np.zeros((1, X.shape[1]))
    Y_pred[A2>0.5] = 1
    return  Y_pred

Y_pred = predict(X,parameters)
print(np.mean(Y_pred==Y))

9.可视化结果与比较

x_min, x_max = X[0, :].min()-0.5, X[0, :].max() + 0.5
y_min, y_max = X[1, :].min()-0.5, X[1, :].max() + 0.5
step = 0.001
xx, yy = np.meshgrid(np.arange(x_min, x_max, step), np.arange(y_min, y_max, step))
Z = predict(np.c_[xx.ravel(), yy.ravel()].T,parameters)
Z = Z.reshape(xx.shape)
plt.contourf(xx, yy, Z,  cmap = plt.cm.Spectral)
plt.scatter(X[0, Y[0, :]==0], X[1, Y[0, :]==0], c ='g', marker='s', label='负类')
plt.scatter(X[0, Y[0, :]==1], X[1, Y[0, :]==1], c ='y', marker='o', label='正类')
plt.legend()
plt.show()

神经网络模型结果
传统逻辑回归预测结果
传统逻辑回归预测结果
可以看出,逻辑回归所得到的线性分类结果准确率是远远不如神经网络的非线性分类结果

欢乐的时光总是短暂的,让我们下一次再见!!!
good good study,day day up! (study hard, improve every day)
预知后事,请听下回分解!!!!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值