一篇文章读懂人工神经网络

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 人工神经网络(ANN)是通过中神经元的信息处理机制开发的解决各种问题的数学模型。本文将通过讲解人工神经网络的原理、实现步骤、实际案例,带着大家读懂人工神经网络。

1.概述

   人工神经网络(ANN)是通过中神经元的信息处理机制开发的解决各种问题的数学模型。神经元又称神经细胞,有细胞体和突起(树突和轴突)组成。动物大脑的神经元处理机制为树突将接受到的信息递给细胞体,细胞经过分析处理通过轴突传递给下一个神经元

image.png

   BP神经网络的结构也和神经元的结构相似,X1、X2、Xn用于接收信息相当于树突的作用。隐含层相当于细胞体,用于处理和传递信息。Y1、Y2、Ym是输出层。

image.png


2.原理

   一种按照误差逆向传播算法训练的多层前馈神经网络,至于模型的特点是信息向前传递,计算出的结果与实际产生的误差反向传递。在向前传递的过程中,输入信号从输入层输入,经过隐含层逐层处理,我们可以把隐含层理解为一个函数,通过输入成一个值的输入,这个值带入隐含层的函数中,最后算出输出层结果。每一层的神经元状态只影响下一神经元状态。如果输出的结果与实际的期望有误差,比如说我们想要他输出的结果为200,但是他计算出的结果为150,在这个时候我们就要根据它的误差调整网络的权值和阈值,从而使得这个神经网络的预测输出不断逼近希望输出。

image.png

   在这一模型中,隐含层可以有多层的,输入层通过隐含层多层的计算,最后得出输出层。我们还需要提及权值和阈值这个这两个概念。权值指的是我们每一个信号特征输入X1、X2、Xn,都会给他匹配权值,可以理解为占到隐含层中的一个权重。可以理解为偏差看,这个输入值根据权值做了相应的计算,和我们实际想要的值有一个差距,通过阈值进行一个修正。


3.训练步骤

 1.网络初始化

   根据实际的条件确定隐含层的层数、每层隐藏层的神经元个数学习速率、神经元激励函数。这个学习速率是指我们在每一次进行计算后得出的误差,他是使用一种梯度下降法,为了保证我们的这个每一次更新权值和阈值,不错过最优解,一般的取值为0~1之间的小数。隐含层的节点数通常需要我们通过一定的经验或者公式来尝试得出。

hidden_floors_num:隐藏层的个数
every_hidden_floor_num:每层隐藏层的神经元个数
learning_rate:学习速率
activation:激活函数
regularization:正则化方式
regularization_rate:正则化比率
total_step:总的训练次数
train_data_path:训练数据路径
model_save_path:模型保存路径

 2.隐含层输出计算

   根据输入向量X,输入层和隐藏层之间的权值。以及隐含层的阈值,计算隐含层的输出。

image.png

   这时我们需要通过激励函数,把这个输出值控制在某一个范围之间。常用的激活函数有sigmoid、tanh 。sigmoid函数把输入的结果控制在0到1的范围内。

image.png

 3.输出层输出计算

   根据隐含层的输出H,连接权值和阈值,计算BP神经网络的预测输出O。

image.png

 4.误差计算

   根据BP神经网络的预测输出O和期望输出Y,计算网络的误差e。

image.png

 5.权值更新

   根据神经网络的误差e,使用梯度下降法,更新网络的权值。

image.png

 6.阈值更新

   根据神经网络的误差e,更新网络的阈值。

image.png

 7.判断算法迭代是否完成

   判断算法迭代是否完成,若没有结束,返回步骤2。


4.案例

   下面将通过一个案例来实现人工神经网络。该案例主要由生成数据、训练模型预测数据三个部分组成。

 1.生成数据

# 生成测试数据importnumpyasnpimportpandasaspd# 训练集和验证集样本总个数sample=2000train_data_path='train.csv'validate_data_path='validate.csv'predict_data_path='test.csv'# 构造生成数据的模型X1=np.zeros((sample, 1))
X1[:, 0] =np.random.normal(1, 1, sample)
X2=np.zeros((sample, 1))
X2[:, 0] =np.random.normal(2, 1, sample)
X3=np.zeros((sample, 1))
X3[:, 0] =np.random.normal(3, 1, sample)
# 模型Y=6*X1-3*X2+X3*X3+np.random.normal(0, 0.1, [sample, 1])
# 将所有生成的数据放到data里面data=np.zeros((sample, 4))
data[:, 0] =X1[:, 0]
data[:, 1] =X2[:, 0]
data[:, 2] =X3[:, 0]
data[:, 3] =Y[:, 0]
# 将data分成测试集和训练集num_traindata=int(0.8*sample)
# 将训练数据保存traindata=pd.DataFrame(data[0:num_traindata, :], columns=['x1', 'x2', 'x3', 'y'])
traindata.to_csv(train_data_path, index=False)
print('训练数据保存在: ', train_data_path)
# 将验证数据保存validate_data=pd.DataFrame(data[num_traindata:, :], columns=['x1', 'x2', 'x3', 'y'])
validate_data.to_csv(validate_data_path, index=False)
print('验证数据保存在: ', validate_data_path)
# 将预测数据保存predict_data=pd.DataFrame(data[num_traindata:, 0:-1], columns=['x1', 'x2', 'x3'])
predict_data.to_csv(predict_data_path, index=False)
print('预测数据保存在: ', predict_data_path)

   以上代码通过Y = 6 * X1 - 3* X2 + X3 * X3 + np.random.normal(0, 0.1, [sample, 1]),随机生成2000组数据。其中1600组放入train.csv,作为训练集。400组放入validate.csv,作为验证集。输入量为X1、X2、X3,输出量为Y。

image.png


 2.训练验证模型

importtensorflowastfimportpandasaspdimportnumpyasnpcreateVar=locals()
'''建立一个网络结构可变的BP神经网络通用代码:在训练时各个参数的意义:hidden_floors_num:隐藏层的个数every_hidden_floor_num:每层隐藏层的神经元个数learning_rate:学习速率activation:激活函数regularization:正则化方式regularization_rate:正则化比率total_step:总的训练次数train_data_path:训练数据路径model_save_path:模型保存路径利用训练好的模型对验证集进行验证时各个参数的意义:model_save_path:模型保存路径validate_data_path:验证集路径precision:精度利用训练好的模型进行预测时各个参数的意义:model_save_path:模型的保存路径predict_data_path:预测数据路径predict_result_save_path:预测结果保存路径'''# 训练模型全局参数hidden_floors_num=1every_hidden_floor_num= [50]
learning_rate=0.00001activation='tanh'regularization='L1'regularization_rate=0.0001total_step=200000train_data_path='train.csv'model_save_path='model/predict_model'# 利用模型对验证集进行验证返回正确率model_save_path='model/predict_model'validate_data_path='validate.csv'precision=0.5# 利用模型进行预测全局参数model_save_path='model/predict_model'predict_data_path='test.csv'predict_result_save_path='test_predict.csv'definputs(train_data_path):
train_data=pd.read_csv(train_data_path)
X=np.array(train_data.iloc[:, :-1])
Y=np.array(train_data.iloc[:, -1:])
returnX, Ydefmake_hidden_layer(pre_lay_num, cur_lay_num, floor):
createVar['w'+str(floor)] =tf.Variable(tf.random_normal([pre_lay_num, cur_lay_num], stddev=1))
createVar['b'+str(floor)] =tf.Variable(tf.random_normal([cur_lay_num], stddev=1))
returneval('w'+str(floor)), eval('b'+str(floor))
definitial_w_and_b(all_floors_num):
# 初始化隐藏层的w, bforfloorinrange(2, hidden_floors_num+3):
pre_lay_num=all_floors_num[floor-2]
cur_lay_num=all_floors_num[floor-1]
w_floor, b_floor=make_hidden_layer(pre_lay_num, cur_lay_num, floor)
createVar['w'+str(floor)] =w_floorcreateVar['b'+str(floor)] =b_floordefcal_floor_output(x, floor):
w_floor=eval('w'+str(floor))
b_floor=eval('b'+str(floor))
ifactivation=='sigmoid':
output=tf.sigmoid(tf.matmul(x, w_floor) +b_floor)
ifactivation=='tanh':
output=tf.tanh(tf.matmul(x, w_floor) +b_floor)
ifactivation=='relu':
output=tf.nn.relu(tf.matmul(x, w_floor) +b_floor)
returnoutputdefinference(x):
output=xforfloorinrange(2, hidden_floors_num+2):
output=cal_floor_output(output, floor)
floor=hidden_floors_num+2w_floor=eval('w'+str(floor))
b_floor=eval('b'+str(floor))
output=tf.matmul(output, w_floor) +b_floorreturnoutputdefloss(x, y_real):
y_pre=inference(x)
ifregularization=='None':
total_loss=tf.reduce_sum(tf.squared_difference(y_real, y_pre))
ifregularization=='L1':
total_loss=0forfloorinrange(2, hidden_floors_num+3):
w_floor=eval('w'+str(floor))
total_loss=total_loss+tf.contrib.layers.l1_regularizer(regularization_rate)(w_floor)
total_loss=total_loss+tf.reduce_sum(tf.squared_difference(y_real, y_pre))
ifregularization=='L2':
total_loss=0forfloorinrange(2, hidden_floors_num+3):
w_floor=eval('w'+str(floor))
total_loss=total_loss+tf.contrib.layers.l2_regularizer(regularization_rate)(w_floor)
total_loss=total_loss+tf.reduce_sum(tf.squared_difference(y_real, y_pre))
returntotal_lossdeftrain(total_loss):
train_op=tf.train.GradientDescentOptimizer(learning_rate).minimize(total_loss)
returntrain_op# 训练模型deftrain_model(hidden_floors_num, every_hidden_floor_num, learning_rate, activation, regularization,
regularization_rate, total_step, train_data_path, model_save_path):
file_handle=open('acc.txt', mode='w')
X, Y=inputs(train_data_path)
X_dim=X.shape[1]
all_floors_num= [X_dim] +every_hidden_floor_num+ [1]
# 将参数保存到和model_save_path相同的文件夹下, 恢复模型进行预测时加载这些参数创建神经网络temp=model_save_path.split('/')
model_name=temp[-1]
parameter_path=''foriinrange(len(temp)-1):
parameter_path=parameter_path+temp[i] +'/'parameter_path=parameter_path+model_name+'_parameter.txt'withopen(parameter_path, 'w') asf:
f.write("all_floors_num:")
foriinall_floors_num:
f.write(str(i) +' ')
f.write('\n')
f.write('activation:')
f.write(str(activation))
x=tf.placeholder(dtype=tf.float32, shape=[None, X_dim])
y_real=tf.placeholder(dtype=tf.float32, shape=[None, 1])
initial_w_and_b(all_floors_num)
y_pre=inference(x)
total_loss=loss(x, y_real)
train_op=train(total_loss)
# 记录在训练集上的正确率train_accuracy=tf.reduce_mean(tf.cast(tf.abs(y_pre-y_real) <precision, tf.float32))
print(y_pre)
# 保存模型saver=tf.train.Saver()
# 在一个会话对象中启动数据流图,搭建流程sess=tf.Session()
init=tf.global_variables_initializer()
sess.run(init)
forstepinrange(total_step):
sess.run([train_op], feed_dict={x: X[0:, :], y_real: Y[0:, :]})
ifstep%1000==0:
saver.save(sess, model_save_path)
total_loss_value=sess.run(total_loss, feed_dict={x: X[0:, :], y_real: Y[0:, :]})
lxacc=sess.run(train_accuracy, feed_dict={x: X, y_real: Y})
print('train step is ', step, ', total loss value is ', total_loss_value,
', train_accuracy', lxacc,
', precision is ', precision)
file_handle.write(str(lxacc)+"\n")
saver.save(sess, model_save_path)
sess.close()
defvalidate(model_save_path, validate_data_path, precision):
# **********************根据model_save_path推出模型参数路径, 解析出all_floors_num和activation****************temp=model_save_path.split('/')
model_name=temp[-1]
parameter_path=''foriinrange(len(temp)-1):
parameter_path=parameter_path+temp[i] +'/'parameter_path=parameter_path+model_name+'_parameter.txt'withopen(parameter_path, 'r') asf:
lines=f.readlines()
# 从读取的内容中解析all_floors_numtemp=lines[0].split(':')[-1].split(' ')
all_floors_num= []
foriinrange(len(temp)-1):
all_floors_num=all_floors_num+ [int(temp[i])]
# 从读取的内容中解析activationactivation=lines[1].split(':')[-1]
hidden_floors_num=len(all_floors_num) -2# **********************读取验证数据*************************************X, Y=inputs(validate_data_path)
X_dim=X.shape[1]
# **********************创建神经网络************************************x=tf.placeholder(dtype=tf.float32, shape=[None, X_dim])
y_real=tf.placeholder(dtype=tf.float32, shape=[None, 1])
initial_w_and_b(all_floors_num)
y_pre=inference(x)
# 记录在验证集上的正确率validate_accuracy=tf.reduce_mean(tf.cast(tf.abs(y_pre-y_real) <precision, tf.float32))
sess=tf.Session()
saver=tf.train.Saver()
withtf.Session() assess:
# 读取模型try:
saver.restore(sess, model_save_path)
print('模型载入成功!')
except:
print('模型不存在,请先训练模型!')
returnvalidate_accuracy_value=sess.run(validate_accuracy, feed_dict={x: X, y_real: Y})
print('validate_accuracy is ', validate_accuracy_value)
returnvalidate_accuracy_valuedefpredict(model_save_path, predict_data_path, predict_result_save_path):
# **********************根据model_save_path推出模型参数路径, 解析出all_floors_num和activation****************temp=model_save_path.split('/')
model_name=temp[-1]
parameter_path=''foriinrange(len(temp)-1):
parameter_path=parameter_path+temp[i] +'/'parameter_path=parameter_path+model_name+'_parameter.txt'withopen(parameter_path, 'r') asf:
lines=f.readlines()
# 从读取的内容中解析all_floors_numtemp=lines[0].split(':')[-1].split(' ')
all_floors_num= []
foriinrange(len(temp)-1):
all_floors_num=all_floors_num+ [int(temp[i])]
# 从读取的内容中解析activationactivation=lines[1].split(':')[-1]
hidden_floors_num=len(all_floors_num) -2# **********************读取预测数据*************************************predict_data=pd.read_csv(predict_data_path)
X=np.array(predict_data.iloc[:, :])
X_dim=X.shape[1]
# **********************创建神经网络************************************x=tf.placeholder(dtype=tf.float32, shape=[None, X_dim])
initial_w_and_b(all_floors_num)
y_pre=inference(x)
sess=tf.Session()
saver=tf.train.Saver()
withtf.Session() assess:
# 读取模型try:
saver.restore(sess, model_save_path)
print('模型载入成功!')
except:
print('模型不存在,请先训练模型!')
returny_pre_value=sess.run(y_pre, feed_dict={x: X[0:, :]})
# 将预测结果写入csv文件predict_data_columns=list(predict_data.columns) + ['predict']
data=np.column_stack([X, y_pre_value])
result=pd.DataFrame(data, columns=predict_data_columns)
result.to_csv(predict_result_save_path, index=False)
print('预测结果保存在:', predict_result_save_path)
if__name__=='__main__':
mode="train"ifmode=='train':
# 训练模型train_model(hidden_floors_num, every_hidden_floor_num, learning_rate, activation, regularization,
regularization_rate, total_step, train_data_path, model_save_path)
ifmode=='validate':
# 利用模型对验证集进行正确性测试validate(model_save_path, validate_data_path, precision)
ifmode=='predict':
# 利用模型进行预测predict(model_save_path, predict_data_path, predict_result_save_path)

   训练时需要调节的参数有隐藏层的个数hidden_floors_num每层隐藏层的神经元个数every_hidden_floor_num学习速率learning_rate激活函数activation总的训练次数total_step

   我们使用阿里云天池实验室PAI DSW进行模型训练以及验证总的训练次数设为100000经元个数设为10。

image.png

模型收敛慢

image.png

预测准确率低


   

总的训练次数设为100000经元个数设为50。

image.png

模型快速收敛

image.png

预测准确率高


   我们可以通过调节隐藏层的个数每层隐藏层的神经元个数学习速率激活函数总的训练次数等参数提高模型的准确率。

 3.预测数据

   最后使用训练好的模型predict_model对数据进行预测。

image.png


目录
相关文章
|
5月前
|
NoSQL Java Redis
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
83 0
|
5月前
|
存储 消息中间件 缓存
Redis系列学习文章分享---第十七篇(Redis原理篇--数据结构,网络模型)
Redis系列学习文章分享---第十七篇(Redis原理篇--数据结构,网络模型)
97 0
WK
|
2月前
|
机器学习/深度学习 自然语言处理 算法
PSO算法和人工神经网络有什么不同
PSO算法(粒子群优化)与人工神经网络(ANN)在原理、应用及优化方式上差异显著。PSO模拟鸟群行为,通过粒子协作在解空间中搜索最优解;而ANN模仿大脑神经元结构,通过训练学习输入输出映射,适用于模式识别、图像处理等领域。PSO主要用于优化问题,实时性高,结果直观;ANN则在处理复杂非线性关系方面更强大,但结构复杂,训练耗时长,结果解释性较差。实际应用中需根据需求选择合适技术。
WK
26 0
|
3月前
|
网络协议 编译器 Go
揭秘!TCP、RPC、gRPC、HTTP大PK,谁才是网络通信界的超级巨星?一篇文章带你秒懂!
【8月更文挑战第25天】本文以教程形式深入对比了TCP、RPC、gRPC与HTTP这四种关键通信协议,并通过Go语言中的示例代码展示了各自的实现方法。TCP作为一种可靠的传输层协议,确保了数据的完整性和顺序性;RPC与gRPC作为远程过程调用框架,特别适合于分布式系统的函数调用与数据交换,其中gRPC在性能和跨语言支持方面表现出色;HTTP则是广泛应用于Web浏览器与服务器通信的应用层协议。选择合适的协议需根据具体需求综合考量。
247 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的网络在线考试系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的网络在线考试系统附带文章源码部署视频讲解等
51 0
基于springboot+vue.js+uniapp的网络在线考试系统附带文章源码部署视频讲解等
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的网络办公系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的网络办公系统附带文章和源代码部署视频讲解等
50 8
|
4月前
|
机器学习/深度学习 数据采集 算法
Python实现人工神经网络回归模型(MLPRegressor算法)并基于网格搜索(GridSearchCV)进行优化项目实战
Python实现人工神经网络回归模型(MLPRegressor算法)并基于网格搜索(GridSearchCV)进行优化项目实战
135 0
|
4月前
|
机器学习/深度学习 算法 数据可视化
Python基于librosa和人工神经网络实现语音识别分类模型(ANN算法)项目实战
Python基于librosa和人工神经网络实现语音识别分类模型(ANN算法)项目实战
137 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的网络互联实验平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的网络互联实验平台附带文章源码部署视频讲解等
53 0
|
5月前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的网络财务管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的网络财务管理系统附带文章和源代码部署视频讲解等
51 6