BP神经网络研究
Posted nanyunan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BP神经网络研究相关的知识,希望对你有一定的参考价值。
本随笔参考文章:《BP神经网络详解与实例》(链接: https://pan.baidu.com/s/1e2niIvD9KtLXEqwXtgdXxw 密码: vb8d)
本随笔原创,转发请注明原处:https://www.cnblogs.com/nanyunan/p/9494946.html
1 神经网络单元示例
2 神经网络示例
3 几个重要公式
3.1 单元前向公式
y=f[sum(wi*xi)-θ]
其中,wi是输入权重,xi是输入值,sum是求和函数,θ是阈(yu)值,f是激发函数
其中,f激发函数主要有:sgn,Sigmoid
其中,sgn是符号函数(https://baike.baidu.com/item/sign/115763)
其次,Sigmoid是S型函数(https://baike.baidu.com/item/Sigmoid%E5%87%BD%E6%95%B0/7981407?fr=aladdin)
3.2 单元后向公式
权重迭代公式
假设有n个样本训练网络,p表示当前训练样本,p-1表示上一个训练样本。
ωlp(i,j)=ωlp-1(i,j)+ηδlpαl-1p(j)
其中,ωlp(i,j)表示第l层第i个神经单元的第j个输入权重
其中,ωlp(i,j)表示新的权重
其中,ωlp-1(i,j)表示旧的权重
其中,η是学习效率,取值(0,1)之间,一般默认取值0.1。η过小,收敛过慢,精度高。η过大,收敛快,优解容易丢失。
其中,δlp(i)=f’Sum[δl+1p(j)ωl+1p-1(j,i)]
其中,f’是激发函数f的导函数
其中,δl+1p(j)表示下一层第j个神经单元的δ值
其中,ωl+1p-1(j,i)表示下一层第j个神经单元第i个权重的旧值
其次,δLp(i)=f’(tp(i)-aLp(i))
其中,L表示最后一层
其中,tp(i)表示最后一层第i个输出神经单元的真值
其中,aLp(i)表示最后一层第i个输出神经单元的输出值
4 编程实例
使用语言:C#
下面并不是所有代码。
源代码(链接: https://pan.baidu.com/s/1nsh8T2VCISZFQb0fU_wBXg 密码: y8pi)
实例(包含程序,说明书,样本)(链接: https://pan.baidu.com/s/1sWkEOGqKXC6uMCGzD9eg_Q 密码: sjfh)
样本(链接: https://pan.baidu.com/s/1O9XlLOGXRbC0PfAVo9LULA 密码: b9st)
4.1 神经网络配置类
public class NerveConfig { public static double Func(double Value) { double myResult = 0; //----- double Key = Math.Pow(Math.E,-Value); myResult = 1.0 / (1+Key); //----- return myResult; } public static double Func_OrderOne(double Value) { double myResult = 0; //----- double Key = Math.Pow(Math.E, -Value); double Key2 = Math.Pow(1+Key,2); myResult = Key / (Key2); //----- return myResult; } public static double Eta = 0.1; public static Random R = new Random(); }
4.2 神经单元类
public class NerveUnit { public NerveUnit(NerveList nerveList) { Input = new UnitInputAdmin(this); Output = new UnitOutput(this,0); Parent = nerveList; for(int i = 0; i < nerveList.Count; i++) { Bound(nerveList[i]); } } public NerveUnit(ValueList valueList) { Input = new UnitInputAdmin(this); Output = new UnitOutput(this, 0); for (int i = 0; i < valueList.Count; i++) { Bound((UnitOutput)valueList[i]); } } public class UnitInput { public UnitInput(UnitOutput Output,NerveUnit Parent) { this.Bound = Output; Output.Bound(this); this.Parent = Parent; } public UnitOmega Omega = new UnitOmega(); public UnitOutput Bound=null; public NerveUnit Parent = null; public double Value { get { double myResult = 0; //----- myResult = Omega.Value * Bound.Value; //----- return myResult; } } public int Location = 0; public void Back(double Delta) { double OriValue = Omega.Value; Omega.Value = Omega.Value + NerveConfig.Eta * Delta * Bound.Value; Log.Adds("Location",Location,"Ori Omega=",OriValue ,"Now Omega=",Omega.Value,"Last layer output=",Bound.Value); } } public class UnitInputAdmin { public UnitInputAdmin(NerveUnit Parent) { this.Parent = Parent; } public List<UnitInput> Data = new List<UnitInput>(); public NerveUnit Parent; public void Bound(UnitOutput Output) { UnitInput unit = new UnitInput(Output,Parent); unit.Location = Data.Count; Data.Add(unit); } public double Value { get { double myResult = 0; //----- for (int i = 0; i < Data.Count; i++) { myResult += Data[i].Value; } //----- return myResult; } } public double Omega(int Index) { double myResult = 0; if (Index >= 0 && Index < Data.Count) { myResult = Data[Index].Omega.Value; } return myResult; } public void SetIniOmega(int Index,double Value) { if (Index >= 0 && Index < Data.Count) { Data[Index].Omega.Ini(Value); } else { throw new Exception("Index="+Index.ToString()+",Count="+Data.Count.ToString()); } } public void SetIniOmegas(OmegaNet.OmegaList.OmegaUnit Value) { for(int i = 0; i < Data.Count && i < Value.Count; i++) { Data[i].Omega.Ini(Value[i]); } } public UnitInput this[int Index] { get { UnitInput myResult; //----- if (Index >= 0 && Index < Data.Count) { myResult = Data[Index]; } else { throw new Exception("Index=" + Index.ToString() + ",Count=" + Data.Count.ToString()); } //----- return myResult; } } public int Count { get { return Data.Count; } } } public class UnitInputList { public List<UnitInput> Data = new List<UnitInput>(); public void Bound(UnitInput Input) { Data.Add(Input); } public double Omega(int Index) { double myResult = 0; if (Index >= 0 && Index < Data.Count) { myResult = Data[Index].Omega.Value; } return myResult; } public UnitInput this[int Index] { get { UnitInput myResult; //----- if (Index >= 0 && Index < Data.Count) { myResult = Data[Index]; } else { throw new Exception("Index=" + Index.ToString() + ",Count=" + Data.Count.ToString()); } //----- return myResult; } } public int Count { get { return Data.Count; } } } public class UnitOmega { public UnitOmega() { Now=NerveConfig.R.NextDouble(); Last = Now; } public double Now = 1; public double Last = 1; public double Value { get { return Now; } set { Last = Now; Now = value; } } public void Ini(double Value) { this.Now = Value; this.Last = Value; } } public Point Location = new Point(0,0); public class UnitOutput { public UnitOutput(NerveUnit Parent,double Value) { this.Value = Value; this.Parent = Parent; } public UnitOutput(double Value) { this.Value = Value; } public UnitOutput(NerveUnit Parent) { this.Parent = Parent; } public UnitOutput() { } public UnitInputList InputList = new UnitInputList(); public void Bound(UnitInput Input) { InputList.Bound(Input); } public NerveUnit Parent; public double Truth = 0; public double Value = 0; public void FigureDelta() { if (Parent.Parent.Layer == NerveList.LayerType.End) { Delta = (Truth-Value) * NerveConfig.Func_OrderOne(Parent.Input.Value); } else { double DeltaChild = 0; for (int i = 0; i < InputList.Count; i++) { DeltaChild += InputList[i].Parent.Output.Delta * InputList[i].Omega.Last; } Delta = NerveConfig.Func_OrderOne(Parent.Input.Value) * DeltaChild; } } public double Delta = 0; public double TipSD = 0; public double SD { get { return Math.Pow(Truth-Value,2); } } public override string ToString() { string myResult = string.Empty; //----- myResult = Value.ToString() + "," + Truth.ToString(); //----- return myResult; } } public class UnitThreshold { public UnitThreshold(double Value) { this.Value = Value; } public double Value = 0; } public UnitThreshold Threshold = new UnitThreshold(1); public UnitInputAdmin Input; public UnitOutput Output; public NerveList Parent; public void Bound(UnitOutput Output) { Input.Bound(Output); } public void Bound(NerveUnit Unit) { Input.Bound(Unit.Output); } public void Forward() { double InValue = Input.Value; double ThValue = Threshold.Value; double delta = InValue - ThValue; Output.Value = NerveConfig.Func(delta); Log.Adds("[Forward]","Location:",Location.X,Location.Y ,"Sum=",InValue,"Threshold=",ThValue ,"delta=", delta,"Output=",Output.Value); } public void Back() { Output.FigureDelta(); Log.Adds("[Back]","Location:",Location.X ,Location.Y ,"Delta=",Output.Delta); for(int i = 0; i < Input.Count; i++) { Input[i].Back(Output.Delta); } } public OmegaNet.OmegaList.OmegaUnit GetOmegaUnit() { OmegaNet.OmegaList.OmegaUnit myResult = new OmegaNet.OmegaList.OmegaUnit(); myResult.Index = Location.Y; //----- for(int i = 0; i < Input.Count; i++) { myResult.Add(Input.Omega(i)); } //----- return myResult; } public void SetOmegas(OmegaNet.OmegaList.OmegaUnit Value) { Input.SetIniOmegas(Value); } }
4.3 神经层类
public class NerveList { public NerveList(NerveList Last,int Count) { this.Last = Last; Last.Next = this; // for(int i = 0; i < Count; i++) { NerveUnit Item = new NerveUnit(Last); Item.Parent = this; Data.Add(Item); } } public NerveList(ValueList Last,int Count) { for (int i = 0; i < Count; i++) { NerveUnit Item = new NerveUnit(Last); Item.Parent = this; Data.Add(Item); } } private int _Location = 0; public int Location { get { return _Location; } set { _Location = value; for(int i = 0; i < Data.Count; i++) { Data[i].Location = new Point(value,i); } } } public enum LayerType { Middle, End } public LayerType Layer = LayerType.Middle; public List<NerveUnit> Data = new List<NerveUnit>(); public NerveUnit this[int Index] { get { NerveUnit myResult; //----- if (Index >= 0 && Index < Data.Count) { myResult = Data[Index]; } else { throw new Exception("Index="+Index.ToString()+",Count="+Data.Count.ToString()); } //----- return myResult; } } public int Count { get { return Data.Count; } } public NerveList Last=null; public NerveList Next=null; public void Forward() { for(int i = 0; i < Data.Count; i++) { Data[i].Forward(); } } public void Back() { for(int i = 0; i < Data.Count; i++) { Data[i].Back(); } } public List<string> Report(bool NeedTruth=true) { List<string> myResult = new List<string>(); //------ if (NeedTruth) { for (int i = 0; i < Data.Count; i++) { myResult.Add(Data[i].Output.ToString()); } } else { for (int i = 0; i < Data.Count; i++) { myResult.Add(Data[i].Output.Value.ToString()); } } //------ return myResult; } public void ApplyTruth(double[] Truth) { ApplyZero(); for(int i=0;i<Data.Count && i < Truth.Length; i++) { Data[i].Output.Truth = Truth[i]; } } public void ApplyTruth(List<double> Truth) { ApplyZero(); for (int i = 0; i < Data.Count && i < Truth.Count; i++) { Data[i].Output.Truth = Truth[i]; } } public void ApplyZero() { ApplyTruth(0); } public void ApplyTruth(double Value) { for (int i = 0; i < Data.Count; i++) { Data[i].Output.Value = Value; } } /// <summary> /// Square difference,平方差 /// </summary> public double SD { get { double myResult = 0; //----- if(Layer== LayerType.End) { for(int i = 0; i < Data.Count; i++) { myResult += Data[i].Output.SD; } } else { throw new Exception("Layer="+Layer.ToString()); } //----- TipSD = myResult; return myResult; } } public double TipSD = 0; public OmegaNet.OmegaList GetOmegaList() { OmegaNet.OmegaList myResult = new OmegaNet.OmegaList(); //----- for(int i = 0; i < Data.Count; i++) { myResult.Add(Data[i].GetOmegaUnit()); } myResult.Index = _Location; //----- return myResult; } public void SetOmegas(OmegaNet.OmegaList Value) { for(int i = 0; i < Data.Count&&i<Value.Count; i++) { Data[i].SetOmegas(Value[i]); } } }
public class ValueList { public ValueList(int Count) { for(int i = 0; i < Count; i++) { NerveUnit.UnitOutput unitValue = new NerveUnit.UnitOutput(); Data.Add(unitValue); } } public List<NerveUnit.UnitOutput> Data = new List<NerveUnit.UnitOutput>(); public NerveUnit.UnitOutput this[int Index] { get { NerveUnit.UnitOutput myResult; //----- if (Index >= 0 && Index < Data.Count) { myResult = Data[Index]; } else { throw new Exception("Index=" + Index.ToString() + ",Count=" + Data.Count.ToString()); } //----- return myResult; } } public int Count { get { return Data.Count; } } public void Apply(List<double> vs) { ApplyZero(); for (int i = 0; i < vs.Count&&i<Data.Count; i++) { Data[i].Value = vs[i]; } } public void Apply(double[] vs) { ApplyZero(); for (int i = 0; i < vs.Length && i < Data.Count; i++) { Data[i].Value = vs[i]; } } public void ApplyZero() { for (int i = 0; i < Data.Count; i++) { Data[i].Value = 0; } } }
4.4 神经网络类
public class NerveNetUnit { public NerveNetUnit(int Rows,int Count, int CountOfOutput) { Create(Rows,Count,CountOfOutput); } public NerveNetUnit(int[] RowsCounts,int CountOfOutput) { Create(RowsCounts,CountOfOutput); } public NerveNetUnit(OmegaNet Net) { SetOmegas(Net); } public void Create(int Rows, int Count, int CountOfOutput) { //初始化 输入 Input = new ValueList(Count); NerveList Last = null; Data.Clear(); //开始创建网络 for (int i = 1; i < Rows; i++) { if (i == 1) { NerveList Item = new NerveList(Input, Count); Item.Location = i; Data.Add(Item); Last = Item; } else { NerveList Item = new NerveList(Last, Count); Item.Location = i; Data.Add(Item); Last = Item; } } Output = new NerveList(Last, CountOfOutput); Output.Location = Rows; Output.Layer = NerveList.LayerType.End; } public void Create(int[] RowsCounts, int CountOfOutput) { //初始化 输入 Input = new ValueList(RowsCounts[0]); NerveList Last = null; Data.Clear(); //开始创建网络 for (int i = 1; i < RowsCounts.Length; i++) { if (i == 1) { NerveList Item = new NerveList(Input, RowsCounts[i]); Item.Location = i; Data.Add(Item); Last = Item; } else { NerveList Item = new NerveList(Last, RowsCounts[i]); Item.Location = i; Data.Add(Item); Last = Item; } } if(Last != null) { Output = new NerveList(Last, CountOfOutput); } else { Output = new NerveList(Input, CountOfOutput); } Output.Location = RowsCounts.Length; Output.Layer = NerveList.LayerType.End; } public List<NerveList> Data = new List<NerveList>(); public ValueList Input; public NerveList Output; public NerveUnit this[int Row,int Index] { get { NerveUnit myResult=null; // if (Row >= 0 && Row < Data.Count) { myResult = Data[Row][Index]; } else { throw new Exception("Row=" + Row.ToString() + ",Count=" + Data.Count.ToString()); } // return myResult; } } public void Forward() { for(int i = 0; i < Data.Count; i++) { Data[i].Forward(); } Output.Forward(); } public void Back() { Output.Back(); for (int i = Data.Count -1; i >=0; i--) { Data[i].Back(); } } /// <summary> /// 此处的Input数目已经固定。 /// </summary> /// <param name="Input">输入的值</param> /// <param name="Output">真值</param> public void SetSample(double[] Input,double[] Output) { this.Input.Apply(Input); this.Output.ApplyTruth(Output); } /// <summary> /// 此处的Input数目已经固定。 /// </summary> /// <param name="Input">输入的值</param> /// <param name="Output">真值</param> public void SetSample(List<double> Input, List<double> Output) { this.Input.Apply(Input); this.Output.ApplyTruth(Output); } /// <summary> /// Square difference,平方差 /// </summary> public double SD { get { double myResult = 0; //----- myResult = Output.SD; //----- return myResult; } } public List<string> Figure(double[] Input) { this.Input.Apply(Input); Forward(); return Output.Report(false); } public string GetNetInfo() { StringBuilder myResult = new StringBuilder(); //----- myResult.Append(Input.Count.ToString()); for(int i = 0; i < Data.Count; i++) { myResult.Append(""+Data[i].Count .ToString()); } myResult.Append(""+Output.Count .ToString()); //----- return myResult.ToString(); } public OmegaNet GetOmegaNet() { OmegaNet myResult = new OmegaNet(); //----- for(int i = 0; i < Data.Count; i++) { myResult.Add(Data[i].GetOmegaList()); } myResult.Add(Output.GetOmegaList()); myResult.CountOfInput = Input.Count; //----- return myResult; } public void SetOmegas(OmegaNet Value) { //先创建网络 List<int> Rows = Value.GetRows(); int CountOfOutput = Value.GetCountOfOutput(); Create(Rows.ToArray(),CountOfOutput); // for(int i = 0;i<Data.Count; i++) { Data[i].SetOmegas(Value[i]); } Output.SetOmegas(Value.End); } }
4.5 样本单元类
public class SampleUnit { //样本单元 public List<double> Input=new List<double>(); public List<double> Output=new List<double>(); public string Report() { StringBuilder myResult = new StringBuilder(); //----- myResult.Append("Input="+Log.ToString(Input)); myResult.Append(" Output=" + Log.ToString(Output)); //----- return myResult.ToString(); } }
4.6 样本容器类
public class SampleContainer { //样本容器 public List<SampleUnit> Data = new List<SampleUnit>(); public void Add(double[] Input,double[] Output) { SampleUnit unit = new SampleUnit(); unit.Input = Input.ToList(); unit.Output = Output.ToList(); Data.Add(unit); } public void Add(List<double> Input, List<double> Output) { SampleUnit unit = new SampleUnit { Input = Input, Output = Output }; Data.Add(unit); } public void Add(SampleUnit unit) { Data.Add(unit); } public int Count { get { return Data.Count; } } public SampleUnit this[int Index] { get { SampleUnit myResult; //----- if (Index >= 0 && Index < Data.Count) { myResult = Data[Index]; } else { throw new Exception("Index=" + Index.ToString() + ",Count=" + Data.Count.ToString()); } //----- return myResult; } } public string Report() { StringBuilder myResult = new StringBuilder(); //----- for(int i = 0; i < Data.Count; i++) { if (i == 0) { myResult.Append(Data[i].Report()); } else { myResult.Append(" "+Data[i].Report()); } } //----- return myResult.ToString(); } }
4.7 Omega网络类(用于提取和设置神经网络权重)
public class OmegaNet { public class OmegaList { public class OmegaUnit { public OmegaUnit(List<double> Value) { Data = Value; } public OmegaUnit() { } public List<double> Data = new List<double>(); public void Add(double Value) { Data.Add(Value); } public int Count { get { return Data.Count; } } public double this[int Index] { get { if (Index >= 0 && Index < Data.Count) { return Data[Index]; } else { throw new Exception("Index=" + Index.ToString() + ",Count=" + Data.Count.ToString()); } } } public int Index = 0; public string Report(string Span="") { StringBuilder myResult = new StringBuilder(); //----- myResult.Append(Span+"."+Index.ToString()+" ="); for (int i = 0; i < Data.Count; i++) { if (i == 0) { myResult.Append(Data[i].ToString()); } else { myResult.Append(","+Data[i].ToString()); } } //----- return myResult.ToString(); } public UConfig.Page GetPage() { UConfig.Page myResult = new UConfig.Page(); myResult.Name = Index.ToString(); myResult.MakeSureCountOfVarsByCount(Data.Count); for(int i = 0; i < Data.Count; i++) { myResult.Vars[i].Value = Data[i].ToString(); } return myResult; } public void SetByPage(UConfig.Page Page) { for(int i = 0; i < Page.Vars.Count; i++) { Data.Add(double.Parse(Page.Vars[i].Value)); } Index = int.Parse(Page.Name); } } public List<OmegaUnit> Data = new List<OmegaUnit>(); public void Add(OmegaUnit Value) { Data.Add(Value); } public int Count { get { return Data.Count; } } public OmegaUnit this[int Index] { get { if (Index >= 0 && Index < Data.Count) { return Data[Index]; } else { throw new Exception("Index=" + Index.ToString() + ",Count=" + Data.Count.ToString()); } } } public int Index = 0; public string Report(string Span="") { StringBuilder myResult = new StringBuilder(); //----- string INSpan = Span + ""; myResult.Append(Span +Index.ToString()); myResult.Append(" "); for(int i = 0; i < Data.Count; i++) { if (i == 0) { myResult.Append(Span+Data[i].Report(INSpan)); } else { myResult.Append(" "+Span+Data[i].Report(INSpan)); } } //----- return myResult.ToString(); } public UConfig.Page GetPage() { UConfig.Page myResult = new UConfig.Page(); myResult.Name = Index.ToString(); for (int i = 0; i < Data.Count; i++) { myResult.Pages.Add(Data[i].GetPage()); } return myResult; } public void SetByPage(UConfig.Page Page) { for (int i = 0; i < Page.Pages.Count; i++) { OmegaUnit Item = new OmegaUnit(); Item.SetByPage(Page.Pages[i]); Data.Add(Item); } Index = int.Parse(Page.Name); } } public List<OmegaList> Data = new List<OmegaList>(); public void Add(OmegaList Value) { Data.Add(Value); } public int Count { get { return Data.Count; } } public OmegaList this[int Index] { get { if (Index >= 0 && Index < Data.Count) { return Data[Index]; } else { throw new Exception("Index=" + Index.ToString() + ",Count=" + Data.Count.ToString()); } } } public OmegaList End { get { return Data[Data.Count - 1]; } } public string Report(string Span="") { StringBuilder myResult = new StringBuilder(); //----- for(int i = 0; i < Data.Count; i++) { if (i == 0) { myResult.Append(Data[i].Report("")); } else { myResult.Append(" ***"); myResult.Append(" "+Data[i].Report("")); } } //----- return myResult.ToString(); } public int Index = 0; public UConfig.Page GetPage() { UConfig.Page myResult = new UConfig.Page(); myResult.Name = Index.ToString(); for (int i = 0; i < Data.Count; i++) { myResult.Pages.Add(Data[i].GetPage()); } UConfig.UVariable Input = new UConfig.UVariable(); Input.Name = "CountOfInput"; Input.Value = CountOfInput.ToString(); Input.Type = UConfig.VariableType.Digit; myResult.Vars.Add(Input); return myResult; } public void SetByPage(UConfig.Page Page) { Data.Clear(); for (int i = 0; i < Page.Pages.Count; i++) { OmegaList Item = new OmegaList(); Item.SetByPage(Page.Pages[i]); Data.Add(Item); } Index = int.Parse(Page.Name); CountOfInput = int.Parse(Page.Vars[0].Value); } public List<int> GetRows() { List<int> myResult = new List<int>(); //----- myResult.Add(CountOfInput); for(int i=0;i<Data.Count - 1; i++) { myResult.Add(Data[i].Count); } //----- return myResult; } public int GetCountOfOutput() { return End.Count; } public int CountOfInput = 0; }
5 具体研究
未完待续
以上是关于BP神经网络研究的主要内容,如果未能解决你的问题,请参考以下文章
撷英|第六十篇 基于BP神经网络模型的征地项目社会稳定风险评价研究