Python中文社区(ID:python-china)人工神经网络(ANNs)已成功应用于许多需要人工监督的日常任务,但由于其复杂性,难以理解他们的工作方法和训练方法。在此博客中,我们深入讨论什么是神经网络、它们如何工作以及如何将它们应用于查找异常值或预测金融时间序列等问题。在这篇文章中,我试图直观地展示一个简单的前馈神经网络如何在训练期间将一组输入映射到不同的空间,以便它们更容易理解。数据为了展示它是如何工作的,首先我创建了一个“玩具”数据集。它包含400个均匀分布在两个类(0和1)中的样本,每个样本有两个维度(X0和X1)。注:所有数据均来自三个随机正态分布,均值[-1,0,1],标准差[0.5,0.5,0.5]。网络架构下一步是按如下方式定义ANN的结构:隐藏层具有最小维度(2个神经元)以显示网络将每个样本映射到2D散点图中的位置。虽然在前面的图中没有显示,但每一层都有一个激活函数来修改它的输出。?输入层有一个线性激活函数来复制它的输入值。?隐藏层有ReLU或tanh激活函数。?输出层有一个sigmoid激活函数,将其输入值“收缩”到[0,1]范围内。训练除了网络架构之外,神经网络的另一个关键方面是训练过程。训练ANN的方法有很多种,但最常见的是反向传播过程。反向传播过程首先将所有训练案例(或一批)前馈给网络,然后优化器根据损失函数计算“如何”更新网络的权重,并根据学习率更新它们。当损失收敛、经过一定数量的epoch或用户停止训练时,训练过程停止。一个epoch意味着所有数据都发送到网络,完成一个前向计算+反向传播的过程。在我们的案例研究中,该架构在隐藏层中使用2种不同的激活函数(ReLU和Tanh)和3种不同的学习率(0.1、0.01和0.001)进行训练。在输入样本周围,有一个点“网格”,显示模型对该位置样本的预测概率。这使得模型在训练期间生成的边界更加清晰。#figureholdingtheevolutionf,axes=plt.subplots(1,3,figsize=(18,6),gridspec_kw={'height_ratios':[.9]})f.subplots_adjust(top=0.82)#cameratorecordtheevolutioncamera=相机(f)#numberofepochsepochs=20#iterateepochtimesforiinrange(epochs):#evaluatethemodel(acc,loss)evaluation=model.evaluate(x_train,y_train,verbose=0)#generateintermediatemodelsmodel_hid_1=模型(model.input,model.get_layer("hidden_??1").output)model_act_1=模型(model.input,model.get_layer("activation_1").output)#generatedatadf_hid_1=pd.DataFrame(model_hid_1.predict(x_train),columns=['X0','X1'])df_hid_1['y']=y_traindf_act_1=pd.DataFrame(model_act_1.predict(x_train),columns=['X0','X1'])df_act_1['y']=y_train#generatemeshgrid(200values)x=np.linspace(x_train[:,0].min(),x_train[:,0].max(),200)y=np.linspace(x_train[:,1].min(),x_train[:,1].max(),200)xv,yv=np.meshgrid(x,y)#generatemeshgridintenistydf_mg_train=pd.DataFrame(np.stack((xv.flatten(),yv.flatten()),axis=1),columns=['X0','X1'])df_mg_train['y']=model.predict(df_mg_train.values)df_mg_hid_1=pd.DataFrame(model_hid_1.predict(df_mg_train.values[:,:-1]),columns=['X0','X1'])df_mg_hid_1['y']=model.predict(df_mg_train.values[:,:-1])df_mg_act_1=pd.DataFrame(model_act_1.predict(df_mg_train.values[:,:-1]),columns=['X0','X1'])df_mg_act_1['y']=model.predict(df_mg_train.values[:,:-1])#showdatasetax=sns.scatterplot(x='X0',y='X1',data=df_mg_train,hue='y',x_jitter=True,y_jitter=True,legend=None,ax=axes[0],palette=sns.diverging_palette(220,20,as_cmap=True),alpha=0.15)ax=sns.scatterplot(x='X0',y='X1',data=df_train,hue='y',legend=None,ax=axes[0],palette=sns.diverging_palette(220,20,n=2))ax.set_title('Inputlayer')ax=sns.scatterplot(x='X0',y='X1',data=df_mg_hid_1,hue='y',x_jitter=True,y_jitter=True,legend=None,ax=axes[1],palette=sns.diverging_palette(220,20,as_cmap=True),alpha=0.15)ax=sns.scatterplot(x='X0',y='X1',data=df_hid_1,hue='y',legend=None,ax=axes[1],调色板=sns.diverging_palette(220,20,n=2))ax.set_title('Hiddenlayer')#showthecurrentepochandthemetricsax.text(x=0.5,y=1.15,s='Epoch{}'.format(i+1),fontsize=16,weight='bold',ha='center',va='bottom',transform=ax.transAxes)ax.text(x=0.5,y=1.08,s='Accuracy{:.3f}-Loss{:.3f}'.format(评估[1],评估[0]),fontsize=13,ha='center',va='bottom',transform=ax.transAxes)ax=sns.scatterplot(x='X0',y='X1',data=df_mg_act_1,hue='y',x_jitter=True,y_jitter=True,legend=None,ax=axes[2],调色板=sns.diverging_palette(220,20,as_cmap=True),alpha=0.15)ax=sns.scatterplot(x='X0',y='X1',data=df_act_1,hue='y',legend=None,ax=axes[2],palette=sns.diverging_palette(220,20,n=2))ax.set_title('Activation')#showtheplotplt.show()#calltogeneratetheGIFcamera.snap()#stopexecutionifloss<=0.263(avoidlooping200timesifnotneeded)ifevaluation[0]<=0.263:break#trainthemodel1epochmodel。fit(x_train,y_train,epochs=1,verbose=0)ReLUactivationTanhactivation注意:使用的损失函数是二元交叉熵,因为我们处理的是二元分类问题,优化器是原始的随机梯度下降(SGD)称为Adam的修改当epoch达到200或损失低于0.263时,模型训练停止。
