Screen group test

pull/1/head
Yong Zhu 6 years ago
parent b090d746be
commit ae34b07e21

@ -1,5 +1,4 @@
## Frog | 人工生命
(English introduction please see "README_EN.md")
这是一个人工生命试验项目最终目标是创建“有自我意识表现”的模拟生命体技术架构基于02年提出的 [一个人工脑模型](一个人工脑模型.md)。
这个项目永远没有结束的时候,开始于模拟一个简单的生命体,然后是青蛙、狗......, 结束于有“自我意识表现”的人工脑,或者说,结束于被机器人代替人类的那一天。
@ -56,9 +55,10 @@ Frog: 这是人工生命的主体,目前起名叫青蛙(Frog),其实叫什
## 目前进展和成绩
2019.03.11 虚拟环境已建好,可以模拟低等生命的遗传、繁殖、变异、进化现象,但只能往一个方向运动,相当于一个最简单的单细胞生物,还不具备视觉能力,不具备主动找食能力。
运行run.bat可以查看演示需要安装Java8和Maven
运行run.bat可以查看演示需要安装Java8和Maven
![result1](https://gitee.com/drinkjava2/frog/raw/master/result1.gif)
另外每步演示的结果(egg)会存盘在根目根目录下名为egg.ser可以删除这个文件以从头开始新的测试。因为还没涉及脑模型的搭建可以看到有些青蛙跑得飞快这是自然选择的结果因为跑在最前面的吃得多。
一些重要的测试参数如显示区大小、是否每次测试要删除保存的蛋等请参见Env.java中开头的常量设定可以手工修改进行不同参数的测试。
2019.03.21 添加了脑图改进随机运动模式为Hungry区驱动。从脑图上可以直观地观察脑结构方便调试。
2019.04.01 改进脑图的显示bug, 每一次生成Frog时添加随机神经元并简单实现"卵+精子->受精卵"算法,以促进种群多样性。
2019-04-12 添加一个简单的眼睛(只有四个感光细胞),自然选择的结果是眼睛被选中,但是和运动区短路了,谈不上智能。但有眼睛后找食效率明显提高了,见下图:
@ -66,7 +66,7 @@ Frog: 这是人工生命的主体,目前起名叫青蛙(Frog),其实叫什
2019-06-13 做了一些重构清理加上了Happy和Pain两个器官分别对应进食奖励和痛苦感后者在靠近边界时激发。观查它的表现痛苦感生效了一些Frog跑到边界后就不再前进而是顺着边界溜下去了但是Happy器官没有生效这也很显然因为Happy属于复杂的进食条件反射链的一部分在没有记忆器官算法引入之前再怎么优胜劣汰也是没办法用上进食奖励信号的。见下图
![resut3](https://gitee.com/drinkjava2/frog/raw/master/result3.gif)
2019-06-26 找食效率太低又改回到4.12的用连接数量代替权值这个逻辑人为设计的算法居然比不过随机连接。Pain器官的加入没有提高找食效率必须与感光细胞合用才能知道是哪个边界急需引入记忆功能。
2019-06-28 为了让青蛙看到边界又加了个新的眼睛它是一个可自进化的nxn点阵的眼睛将来会取代只有四个象素点(但能看得远)的老眼睛。到目前为止,依然还没有进行模式识别和记忆功能开发。另外脑图可以动态显示了,用一个红圈标记出被动态跟踪显示的青蛙。
2019-06-28 为了让青蛙看到边界又加了个新的眼睛它是一个可自进化的nxn点阵的眼睛将来会取代只有四个象素点(但能看得远)的老眼睛。到目前为止,依然还没有进行模式识别和记忆功能开发。另外脑图可以动态显示了,用一个红圈标记出被动态跟踪显示的青蛙。
2019-07-28
有以下改动1.在Env区中间加了一个陷阱区Trap以增加趣味性自然选择的结果是青蛙会自动绕开陷阱区。2.增加一个Active器官它的作用是一直保持激活发现比Hungry器官驱动更能提高找食效率。3.增加一个Chance器官,它的作用是引入随机扰动,打破青蛙有时候围着一个食物打转就是吃不着的死循环。目前进食奖励信号没用到,白白浪费了。
另外Chance和Eye类里也再次运用了随机试错原理去确定关键参数效果还不错有兴趣的可以看一看源码。
@ -75,13 +75,14 @@ Frog: 这是人工生命的主体,目前起名叫青蛙(Frog),其实叫什
另外发现青蛙其实是有记忆能力的,因为连接本身就是一种记忆,只不过它没有复杂的模式识别能力,例如给个蛇的图片它就认不出来。以后的工作将以模式识别为重点(当然随机连接看起来很有用,以后还可能保留)基本原理是见note中提到的仿照波传播及全息存储原理在思维区逆向成像。而且脑可能改成三维结构并根据逆向成像原理要将所有输入输出器官全移到三维结构的同一侧(即思维区)。这将会是一个非常大的改动下面我简单画了一个3D示意图来说明我想象中的这个模式识别和记忆的原理至于对不对还需要实验来验证:
![3d-model](https://gitee.com/drinkjava2/frog/raw/master/3d-model.gif)
这个模型的最顶层表示眼睛的感光细胞(或任意输入输出细胞),同时也是思维区,红色表示一个长条的图形,兰色表示一个三角图形,如果这两个图形经常有规律地同时出现,就会把它们共有的节点撑大,见紫色的节点,当红色图形单独出现,就会强烈激活紫色节点,然后紫色节点的信号反向传播,就会激活三角图形,反之亦然。这就同时解释了模式识别和记忆(或者说回忆)功能的的原理。一个节点可以被多个感光细胞共享,所以它的存储能力是很强的。而且可能这个原理比较符合生物脑结构。当然,实际编程时,虚拟神经元不一定要排成正立方三角,而可能通过胡乱排放,大致上过得去就行了,也许能乱拳打死老师傅,最终要靠电脑自动随机的排放,然后用优胜劣汰来筛选。目前有个难点是这个记忆功能在思维区成像是如何有条不紊地大体上按串行进行工作的,这个问题先放一放。
2019-08-04 更新了一个分组测试功能,如果测试青蛙数量太多,可以分批来测试,每轮测试最少的青蛙数量可以少到只有一个,这是用时间来换空间。
## 版权 | License
[Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0)
## 期望 | Futures
欢迎发issue提出建意或加入开发组,尤其欢迎能接触到超级计算机的同学加入,随着神经元数量增多,对电脑的速度要求会越来越高,很快将达到台式机性能瓶颈,只能通过拖长运行时间来换取大样本数量了。
另外本项目正式宣布开启哭穷模式比提交一个pull request还能帮助这个项目开发的莫过于提交一个红包了您的赞助将实实在在地转化成我(或其它开发者)的项目开发时间,本项目将建立赞助者名单及收支明细账。
欢迎发issue、私信等方式提出建议或加入开发组。
另外本项目开启哭穷模式比提交一个pull request还能帮助这个项目开发的莫过于提交一个红包了金钱就是时间,您的捐助将只会用于回馈本项目的实际参与开发者。
## 作者其它开源项目 | Other Projects
- [Java持久层工具 jSqlBox](https://gitee.com/drinkjava2/jSqlBox)
@ -92,4 +93,4 @@ Frog: 这是人工生命的主体,目前起名叫青蛙(Frog),其实叫什
## 关注我 | About Me
[Github](https://github.com/drinkjava2)
[码云](https://gitee.com/drinkjava2)
微信:yong99819981(如想长期关注本项目、交流信息,或想参与具体项目开发的,请留言加"人工生命群",如果只是想临时私聊也可加我好友后再删掉,我不介意)
微信:yong99819981(如想长期关注本项目、交流信息,或想参与具体开发的,请留言加"人工生命群",如果只是想临时私聊也可加我好友后再删掉,我不介意)

File diff suppressed because it is too large Load Diff

@ -15,7 +15,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@ -39,46 +38,41 @@ public class EggTool {
/**
* Frogs which have higher energy lay eggs
*
* Java (fat)Frog, Frog
*
* Java ()Frog, Frog
* EGG_QTY
*/
public static void layEggs(Env env) {
sortFrogsOrderByEnergyDesc(env);
public static void layEggs() {
sortFrogsOrderByEnergyDesc();
Frog first = env.frogs.get(0);
Frog last = env.frogs.get(env.frogs.size() - 1);
Frog first = Env.frogs.get(0);
Frog last = Env.frogs.get(Env.frogs.size() - 1);
if (Env.DEBUG_MODE)
for (int i = 0; i < first.organs.size(); i++) {
Organ org = first.organs.get(i);
System.out.println("Organ(" + i + ")=" + org + ", fat=" + org.fat + ", organWasteEnergy="
System.out.println("Organ(" + i + ")=" + org + ", fat=" + org.fat + ", organWasteEnergy="
+ org.organActiveEnergy + ", outputEnergy=" + org.organOutputEnergy);
}
System.out.println("1st frog has " + first.organs.size() + " organs, energy=" + first.energy + ", seeDist="
+ ((Eye) first.organs.get(6)).seeDistance + ", chance=" + ((Chance) first.organs.get(10)).percent);
System.out.println("Last frog has " + last.organs.size() + " organs, energy=" + last.energy);
try {
List<Egg> newEggs = new ArrayList<>();
Env.eggs.clear();
for (int i = 0; i < Env.EGG_QTY; i++)
newEggs.add(new Egg(env.frogs.get(i)));
Env.eggs.add(new Egg(Env.frogs.get(i)));
FileOutputStream fo = new FileOutputStream(Application.CLASSPATH + "eggs.ser");
ObjectOutputStream so = new ObjectOutputStream(fo);
so.writeObject(newEggs);
so.writeObject(Env.eggs);
so.close();
env.eggs = newEggs;
System.out
.println("Saved " + env.eggs.size() + " eggs to file '" + Application.CLASSPATH + "eggs.ser" + "'");
System.out.print("\r1st frog has " + first.organs.size() + " organs, energy=" + first.energy + ", seeDist="
+ ((Eye) first.organs.get(6)).seeDistance + ", chance=" + ((Chance) first.organs.get(10)).percent);
System.out.println(", Last frog has " + last.organs.size() + " organs, energy=" + last.energy);
System.out.println("Saved 1 group eggs to file '" + Application.CLASSPATH + "eggs.ser'");
} catch (IOException e) {
System.out.println(e);
}
}
private static void sortFrogsOrderByEnergyDesc(Env env) {// 按能量多少给青蛙排序
Collections.sort(env.frogs, new Comparator<Frog>() {
private static void sortFrogsOrderByEnergyDesc() {// 按能量多少给青蛙排序
Collections.sort(Env.frogs, new Comparator<Frog>() {
public int compare(Frog a, Frog b) {
if (a.energy > b.energy)
return -1;
@ -90,24 +84,6 @@ public class EggTool {
});
}
// private static void sortFrogsOrderByEnergyDesc(Env env) {//
// 按吃到食物数量、剩余能量多少给青蛙排序
// Collections.sort(env.frogs, new Comparator<Frog>() {
// public int compare(Frog a, Frog b) {
// if (a.ateFood > b.ateFood)
// return -1;
// else if (a.ateFood == b.ateFood) {
// // if (a.energy > b.energy)
// // return -1;
// // if (a.energy < b.energy)
// // return 1;
// return 0;
// } else
// return 1;
// }
// });
// }
public static void deleteEggs() {
System.out.println("Delete exist egg file: '" + Application.CLASSPATH + "eggs.ser'");
FrogFileUtils.deleteFile(Application.CLASSPATH + "eggs.ser");
@ -117,25 +93,26 @@ public class EggTool {
* Egg
*/
@SuppressWarnings("unchecked")
public static void loadEggs(Env env) {
public static void loadEggs() {
boolean errorfound = false;
try {
FileInputStream eggsFile = new FileInputStream(Application.CLASSPATH + "eggs.ser");
ObjectInputStream eggsInputStream = new ObjectInputStream(eggsFile);
env.eggs = (List<Egg>) eggsInputStream.readObject();
Env.eggs = (List<Egg>) eggsInputStream.readObject();
System.out.println(
"Loaded " + env.eggs.size() + " eggs from file '" + Application.CLASSPATH + "eggs.ser" + "'.");
"Loaded " + Env.eggs.size() + " eggs from file '" + Application.CLASSPATH + "eggs.ser" + "'.\n");
eggsInputStream.close();
} catch (Exception e) {
errorfound = true;
}
if (errorfound) {
System.out.println("Fail to load egg file at path '" + Application.CLASSPATH + "', created " + Env.EGG_QTY
+ " new eggs to do test.");
env.eggs = new ArrayList<Egg>();
for (int i = 0; i < Env.EGG_QTY; i++)
env.eggs.add(new Egg());
Env.eggs.clear();
for (int j = 0; j < Env.EGG_QTY; j++)
Env.eggs.add(new Egg());
System.out.println("Fail to load egg file at path '" + Application.CLASSPATH + "', created "
+ Env.eggs.size() + " eggs to do test.\n");
}
}
}

@ -47,9 +47,11 @@ ENV_WIDTH:
ENV_HEIGHT: 虚拟环境高度大小通常取值100~1000左右
FROG_BRAIN_DISP_WIDTH: Frog的脑图在屏幕上的显示大小,通常取值100~1000左右
STEPS_PER_ROUND: 每轮测试步数, 每一步相当于脑思考的一桢,所有青蛙的脑神经元被遍历一次。
EGG_QTY: 每次允许Frog下多少个蛋每个蛋可以孵出4个青蛙。通常下蛋取值在10~1000之间。蛋保存着我们测试的结果。实验的最终目标就是获得一个蛋。
FOOD_QTY食物的数量食物越多则Frog的生存率就越高能量排名靠前的一批Frog可以下蛋其余的被淘汰。
DELETE_EGGS: 每次运行是否先删除保存的蛋
EGG_QTY: 每次允许Frog下多少个蛋通常下蛋取值在10~1000之间。蛋保存着我们测试的结果。实验的最终目标就是获得一批蛋。
FROG_PER_EGG 每个蛋可以孵出多少个青蛙。
SCREEN 分屏测试,一轮测试可以分为多个批次进行,这里是屏数。每轮总的青蛙数量=EGG_QTY * FROG_PER_EGG * SCREEN
FOOD_QTY食物的数量食物越多则Frog的生存率就越高能量排名靠前的一批Frog可以下蛋其余的被淘汰。
DELETE_EGGS: 每次运行是否先删除保存的蛋,如果设为false将不删除保存的蛋会接着上次的测试结果续继运行。
DEBUG_MODE: 调试模式开关,如开启会打印出更多的调试信息
```
#### Frog模块

File diff suppressed because one or more lines are too long

@ -56,4 +56,7 @@
1. 在Env区中间加了一个陷阱区Trap以增加趣味性青蛙如果走到陷阱区就死掉结果自然选择的结果是青蛙会绕开陷阱区。
2. 青蛙增加一个Active器官它的作用是一直保持激活如果有神经元触突位于这个区就会驱动神经元兴奋这个器官经实践证明比Hungry器官驱动更能提高找食效率。
3. 青蛙增加一个Chance器官,它的作用是引入随机扰动,打破青蛙有时候围着一个食物打转就是吃不着的死循环。
从当前这个版本可以看出,实际上青蛙是有一定的记忆能力的,连接就=记忆只不过没有模式识别能力以后的工作将以模式识别为重点基本原理是见note中提到的仿照全息存储原理在思维区逆向成像。因为逆向成像的限制以后的版本所有的器官会被移到脑图的同一侧不再是随意分布在脑图上了这将是一个比较明显的改动。当然随机连接这个算法看起来比较有用以后还是可能保留的。
从当前这个版本可以看出,实际上青蛙是有一定的记忆能力的,连接就=记忆只不过没有模式识别能力以后的工作将以模式识别为重点基本原理是见note中提到的仿照全息存储原理在思维区逆向成像。因为逆向成像的限制以后的版本所有的器官会被移到脑图的同一侧不再是随意分布在脑图上了这将是一个比较明显的改动。当然随机连接这个算法看起来比较有用以后还是可能保留的。
### 2019-08-04, Commit: Screen group test
引入分屏测试功能如果青蛙数量多可以分屏来测试每屏青蛙的数量可以少到只有1只。
Loading…
Cancel
Save