BP神经网络(以西瓜为例)

神经网络构建

import pandas as pd
import numpy as np
import datetime
import matplotlib.pyplot as plt
from pandas.plotting import radviz
'''
    构建一个具有1个隐藏层的神经网络,隐层的大小为10
    输入为6个特征,输出层有一个神经元
    输出层大于0.5时代表是一个好瓜,小于0.5代表是一个坏瓜
'''


# 1.初始化模型参数
def initialize_parameters(n_x, n_h, n_y):
    np.random.seed(2)

    # 权重和偏置矩阵
    w1 = np.random.randn(n_h, n_x) * 0.01
    b1 = np.zeros(shape=(n_h, 1))
    w2 = np.random.randn(n_y, n_h) * 0.01
    b2 = np.zeros(shape=(n_y, 1))

    # 通过字典存储参数
    parameters = {'w1': w1, 'b1': b1, 'w2': w2, 'b2': b2}
    return parameters


# 2.前向传播
def forward_propagation(X, parameters):
    w1 = parameters['w1']
    b1 = parameters['b1']
    w2 = parameters['w2']
    b2 = parameters['b2']

    # 通过前向传播来计算a2
    z1 = np.dot(w1, X) + b1     # w1*x+b1  这个地方需注意矩阵加法:虽然(w1*X)和b1的维度不同,但可以相加
    a1 = np.tanh(z1)            # 使用tanh作为第一层的激活函数
    z2 = np.dot(w2, a1) + b2    # w2*x+b2
    a2 = 1 / (1 + np.exp(-z2))  # 使用sigmoid作为第二层的激活函数

    # 通过字典存储参数
    cache = {'z1': z1, 'a1': a1, 'z2': z2, 'a2': a2}

    return a2, cache


# 3.计算代价函数
def compute_cost(a2, Y, parameters):
    m = Y.shape[1]      # Y的列数即为总的样本数

    # 采用交叉熵(cross-entropy)作为代价函数
    logprobs = np.multiply(np.log(a2), Y) + np.multiply((1 - Y), np.log(1 - a2))
    cost = - np.sum(logprobs) / m

    return cost


# 4.反向传播(计算代价函数的导数)
def backward_propagation(parameters, cache, X, Y):
    m = Y.shape[1]
    w2 = parameters['w2']
    a1 = cache['a1']
    a2 = cache['a2']

    # 反向传播,计算dw1、db1、dw2、db2
    dz2 = a2 - Y # 误差求导结果
    dw2 = (1 / m) * np.dot(dz2, a1.T) # 计算出第二层的梯度
    db2 = (1 / m) * np.sum(dz2, axis=1, keepdims=True)
    dz1 = np.multiply(np.dot(w2.T, dz2), 1 - np.power(a1, 2))
    dw1 = (1 / m) * np.dot(dz1, X.T) #计算出第一层的梯度
    db1 = (1 / m) * np.sum(dz1, axis=1, keepdims=True)
    grads = {'dw1': dw1, 'db1': db1, 'dw2': dw2, 'db2': db2}

    return grads


# 5.更新参数
def update_parameters(parameters, grads, learning_rate=0.05):
    # 获取当前参数
    w1 = parameters['w1']
    b1 = parameters['b1']
    w2 = parameters['w2']
    b2 = parameters['b2']
    # 获取梯度
    dw1 = grads['dw1']
    db1 = grads['db1']
    dw2 = grads['dw2']
    db2 = grads['db2']

    # 更新参数,根据参数更新公式w=w - α*learning_rate 进行
    w1 = w1 - dw1 * learning_rate
    b1 = b1 - db1 * learning_rate
    w2 = w2 - dw2 * learning_rate
    b2 = b2 - db2 * learning_rate
    # 更新存储后的参数
    parameters = {'w1': w1, 'b1': b1, 'w2': w2, 'b2': b2}

    return parameters


# 6.模型评估
def predict(parameters, x_test, y_test):
    #得到训练好后的模型参数
    w1 = parameters['w1']
    b1 = parameters['b1']
    w2 = parameters['w2']
    b2 = parameters['b2']

    z1 = np.dot(w1, x_test) + b1
    a1 = np.tanh(z1)
    z2 = np.dot(w2, a1) + b2
    a2 = 1 / (1 + np.exp(-z2))

    # 结果的维度
    n_rows = y_test.shape[0]
    n_cols = y_test.shape[1]

    # 判断模型的预测值并存储结果
    output = np.empty(shape=(n_rows, n_cols), dtype=int)
    print((a2))

    for i in range(n_rows):
        for j in range(n_cols):
            if a2[i][j] > 0.5: # 预测值大于0.5时判断为一个好瓜,记录为1
                output[i][j] = 1
            else:
                output[i][j] = 0 # 预测值大小于0.5时判断为一个坏瓜,记录为0
    print('预测结果:')
    print(output)
    print('真实结果:')
    print(y_test)
    count = 0
    # 统计好瓜坏瓜的数量
    for k in range(0, n_cols):
        if output[0][k] == y_test[0][k] :
            count = count + 1
        else:
            print(k)
    # 计算准确率
    acc = count / int(y_test.shape[1]) * 100
    print('准确率:%.2f%%' % acc)
    return output


# 建立神经网络
def nn_model(X, Y, n_h, n_input, n_output, num_iterations=1000, print_cost=False):
    np.random.seed(3)
    n_x = n_input           # 输入层节点数
    n_y = n_output          # 输出层节点数
    # 1.初始化参数
    parameters = initialize_parameters(n_x, n_h, n_y)
    # 梯度下降循环,执行1000次迭代训练
    for i in range(0, num_iterations):
        # 2.前向传播
        a2, cache = forward_propagation(X, parameters)
        # 3.计算代价函数
        cost = compute_cost(a2, Y, parameters)
        # 4.反向传播
        grads = backward_propagation(parameters, cache, X, Y)
        # 5.更新参数
        parameters = update_parameters(parameters, grads)

        # 每10次迭代,输出一次代价函数
        if print_cost and i % 100 == 0:
            print('迭代第%i次,代价函数为:%f' % (i, cost))
    return parameters

if __name__ == "__main__":
    # 读取训练集
    data_set = pd.read_csv('melon_train.csv', header=None)
    # 对数据进行切分
    X = data_set.iloc[:, 1:7].values.T          # 第1至第七列是特征,T表示转置
    Y = data_set.iloc[:, 7:].values.T           # 最后一列是分类标签
    Y = Y.astype('uint8')
    # 开始训练
    start_time = datetime.datetime.now()
    # 输入6个节点,隐层10个节点,输出1个节点,迭代100次,并得到模型的最终参数存储在parameters中
    parameters = nn_model(X, Y, n_h=10, n_input=6, n_output=1, num_iterations=1000, print_cost=True)
    end_time = datetime.datetime.now()
    print("用时:" + str((end_time - start_time).seconds) + 's' + str(round((end_time - start_time).microseconds / 1000)) + 'ms')
    # 同理读入测试数据集
    data_test = pd.read_csv('melon_test.csv', header=None)
    x_test = data_test.iloc[:, 1:7].values.T
    y_test = data_test.iloc[:, 7:].values.T
    y_test = y_test.astype('uint8')

    #测试函数
    result = predict(parameters, x_test, y_test)

处理数据集

# 导入包
import pandas as pd
from sklearn import tree
import graphviz
import numpy as np


if __name__=='__main__':
    df = pd.read_csv('melon.txt')
    df.head(10)
    df['色泽'] = df['色泽'].map({'浅白': 1, '青绿': 2, '乌黑': 3})
    df['根蒂'] = df['根蒂'].map({'稍蜷': 1, '蜷缩': 2, '硬挺': 3})
    df['敲声'] = df['敲声'].map({'清脆': 1, '浊响': 2, '沉闷': 3})
    df['纹理'] = df['纹理'].map({'清晰': 1, '稍糊': 2, '模糊': 3})
    df['脐部'] = df['脐部'].map({'平坦': 1, '稍凹': 2, '凹陷': 3})
    df['触感'] = np.where(df['触感'] == "硬滑", 1, 2)
    df['好瓜'] = np.where(df['好瓜'] == "是", 1, 0)
    x_train = df[['色泽', '根蒂', '敲声', '纹理', '脐部', '触感']]
    y_train = df['好瓜']
    df.to_csv('melon_train.csv')
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是使用BP神经网络进行西瓜分类Python代码示例: ```python import numpy as np import json # 定义sigmoid函数 def sigmoid(x): return 1 / (1 + np.exp(-x)) # 定义sigmoid函数的导数 def sigmoid_derivative(x): return x * (1 - x) # 定义BP神经网络类 class NeuralNetwork: def __init__(self, x, y): self.input = x self.weights1 = np.random.rand(self.input.shape[1], 4) self.weights2 = np.random.rand(4, 1) self.y = y self.output = np.zeros(self.y.shape) def feedforward(self): self.layer1 = sigmoid(np.dot(self.input, self.weights1)) self.output = sigmoid(np.dot(self.layer1, self.weights2)) def backprop(self): d_weights2 = np.dot(self.layer1.T, (2*(self.y - self.output) * sigmoid_derivative(self.output))) d_weights1 = np.dot(self.input.T, (np.dot(2*(self.y - self.output) * sigmoid_derivative(self.output), self.weights2.T) * sigmoid_derivative(self.layer1))) self.weights1 += d_weights1 self.weights2 += d_weights2 def train(self, X, y): self.output = np.zeros(y.shape) for i in range(1500): self.feedforward() self.backprop() # 将习得的神经网络结构保存为json格式文件 network = {"weights1": self.weights1.tolist(), "weights2": self.weights2.tolist()} with open('network.json', 'w') as outfile: json.dump(network, outfile) # 加载西瓜数据集 X = np.array([[0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1]]) y = np.array([[0], [1], [1], [0]]) # 创建BP神经网络对象并进行训练 nn = NeuralNetwork(X, y) nn.train(X, y) # 加载习得的神经网络结构 with open('network.json') as json_file: network = json.load(json_file) weights1 = np.array(network['weights1']) weights2 = np.array(network['weights2']) # 进行预测 new_input = np.array([1, 0, 0]) layer1 = sigmoid(np.dot(new_input, weights1)) output = sigmoid(np.dot(layer1, weights2)) print(output) # 输出:[[0.99999999]] ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值