动态创建一个相同且独立的神经网络副本。 JAVA
Dynamically creating an identical and independent copy of a neural network. JAVA
上下文
我正在模拟行为进化。为此,我使用神经网络来模拟行为。实际上有成千上万个这样的神经网络在相互作用。在任何给定世代的末尾,最强的行为都会被复制到它的邻居身上。当这种情况发生时,我需要在新的神经网络上创建一个相同但独立的更强的神经网络版本;从而取代它。
问题
我已经研究过深度克隆,它可以工作,但它是复制节点引用,而不是创建一个新的相同实例。困难来自系统结构。我看不出如何改善它。
速度也是一个因素。我每周需要 运行 数百万次迭代。
如有任何帮助,我们将不胜感激。
体系结构
单元格
public class Cell_NN Extends Cell
{
private Network network;
//Methods
}
网络
public class Network implements Cloneable, Serializable
{
private ArrayList<ArrayList<Node>> net;
private ArrayList<Node> layer;
//Methods
}
节点
public class Node implements Cloneable, Serializable
{
private ArrayList<Node> nextNodes;
private ArrayList<Float> weights;
//Methods
}
深度克隆(我从 Whosebug 上抄袭的)
public Network deepClone()
{
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Network network = (Network) ois.readObject();
return (Network) ois.readObject();
} catch (IOException e) {
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
我不确定这是否被允许,但这是我的 github 如果您想了解更多信息:Napier40124399。项目名为 HonorsMain_v2,是 public。
我认为您的代码只包含一个小错误:
Network network = (Network) ois.readObject();
return (Network) ois.readObject();
在这里,您从 ObjectInputStream
读取网络两次,并且 return 第二次读取网络(应该为空)。如果您删除第一行,它应该可以工作。
对象是深度克隆的,新网络实例中的所有引用都正确连接到彼此,而不是原始对象。
但是, 这种序列化/反序列化在性能方面非常昂贵。如果性能至关重要,我建议找到一个处理速度更快的结构。
例如,每个网络有两个平面数组,一个带有权重(作为原始浮点数甚至整数),另一个带有指向下一个节点的 int 索引,使用 System.arraycopy()
.
我觉得这部分深度克隆代码很奇怪:
Network network = (Network) ois.readObject();
return (Network) ois.readObject();
读取对象两次,只返回第二次...我希望这里有异常。
上下文 我正在模拟行为进化。为此,我使用神经网络来模拟行为。实际上有成千上万个这样的神经网络在相互作用。在任何给定世代的末尾,最强的行为都会被复制到它的邻居身上。当这种情况发生时,我需要在新的神经网络上创建一个相同但独立的更强的神经网络版本;从而取代它。
问题 我已经研究过深度克隆,它可以工作,但它是复制节点引用,而不是创建一个新的相同实例。困难来自系统结构。我看不出如何改善它。 速度也是一个因素。我每周需要 运行 数百万次迭代。
如有任何帮助,我们将不胜感激。
体系结构
单元格
public class Cell_NN Extends Cell
{
private Network network;
//Methods
}
网络
public class Network implements Cloneable, Serializable
{
private ArrayList<ArrayList<Node>> net;
private ArrayList<Node> layer;
//Methods
}
节点
public class Node implements Cloneable, Serializable
{
private ArrayList<Node> nextNodes;
private ArrayList<Float> weights;
//Methods
}
深度克隆(我从 Whosebug 上抄袭的)
public Network deepClone()
{
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Network network = (Network) ois.readObject();
return (Network) ois.readObject();
} catch (IOException e) {
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
我不确定这是否被允许,但这是我的 github 如果您想了解更多信息:Napier40124399。项目名为 HonorsMain_v2,是 public。
我认为您的代码只包含一个小错误:
Network network = (Network) ois.readObject();
return (Network) ois.readObject();
在这里,您从 ObjectInputStream
读取网络两次,并且 return 第二次读取网络(应该为空)。如果您删除第一行,它应该可以工作。
对象是深度克隆的,新网络实例中的所有引用都正确连接到彼此,而不是原始对象。
但是, 这种序列化/反序列化在性能方面非常昂贵。如果性能至关重要,我建议找到一个处理速度更快的结构。
例如,每个网络有两个平面数组,一个带有权重(作为原始浮点数甚至整数),另一个带有指向下一个节点的 int 索引,使用 System.arraycopy()
.
我觉得这部分深度克隆代码很奇怪:
Network network = (Network) ois.readObject();
return (Network) ois.readObject();
读取对象两次,只返回第二次...我希望这里有异常。