深度学习一:自己写java代码,训练一个神经元

神经网络与深度学习这本书是我学习深度学习的启蒙教材,感兴趣可以到链接出下载。通过一段时间的学习,感觉基本理解了梯度下降算法和反向传播算法,于是尝试着自己写代码来实现神经网络。一开始总是很难的,所以我设计了个非常简单的目标,训练一个神经元。比如我给他输入1,我期望它输出0,这就是一个反相器。我希望它能做到这一点,所以我对他进行训练。
训练一个神经元能简化梯度下降算法和反向传播算法的实现,也能帮助我们更好的理解升经这两个算法。对于初学深度学习的人来说,勇敢的迈出第一步非常的重要,因此,如果你能成功的训练一个神经元,那也意味着你在深度学习的学习中迈出了重要的一步。
关于梯度下降算法和反向传播算法,还是需要你认真阅读推荐的书籍,这两个算法是深度学习的基石,一定要彻底弄懂才行。
如果在网页上代码不太好看,你可以在这里下载源码:
源码

首先定义一个神经元类:

public class NeureCell {
	private double w = 0;
	private double b = 0;
	private double out = 0;
	private int in = 0;
	public void setIn(int in){
		this.in = in;
	}
	public void setWandB(double w,double b){
		this.w = w;
		this.b = b;
	}
	public double getW(){return w;}
	public double getB(){return b;}
	public double getOut(){
		double z = in*w+b;
		return 1/(1+Math.exp(-z));
	}
}

使用梯度下降算法训练神经网络

import java.util.Random;

public class DeepLearn {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		NeureCell cell = new NeureCell();
		Random random = new Random();
		//init w and b
		double eta = 3;//learn speed
		cell.setWandB(random.nextDouble(), random.nextDouble());
		cell.setIn(1);
		double a0 = cell.getOut();
		double dw = 0.2*eta*a0;	
		double db = 0.2*eta*a0;	
		cell.setWandB(cell.getW()-dw, cell.getB()-db);
		for(int i=0;i<200;i++){
			cell.setIn(1);
			double ai = cell.getOut();
			dw = 0.2*eta*ai;	
			db = 0.2*eta*ai;	
			cell.setWandB(cell.getW()-dw, cell.getB()-db);
			System.out.println(ai);
		}
		
	}

}

结果如下:
这里写图片描述

可以看到这个输出越来越接近与0了。
这里使用的是最简单的二次代价函数:
这里写图片描述

反向传播算法可以概括为一下五步:
这里写图片描述
如果你能理解这五步,那么你就会明白,这点代码完全就是按照这个步骤做了一遍而已。


我最新重写的卷积神经网络CupCnn在mnist准确率可达99%了,CupCnn也是用java写的,但是代码更规范,更加模块化,以下是CupCnn在github上的地址,欢迎大家下载:
CupCnn
更多详情请参考我的博文:
java写卷积神经网络—CupCnn简介

发布了116 篇原创文章 · 获赞 247 · 访问量 54万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章