BP神经网络对鸢尾花进行分类
题目:BP神经网络分类器一、实验项目: BP神经网络对鸢尾花进行分类二、实验目的:掌握BP神经网络学习算法,利用BP神经网络进行数据分类三、实验内容:1、编程实现BP神经网络算法2、建立三层BP神经网络,节点个数、参数自拟3、选择iris-人工神经网络.txt中的一部分数据集作为训练集,通过训练集对BP神经网络的连接权重进行学习4、记录实验数据(连接权值的变化、迭代次数、总的误差变化)5、用剩下的
题目:BP神经网络分类器
一、实验项目: BP神经网络对鸢尾花进行分类
二、实验目的:
掌握BP神经网络学习算法,利用BP神经网络进行数据分类
三、实验内容:
1、编程实现BP神经网络算法
2、建立三层BP神经网络,节点个数、参数自拟
3、选择iris-人工神经网络.txt中的一部分数据集作为训练集,通过训练集对BP神经网络的连接权重进行学习
4、记录实验数据(连接权值的变化、迭代次数、总的误差变化)
5、用剩下的数据集作为测试集,验证学习的效果
四、实验要求:
1、画出实验所用的BP神经网络的结构图
2、附上主体代码清单
3、写清楚实验步骤和实验结果
4、调节参数后,得到不同的实验数据,对数据进行分析
代码:
import numpy as np
import pandas as pd
'''
构建一个具有1个隐藏层的神经网络,隐层的大小为5
输入层为2个特征,输出层为2个分类
0为第一类,1为第二类
'''
# 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))
print('输入层与隐含层之间的初始权值:')
print(w1)
print('输入层与隐含层之间的初始偏置:')
print(b1)
print('隐含层与输出层之间的初始权值:')
print(w2)
print('隐含层与输出层之间的初始偏置:')
print(b2)
# 通过字典存储参数
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的维度不同,但可以相加
a1 = np.tanh(z1) # 使用tanh作为第一层的激活函数
z2 = np.dot(w2, a1) + 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.4):
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 - 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']
print('训练集训练后,输入层与隐含层之间的权值为:')
print(w1)
print('训练集训练后,输入层与隐含层之间的偏置为:')
print(b1)
print('训练集训练后,隐含层与输出层之间的权值为:')
print(w2)
print('训练集训练后,隐含层与输出层之间的偏置为:')
print(b2)
print('================================================================')
print('================================================================')
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)
for i in range(n_rows):
for j in range(n_cols):
if a2[i][j] > 0.5:
output[i][j] = 1
else:
output[i][j] = 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)
# 建立神经网络
def nn_model(X, Y, n_h, n_input, n_output, num_iterations=10000, print_cost=False):
np.random.seed(3)
n_x = n_input # 输入层节点数
n_y = n_output # 输出层节点数
print('================================================================')
print('================================================================')
# 1.初始化参数
parameters = initialize_parameters(n_x, n_h, n_y)
print('================================================================')
print('================================================================')
# 2.前向传播
a2, cache = forward_propagation(X, parameters)
# 3.计算代价函数
cost0 = compute_cost(a2, Y, parameters)
# 4.反向传播
grads = backward_propagation(parameters, cache, X, Y)
# 5.更新参数
parameters = update_parameters(parameters, grads)
# 梯度下降循环
for i in range(1, num_iterations+1):
# 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)
# 每1000次迭代,输出一次代价函数
# =============================================================================
# if print_cost and i % 1000 == 0:
# print('迭代第%i次,代价函数为:%f' % (i, cost))
# =============================================================================
print('迭代次数为:%i次,总的误差变化为:%f' % (i, cost-cost0))
print('================================================================')
print('================================================================')
return parameters
if __name__ == "__main__":
# 读取数据
f=open('F:\\小n\\智能计算\\实验\\实验3\\iris数据集\\iris-人工神经网络-训练集.txt')
data_set = pd.read_table(f,sep=',', header=None)
# 不同的取数据的方式
X = data_set[data_set.columns[0:2]].values.T
Y = data_set[data_set.columns[2:3]].values.T
Y = Y.astype('uint8')
# 输入2个节点,隐层5个节点,输出1个节点,迭代10000次
parameters = nn_model(X, Y, n_h=5, n_input=2, n_output=1, num_iterations=10000, print_cost=True)
# 对模型进行测试
f1=open('F:\\小n\\智能计算\\实验\\实验3\\iris数据集\\iris-人工神经网络-测试集.txt')
data_test = pd.read_csv(f1, header=None)
x_test = data_test[data_test.columns[0:2]].values.T
y_test = data_test[data_test.columns[2:3]].values.T
y_test = y_test.astype('uint8')
predict(parameters, x_test, y_test)
运行结果:
参考文章:
Python 基于BP神经网络的鸢尾花分类
pandas之 read_table函数读取txt文件
总结一下遇到的小问题:
(1)敲pandas出错?
(第一次用pandas库)误以为就是panda,运行的时候发现没有这个模块。
(2)利用pandas不能直接读含有中文的路径,否则会报错
#路径中含有中文,pandas不能直接读,报错
data_set = pd.read_table('F:\\小n\\智能计算\\实验\\实验3\\iris数据集\\iris-人工神经网络-训练集.txt',sep=',', header=None)
#如何解决
f=open('F:\\小n\\智能计算\\实验\\实验3\\iris数据集\\iris-人工神经网络-训练集.txt')
data_set = pd.read_table(f,sep=',', header=None)
(3)如何用pandas来读取txt文件数据(非常方便,尤其是对txt文件中的数据切片取行或取列时),使用read_table()方法。pandas的read_table返回一个DataFrame,二维型的,会像一棋盘那样标识数据。事实上,所谓的txt文件中的数据就是一个DataFrame。如下图所示:
data_set = pd.read_table(f,sep=',', header=None)
其中,f是读入的txt文件的路径;sep=‘,’ 表示txt文件单行数据之间的分隔符为逗号,这个参数可缺省,默认为sep=‘\t’,制表符;header=None 表示txt文件的第一行不是列的名字,是数据。
(4)最简单的对DataFrame取列的方式:
(一个txt文件中的数据,就是一个DataFrame)
X = data_set[data_set.columns[0:2]].values.T #取第1,2列
Y = data_set[data_set.columns[2:3]].values.T #取第3列
(5)BP神经网络构建一个分类器的思路:
第一步:初始化参数(包括权值和偏置)
第二步:前向传播
第三步:计算代价函数
第四步:反向传播
第五步:更新参数
第六步:模型评估
其中:第二、三、四、五步是建立训练集的基础上进行的,得到一组训练后的权值和偏置,到目前为止就实现了一个分类器;以这一组新的权值和偏置作为测试集的初始化参数,通过前向传播的结果与真实结果的对比来估计这个分类器的好坏。
更多推荐
所有评论(0)