opennars / OpenNARS-4

MIT License
27 stars 8 forks source link

[Feature] Load and save experience and memory #19

Open bowen-xu opened 1 year ago

bowen-xu commented 1 year ago

Is your feature request related to a problem? Please describe.

In OpenNARS 3.0.4, there are some routines for loading and saving experience and memory,

image

These functions are useful for users to analyzing system's exceptions and bugs.

Describe the solution you'd like

To save and load system's memory, pickle might be enough.

To save experience, using some log tools of python. To load experience, input them to the system line by line.

ARCJ137442 commented 1 year ago

I used PyNARS to wrap a "PyNARS-Interface", which includes ① some simplified input syntax, ② an easy-to-use "command system", and ③ a small tool for converting standardized data structures (currently only JSON) into Narsese Of course, by developing the "command system", I also explored the use of jsonpickle libraries for "Memory access", trying to save and load Memory objects with JSON, but had not investigated further due to a issue about "data size overload". Because the project is a personal research, the code is relatively personal, so for the time being, ⚠️the repository is still private, but it is now open to you for visibility. If possible, it may be able to migrate some code to a public repository or incorporate it into PyNARS as a pull request. I hope my previous research can provide some references and contributions to PyNARS :)


The Chinese version:

我先前在交互式学习NARS的时候,自己用PyNARS封装了一个「NARS接口」,其中包含①一些简化的输入语法②一个较为易用的「指令系统」③一个把标准化数据结构(目前只有JSON)转化为Narsese的小工具。 ​当然,在「指令系统」中我也探索过使用jsonpickle库进行「记忆存取」的工作,尝试用JSON保存与加载Memory对象,但当时因「数据规模问题」没有进一步研究。 因为项目是个人研究,其代码编写相对个人化,所以⚠️暂时还是私人存储库。但目前存储库已经对你开放了可见性,如果后续可行,它或许能在进行一些代码迁移后转为公开存储库,或者作为一个pr合并入PyNARS中。 ​希望我之前的研究能为PyNARS提供一些参考与贡献 :)

bowen-xu commented 1 year ago

@ARCJ137442 Sounds good. Feel free to raise pull-requests. The functions mentioned above (save/load experience/memory) are important for users to store/restore the system for debugging or other purposes. You can try to solve this if you wish. One question: why have to use json? I think pickle is the simplest way and enough for solving the issue.

ARCJ137442 commented 1 year ago

(I have provided the Chinese version in the later section, which may help you understand my idea faster)

This is more of a historical question, but it also involves my personal views on the "representation of NARS data structures implemented across computers".

In one sentence: I would like to have a memory storage format that is common across multiple "computer implementations of NARS" (I'll call it "CIN" for convenience)

(As a simple Narsese task stream, the storage format of NARS's experience just required the compatibility of Narsese syntax)


Here is some expanded information:

In order to make the study more convenient and comparative, we often use different CIN. Examples of CIN include OpenNARS(Java), ONA(C), and NARS-Python(Python), as well as other implementations such as PyNARS(Python) and NARS-Swift(Swift).

Previously, Christian H's "NARS-Pong" and BoYang XU's "NARS-FighterPlane" used the way of "opening program in command line + string IO" to make interaction in multiple CIN.

However, this kind of cross-CIN Demo has a major disadvantage, as stated in this issue: the running results of NARS learning (as memory and experience) cannot be saved as a file likes breakpoint, or "save its memory and experience, and continue to work on this basis in subsequent experiments (such as debugging the kernel, checking reasoning)"; moreover, because there is no "universial memory storage format" across CIN, it is difficult for such demos to do some more advanced "comparative tests between CINs" (for example, given the same memory and experience, observe the different reasoning methods, processes, and results of each CIN).

So when I was researching "Load and save memory in PyNARS" last year, I came up with the idea of using a "Universal markup language" like JSON to save its memory area (the code is represented by jsonpickle instead of pickle, which I have also seen the latter in ONA's scheme).

In summary,

  1. In order to achieve "progressive and comparative research between multiple NARS versions", it is necessary to achieve "storage of NARS memory area across CIN implementations". (this may also require stability between versions of the same CIN, and it can't occur that "modify a property name in class Memory, then the new version is incompatible with the old version")
  2. Therefore, it is necessary to use a "universal memory storage format that does not depend on a certain programming language" memory storage standard. (the method of directly using the language built-in serialization library has long been available in OpenNARS, but this storage method can only be used in languages around Java, which is totally different with "any language supports semantically invariant reading and writing" like JSON does)
  3. For this motivation, as an initial personal research, I used JSON format by jsonpickle instead of the Python-specific pickle. (although the real solution would be to "identify a standard for using JSON" rather than "call any existing serialization library directly")

The Chinese Version

这更多是一个历史问题,但其中也涉及到我对「跨计算机实现的NARS数据结构表示」的个人观点。

用一句话表示:我希望能有一个可以在多种「NARS的计算机实现」(为了方便称呼,我把它叫做「CIN」)中通用的记忆存储格式。 (经验作为简单的Narsese语句流,只要Narsese语法兼容即可)


下面是一些扩充信息:

为了使研究变得更为方便和有对比性,我们经常用到不同的CIN。这些CIN的例子主要有OpenNARS(Java)、ONA(C)、NARS-Python(Python),当然也包括PyNARS(Python)、NARS-Swift(Swift)等其它实现。 先前Christian H的「NARS-Pong」、BoYang XU的「NARS-FighterPlane」都使用了「命令行打开程序+文本输入输出」的方式实现在多个CIN的互动。

但这类跨CIN的Demo有个很大的缺点,也正如这个issue所说:NARS学习的成果(作为记忆与经验)无法以文件形式断点保存,或者说「保存其记忆与经验,并在后续实验中以此为基础继续开展工作(例如调试内核、检查推理)」;并且,因为没有跨CIN的「通用记忆格式」,这类Demo很难做到一些更高级的「对比性测试」(例如,给定相同的记忆与经验,观察各CIN推理方式、过程、结果的不同)。 所以我在去年研究「PyNARS记忆存取方案」时,就想到用类似JSON这样的「通用标记语言」去保存其记忆区(在代码的体现上就是使用jsonpickle而非pickle,后者我也有见到,可以参考ONA的方案)。

总的来说,

  1. 要想实现「多个NARS版本间的渐进性对比性研究」,就有必要实现「跨CIN实现的NARS记忆区存储方式」(这可能还需要对相同CIN的各个版本间保持稳定,不能「修改一个变量名后,新版与旧版就无法兼容」)
  2. 所以就有必要使用一个「不依赖于程序语言实现的通用记忆存储格式」的记忆存储标准(直接使用语言内置序列化库的方法,在OpenNARS早已有之,但这种存储方式只能在Java一众语言内通用,而无法像JSON那样做到『任何语言都支持语义不变的读写』)
  3. 出于这样的动机,作为一个在起步阶段的个人研究,我当时使用了JSON格式的jsonpickle而非特定在Python平台的pickle库(虽然真正的解决方法应该是「确定一个使用JSON的标准」而并非「直接调用现有序列化库)
poerlang commented 1 year ago

If only one project wins in the future, then pickle is the best choice, both in terms of performance, learning cost, and ease of use

ARCJ137442 commented 1 year ago

Now I have performed an experiment based on pull request #27 (uses ExConsole with cmd \pickle, \unpickle, at this commit), but it currently failed because of some object that unable to pickle.

The following is the result of test (only critical outputs):

Save Failed! Error: Can't pickle local object 'Bag.__init__.<locals>.map_priority'
...
Deserialization failed! Error: Ran out of input

Image: image

bowen-xu commented 1 year ago

Now I have performed an experiment based on pull request #27 (uses ExConsole with cmd \pickle, \unpickle, at this commit), but it currently failed because of some object that unable to pickle.

The following is the result of test (only critical outputs):

Save Failed! Error: Can't pickle local object 'Bag.__init__.<locals>.map_priority'
...
Deserialization failed! Error: Ran out of input

Yeah.. this is because there is a local (lambda) function in Bag. I think it would work just to make it a class method or global function.