单神经元基于逻辑回归的训练函数

import numpy as np


def sigmoid(z):
    """
    sigmoid激活函数
    :param z: 一个数值或者一个numpy数组
    :return: sigmoid计算后的值,范围在[0,1]以内
    """
    s = 1 / (1 + np.exp(-z))
    return s


def initialize_with_zeros(dim):
    """
    初始化权重数组w和偏置/阈值b
    :param dim: w的大小
    :return:
    w -- 权重数组,初始化为全为0的一个列向量
    b -- 阈值
    """
    w = np.zeros((dim, 1))
    b = 0
    return w, b


def propagate(w, b, X, Y):
    """ 前反向传播,计算dw、db与对应的cost
    :param w: 权重数组 一组列向量
    :param b: 阈值
    :param X: 图片特征 n*m的矩阵,n行特征,m列样本,一行就代表所有样本的第一个特征
    :param Y: 标签 一组长度为m的行向量,对应每个样本的标签
    :return: 一组列向量,代表某个特征的dw、db
    """
    m = X.shape[1]
    # 前向传播,计算结果、成本,得到一个长度为m的行向量,其中一个元素就代表了一个样本的预测值a
    A = sigmoid(np.dot(w.T, X) + b)
    # 损失
    cost = -np.sum(Y * np.log(A) + (1 - Y) * np.log(1 - A)) / m
    # 反向传播,计算dw、db
    dZ = A - Y
    # 一组长度为n的列向量,其中一个元素,就代表了所有样本的某个特征的偏导均值
    dw = np.dot(X, dZ.T) / m
    db = np.sum(dZ) / m
    grades = {"dw": dw, "db": db}
    return grades, cost


def optimize(w, b, X, Y, num_iterators, learning_rate, print_cost=False):
    """
    梯度下降
    :param w: 权重数组
    :param b: 阈值
    :param X: 特征与样本
    :param Y: 标签
    :param num_iterators: 迭代次数
    :param learning_rate: 学习率
    :param print_cost: 是否打印成本
    :return: 梯度下降后的w、b
    """
    costs = []
    for i in range(num_iterators):
        grades, cost = propagate(w, b, X, Y)  # 传播训练,计算
        # 从字典中取出梯度
        dw = grades["dw"]
        db = grades["db"]

        # 梯度下降,更新参数,使其越来越优化,使成本越来越小
        w = w - learning_rate * dw
        b = b - learning_rate * db

        # 记录成本
        if i % 100 == 0:
            costs.append(cost)
            if print_cost:
                print("优化%i次后的成本是:%f" % (i, cost))
    params = {"w": w, "b": b}
    return params, costs


def predict(w, b, X):
    """
    预测函数
    :param w: 权重数组
    :param b: 阈值
    :param X: 特征数据
    :return: 每张图片的预测结果
    """
    m = X.shape[1]
    Y_prediction = np.zeros((1, m))
    # 预测
    A = sigmoid(np.dot(w.T, X) + b)
    # 上面得出的预测结果是小数的形式,为了方便后面显示,我们将其转换成0和1的形式(如:大于等于0.5就是1/有猫,小于0.5就是0/无猫)
    for i in range(A.shape[1]):
        if A[0, i] >= 0.5:
            Y_prediction[0, i] = 1
    return Y_prediction


def model(X_train, Y_train, X_test, Y_test, num_iterations=2000, learning_rate=0.5, print_cost=False):
    w, b = initialize_with_zeros(X_train.shape[0])
    parameters, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)
    w = parameters["w"]
    b = parameters["b"]

    Y_prediction_train = predict(w, b, X_train)
    Y_prediction_test = predict(w, b, X_test)

    print("对训练图片的预测准确率为:{}%".format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100))
    print("对测试图片的预测准确率为:{}%".format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100))
    d = {
        "costs": costs,
        "Y_prediction_test": Y_prediction_test,
        "Y_prediction_train": Y_prediction_train,
        "w": w,
        "b": b,
        "learning_rate": learning_rate,
        "num_iterations": num_iterations
    }
    return d

你可能感兴趣的:(AI入门)