## 初学者入门介绍
注意这个介绍只是针对码云"人工生命"（以后简称Frog)这个项目本身，并不是神经网络知识入门介绍。

### 项目的运行环境
Frog项目需要安装JDK8、Maven、GIT客户端，如果已经在本机上安装过的请跳过这一节：  
* 首先电脑要安装JDK8运行环境，请百度"JDK8 安装"。
* 然后需要安装Maven，请百度"Maven 安装"。Frog项目暂时没用到任何第三方库，但是安装Maven会方便它的运行。
* 然后需要安装Git客户端，请百度"Git 客户端安装"。
* 以下三项安装好后，打开windows命令行，在任一个目录下运行"git clone https://gitee.com/drinkjava2/frog", 就会从码云网站下载Frog项目的源码，然后打开frog目录，运行其中的run.bat批处理，就可以启动运行了。
* 如果不能下载源码或启动运行，需要检查是否路径环境变量设置正确，请在桌面“我的电脑”图标上右击，选“属性”->"系统高级设置"->"环境变量设置"，在系统变量Path里，确保三个软件的路径设置已加入，例如，在我的电脑上有，Path中包含了以下三个路径设置：
...(略)...;C:\jdk8\bin;F:\DevTools\git\Git\cmd;F:\DevTools\maven3.2.5\bin;...(略)...   

对于git初学者来说，可用在命令行下输入gitk查看历史记录，并结合“版本提交记录.md”的介绍了解项目的演化过程，如果要回到以前的某个历史版本，可以用git reset命令,  例如以下:  
git reset --hard 2fac4ae4084   
可以将项目源码重置到"人工生命v1.0.0"第一版。  

git reset --hard ae34b07e  
可以转回到分组测试的青蛙找食版。  

在项目根目录，有一个"版本提交记录.md"，简单介绍了一些提交的修改内容。

### 项目的设计思路
这个项目的基本设计思路很简单，就是试图模拟大自然的生命进化过程，一步步地从低到高，利用生物的数量、随机变异、优胜劣汰来逐渐获取一个能够适应复杂环境的模拟生命体。
它是模拟大自然进化，但是技术细节实现上和大自然有明显不同：  
大自然的生命首先必须面临一个生存问题，这需要它进化出一系列生理功能如繁殖、进食、肌肉等，而电脑模拟可以完全忽略这些生理要素，只需要关注模拟脑的形成过程就可以了。  
大自然的进化是一个不存在人为设计的过程，这是它的劣势，随时可能因为环境突变灭绝所有生命;而电脑模拟可以人为参与设计，一门心思让模拟生命适应环境，人的参与可以极大地缩短进化模拟过程。  
大自然生命体脑细胞数量可以极其庞大，这是它的优势，电脑虽然速度快，可以用串行模拟并行的脑细胞运算，但是随着细胞数向海量发展，串行机最终还是会力不从心，需要移植到并行机硬件。     
大自然的进化生命样本数量极其庞大，所有的生命都是它的实验品，而电脑模拟在这一点是弱项，只能用极少的样本数量和粗糙的虚拟环境去模拟。  
大自然的进化没有目的，没有参照物，存在即合理，而电脑模拟可以通过解剖和学习大自然的样本来进行拷贝、模拟。  
考虑到以上差异，电脑模拟必须尽量发挥自已的优点，避开缺点，模拟但不是全盘照搬真实生命的进化过程。因为我们的最终目的是要获得一个智能脑。  

### 算法
这个项目的一个特点就是重视实践胜过重视算法。目前神经网络研究主要偏重于模式识别等算法，对于如何构造出一个类似人脑这样复杂的、整体化的脑结构并没有给出一个按步就班可以实现的途径，而且笔者认为利用算法的搭配，有可能在搭建脑结构过程陷入误区，复杂的大脑结构可能不能用人为搭建的方式来构造，而必须通过让电脑自动进化出脑结构这种方式来完成。因为人的参与有两个问题：1.人可能犯错. 2.人的速度太慢，不利于用电脑的高速度来循环迭代，淘汰错误模型。  
如果说大自然有算法的话，那就只有一个算法：随机试错。不合理的生理结构、不合理的脑结构，都被大自然给淘汰掉了，剩下的肯定是最合理的。  
Frog项目的模拟也一样，如果有算法的话，"随机数"就是算法之王，排在第一位。其它的算法或模型，如模式识别等，都受"随机数"这个算法之王管辖。
"随机数"要和大样本数量、变异、优胜劣汰等原则一起使用，这样就可以保证正确的方案一定会出现，而且正确的方案一定会最后保留下来。例如：  
当前版本中，Frog有四个运动脑细胞，可以控制青蛙进行上下左右移动，还有四个感光脑细胞，能够看到四个不同方向是否有食物，我想让这个青蛙在看到食物时向它移动，但是不能使用硬编码，在算法上是怎么实现的呢?   方法就是每次青蛙诞生时会随机生成许多脑细胞，它的输入和输出触突位于脑内的任意随机位置，如果碰巧输入区在感光细胞位置，输出区在运动细胞位置，而且方向正确，那么这个青蛙当然会看到食物就向这个方向运动，最终会吃到更多的食物，会在生存竞争中胜出。  
这是一个最简单的例子，随机数可以解决很多复杂的问题，今后的脑的结构自动分化、模式识别算法中各个参数的调整等，都可以考虑用随机试错、适者生存的方式来解决。一招鲜，吃遍天，大自然也就只有随机试错这一个算法，但是它就是用这唯一一个算法造出了人类。 
 
### 程序源码导读
这是一个Java项目，分为三大模块: Application模块、Env模块、Frog模块

#### Application模块
见Application.java。这个模块用于项目的启动、关闭等基础服务，Windows环境下可以用run.bat来启动它查看演示。读它的源码需要了解一些Java Swing作图基本知识。  

#### Env模块
见Env.java，这个模块模拟一个生物生存区，用不同形状的图形点阵来表达和模拟食物、天敌、障碍等物体，这个虚拟空间由程序员全权控制和设计，将随着Frog的脑进化而不断变得越来越复杂，通过完成人为设计的一个又一个任务来引导青蛙的进化。   
Env.java中的可调整参数说明(请手工修改这些参数进行不同的测试，前5个参数很重要):
```
SHOW_SPEED： 调整实验的速度(1~1000)，值越小则越慢。
DELETE_EGGS: 每次运行是否先删除保存的蛋,如果设为false，将不删除保存的蛋，会接着上次的测试结果续继运行。 
EGG_QTY: 每次允许Frog下多少个蛋，通常下蛋取值在10~1000之间。蛋保存着我们测试的结果。实验的最终目标就是获得一批蛋。
FROG_PER_EGG： 每个蛋可以孵出多少个青蛙。  
SCREEN： 分屏测试，一轮测试可以分为多个批次进行，这里是屏数。每轮总的青蛙数量=EGG_QTY * FROG_PER_EGG, 每屏青蛙数=总数/SCREEN  
ENV_WIDTH: 虚拟环境的宽度大小，通常取值100~1000左右
ENV_HEIGHT: 虚拟环境高度大小，通常取值100~1000左右
FROG_BRAIN_DISP_WIDTH: Frog的脑图在屏幕上的显示大小,通常取值100~1000左右
STEPS_PER_ROUND: 每轮测试步数, 每一步相当于脑思考的一桢，所有青蛙的脑神经元被遍历一次。
FOOD_QTY：食物的数量，食物越多，则Frog的生存率就越高，能量排名靠前的一批Frog可以下蛋，其余的被淘汰。  
```
#### Frog模块
见Frog.java, 这是人工生命的主体，目前起名叫青蛙(Frog)，其实叫什么都一样。Frog不是生命的全盘模拟，它主要模拟生物的脑结构和功能，它主要具备以下与脑功能相关的器官：  
* 运动器官: (见MoveUp.java,MoveDown.java等)与运动神经元相连，目前只有4个动作：上下左右。简单地，它只是随便在脑区域指定了四个区，当这些区激活后，青蛙会向相应方向移动。  
* 进食器官：(见Eat.java)当Frog与食物的坐标重合时，食物会被从Env中删除，并相应增加Frog的能量值，并激活Frog的进食感觉器官（Happy.java)。随时间流逝青蛙能量将减少，能量耗尽则Frog死亡。  
* 视觉感觉器官: (见Eye.java)这是脑模型的一部分，在实验中先固定随意取脑内一片神经元区作为视网膜，这个视网膜上目前只有四个感光细胞，今后眼的感光细胞数量会参与进化，但目前笔者还没有头绪。  
* 进食奖励感觉器官: (见Happy.java)当青蛙吃掉食物后，这个器官所在区域内的所有神经元的输入触突激活。  
* 痛觉感觉器官: (见Pain.java)当青蛙靠近边界时激发，这个器官的作用是模拟痛觉，将来青蛙接近天敌时，这个器官也会激活。至于青蛙本体是否感觉到痛苦，这不在程序员考虑范围之内，反正这个器官激活后，它应该表现出很痛苦的应激反应，表现不出来的已经被自然淘汰了。我们只从青蛙的外在表现判断它的主观感受。  
* 脑内细胞组: （见Group.java抽象类及其子类)，Group类是器官的子类，它代表一组功能相似的脑细胞，目前只有一个随机连结实例(RandomConnectGroup.java)，它实现的算法是在指定矩形区内随机选取两点作为脑细胞的触突感受区和触突输出区，这个连接会在下一代青蛙生成时遗传下来，如果这个连接从没有用到，则有很大的机率被丢弃掉。另一方面如果用到了但不确，这个连接会连带它的主人青蛙一起被淘汰掉。随机连接模仿生物体天生的、可以遗传的本能条件反射，这不是一个很有用的反射，将来会被更多的后天形成的条件反射覆盖掉。

Group在脑活动中不起作用，可以把Group比作播种机，把种子排列好后，就撒手不管了,在遗传过程中有一个fat参数，如果细胞活跃多，则Group保留及变异的可能性大，反之则舍弃掉。
Group是器官的一种，所以蛋里存放着所有Group的位置、大小、内部参数等信息，但是蛋里面不保存具体的细胞。这样通过控制有多少个"播种机"，就可以控制大脑的结构了，这样可以缩小蛋(eggs.ser)的尺寸。 原则上Group遗传的一下代与父代是同一个播种(算法)类型。 
 
Group.java类的vary方法需要重写，每个Group实例负责自已的变异(如位置、大小、参数、数量变化)，基本原则是用进废退，通常有小变异，但有极小的概率大变异。
Group.java类的DrawOnBrainPicture方法需要重写，每个Group实例负责自已在脑图上的显示绘制。

目前青蛙脑还没有引入更多的算法（如记忆、模式识别功能),也就是说这个青蛙的开发还处在起步阶段，脑的结构是程序员要解决的问题，也是要获取的最终目标。脑模型的生成由电脑优胜夯汰、循环迭代进化生成，但这个模型的进化过程还是必须由程序员来掌控，一步步探索出来。  
另外这个项目不要局限于已有的编码，而要着眼于它的总体思路，大胆试错，现有的编码只是暂时的，随时都可能被推翻。  