単一化の機構を利用した階層型強化学習のテーブル圧縮手法の検討
第10回 人工知能学会 汎用人工知能研究会(SIG-AGI)
2018-11-22

1

私の研究の長期的目標• 脳を模倣して「人間のような知能を持つ機械」を作る。（脳のリバースエンジニアリング）
運動野
前頭前野

言語野

視覚野

大脳皮質

基底核

扁桃体

海馬

小脳

2

現在の短期的目標：前頭前野周辺の計算モデルの構築を目指す[Ichisugi, ICANN 2012][Ichisugi and Takahashi, BICA 2018]

Yuuji Ichisugi, A Computational Model of Motor
Areas Based on Bayesian Networks and Most
Probable Explanations, In Proc. of The
International Conference on Artificial Neural
Networks (ICANN 2012), Part I, LNCS 7552,
pp.726--733, 2012.

Ichisugi Y., Takahashi N., A Formal Model of the
Mechanism of Semantic Analysis in the Brain. In:
Biologically Inspired Cognitive Architectures 2018 (BICA
2018), Advances in Intelligent Systems and Computing, vol848. Springer, Cham, pp.128--137, 2018.

運動野
前頭前野

言語野

視覚野

[Nakada and Ichisugi, BICA 2017]

大脳皮質

基底核

扁桃体

海馬

Hidemoto Nakada and Yuuji Ichisugi,Context-Dependent Robust Text Recognition using
Large-scale Restricted Bayesian Network, In Proc. ofInternational Conference on Biologically Inspired
Cognitive Architectures (BICA 2017), Procedia
Computer Science, Vol. 123, pp.314--320, 2018.

小脳概要• 階層型強化学習 RGoal の行動価値関数の
テーブル圧縮手法を提案– 大脳皮質による実現方法の１つの案を提案– 理想的に圧縮されたテーブルを手で書く記述実
験により、提案手法を予備的評価– RGoal をプログラム合成システムと見なし、合成される「プログラム」の性質に関して考察

4

RGoal アーキテクチャ[一杉 2018年8月 汎用人工知能研究会]• 多層の階層型強化学習アーキテクチャ• エージェントは、各ステップで行動するかサブルーチンを呼び出すかのどちらかを選択• ここではサブルーチン g は「任意の環境の状態からある１つの状態（サブゴール） g に向かう方策」– 例：はしごをかける（「はしごをかけた状態」をサブゴールとして行動する）
5

価値関数分解• 関数 Q をサブゴール g の到着の前後で分解
s

a

s'

𝜋𝜋

g

𝜋𝜋

G

𝑄𝑄𝐺𝐺𝜋𝜋 (𝑠𝑠, 𝑔𝑔), 𝑎𝑎 = 𝑴𝑴𝝅𝝅 𝒔𝒔, 𝒈𝒈, 𝒂𝒂 + 𝑉𝑉𝐺𝐺𝜋𝜋 𝑔𝑔• 関数 M(s,g,a) は状態 s から g に到達するまでの報酬の総和の期待値– おおもとのゴール G に依存しないため、異なるタ
スク間で共有できる。
– 共有により、マルチタスク環境で学習が速くなる。
6

RGoal のテーブル• テーブル M(s,g,a) のインデックスの次元は環境の状態 s の次元の３倍– 素朴に実装するとテーブルのサイズが爆発• このテーブルを単一化の機構を使って圧縮する手法を提案– 圧縮により学習パラメタが減り、学習速度・汎化
性能がより向上するはず。

7

単一化(unification)とは• 変数を含む２つの項が等しくなるように、変数の値を割り当てる操作。
• 計算機科学、理論言語学でよく使われる。
– prolog 言語, 型推論など
例：
ベクトル１

ベクトル２

単一化の結果 変数の割り当て

(2,X)

(Y,3)

(2,3)

X=3,Y=2

(2,X)

(3,Y)

単一化失敗

-

テーブル圧縮の例• パターンと値の組からなるルールの集合としてテーブルを表現
インデックス

値

パターン

値

0

1.0

1

3.0

1

3.0

X

1.0

2

1.0

3

1.0

4

1.0

インデックスが 1 のとき 3.0
その他の時は 1.0

サイズが５のテーブルが２個のルールに圧縮9インデックスが２次元の場合の例
Y 0

1

2

3

4

パターン

値

2.0 1.0 1.0 3.0 1.0

(3,3)

4.0

1

1.0 2.0 1.0 3.0 1.0

(X,3)

3.0

2

1.0 1.0 2.0 3.0 1.0

(X,X)

2.0

3

1.0 1.0 1.0 4.0 1.0

(X,Y)

1.0

4

1.0 1.0 1.0 3.0 2.0

X0

サイズ 5 x 5 = 25 のテーブルが４個のルールに圧縮
・ ルールの順序には意味はないものとする。
・ マッチするルールが複数ある場合、最も特殊なパターンをもつルールの方を選択する。
・ 「最も特殊なパターン」とは、用いる変数の種類が最も少ないパターンと定義。
10

精度を落とした圧縮の例• 一般に精度を落としてよければテーブルをより小さく圧縮できる。
X
0
1
2
3
4

Y 0

1

2

3

4

−∞ 1.0 −∞ −∞ −∞−∞ 1.5 −∞ −∞ −∞

パターン

値

(X,1)

1.4

(X,Y)

−∞

−∞ 1.2 −∞ −∞ −∞−∞ 2.0 −∞ −∞ −∞−∞ 1.3 −∞ −∞ −∞どのくらい圧縮すればよいかは、オンライン性
能を最大化するためのハイパパラメタの１つ

11単一化によるテーブル圧縮の脳内での実現の可能性

12

なぜ単一化？
• 理論言語学における文法記述の枠組みの多くが単一化文法– 単一化文法：単一化を使って構文解析を進めていく文法枠組みの総称– LFG, HPSG, CCG, TAG, ...
自然言語の性質を表現する道具として洗練され到達した１つの結果が単一化文法であるという事実は、脳の言語野で何らかの形で単一化が行われていることを強く示唆している。
大脳皮質に単一化が行えるなら、前頭前野も単一化を行えるはず。

確率伝搬と大脳皮質の対応 Ver.2
U1
𝐵𝐵𝐵𝐵𝐵𝐵 𝑥𝑥 = 𝛼𝛼𝛼𝛼 𝑥𝑥 𝜋𝜋 𝑥𝑥
𝜋𝜋(𝑥𝑥) = Σu1 ,…,um 𝑃𝑃 𝑥𝑥 𝑢𝑢1 , … , 𝑢𝑢𝑚𝑚 Π𝑘𝑘 𝜋𝜋𝑋𝑋 𝑢𝑢𝑘𝑘
πX(uk)
𝜆𝜆 𝑥𝑥 = Π𝑙𝑙 𝜆𝜆𝑌𝑌𝑙𝑙 𝑥𝑥
πYl(x)𝜋𝜋𝑌𝑌𝑙𝑙 𝑥𝑥 = 𝐵𝐵𝐵𝐵𝐵𝐵 𝑥𝑥 ⁄𝜆𝜆𝑌𝑌𝑙𝑙 𝑥𝑥
𝜆𝜆𝑋𝑋 (𝑢𝑢𝑘𝑘 ) = Σ𝑥𝑥 𝜆𝜆(𝑥𝑥)Σ𝑢𝑢1,…,𝑢𝑢𝑚𝑚 ∖𝑢𝑢𝑘𝑘 𝑃𝑃 𝑥𝑥 𝑢𝑢1 , … , 𝑢𝑢𝑚𝑚 Π𝑖𝑖≠𝑘𝑘 𝜋𝜋𝑋𝑋 𝑢𝑢𝑖𝑖
Y1

I
II
III
IV
V
VI
下位領野

上位領野

解剖学的構造

...

[未発表]

Um
λX(uk)X

λYl(x)...

Yn

𝜋𝜋 𝑢𝑢𝑘𝑘

𝜋𝜋 𝑥𝑥I𝜆𝜆 𝑢𝑢𝑘𝑘

𝜆𝜆 𝑥𝑥

III

𝐵𝐵𝐸𝐸𝐸𝐸 𝑥𝑥

V

𝜆𝜆𝑋𝑋 𝑢𝑢𝑘𝑘

𝐵𝐵𝐵𝐵𝐵𝐵 𝑢𝑢𝑘𝑘
𝜋𝜋𝑋𝑋 𝑢𝑢𝑘𝑘

𝜆𝜆𝑌𝑌𝑙𝑙 𝑥𝑥

𝜋𝜋𝑌𝑌𝑙𝑙 𝑥𝑥

II
IV
VI
14

ゲートノード[一杉 2016 汎用人工知能研究会]

制御ノード
Open

U

Close

U

ゲートノード制御ノードの値がOpen なら U と Ｘ が結合、Close なら切断
ゲートノードの条件付確率表

X

𝑃𝑃 𝐺𝐺 = 0 𝑐𝑐, 𝑢𝑢 = 1 − 1 − 𝑤𝑤𝑢𝑢 ¬𝑢𝑢 1 − 𝑤𝑤𝑐𝑐 c
𝑃𝑃 𝐺𝐺 = 1 𝑐𝑐, 𝑢𝑢 = 1 − 𝑤𝑤𝑢𝑢 ¬𝑢𝑢 1 − 𝑤𝑤𝑐𝑐 𝑐𝑐

X

・ 論理回路のような感覚で生成モデルを設計できる。
・ あくまでベイジアンネットなので、 出力（下流の値）から入力（上流の値）の推定もできる。
ゲートノードの行列
C

U1

C

U2

U1

U2

X1

X2

略記
X1

X2

ベイジアンネットによるパターン
マッチを行う回路の１つの案
パターン内の変数への値の割り当てパターン P

X

Y

Z

ゲートノード群
ノードＰはパターンのＩＤを表す。
パターンに応じてゲートの開閉を制御する。

入力ベクトル
16

パターンマッチの結果の例
パターン内の変数への値の割り当て(X,X,1,Y,Y,4)
パターン P

X
5

Y

Z

9

ゲートノード群

下の層に値を与えると、上の層にマッチするパターンと変数割り当てが推論され
る。

5

5

1

9

9

4

入力ベクトル
17

脳におけるルール（パターン）の数• 大脳皮質においては、１つのルールが１つのミニコラムに対応するのではないかと考えている。
– 仮にヒトの大脳皮質全体のニューロン数を１００
憶個とし、その 1/100 がルールを表現する領野で、１つのミニコラム内のニューロン数が１００個だとすると、１００万個のルールが保持されること
になる。

18

ルールの「記述実験」• ベイジアンネットによるパターンマッチの学習を成功させるのはおそらく簡単ではなく、適切な目的関数の設計が必要• まずは理想的に圧縮されたテーブルを手で書いてみる記述実験により、適切な目的関数設計のヒントを得るのが今回の目的

19

汎用人工知能とプログラム合成• 強化学習によるプログラム合成は汎用人工知能実現への有望なアプローチ• AIXI [Hutter 2000], MagicHaskeller [Katayama 2008,2018], DNC(Differentiable Neural Computers) [Graves
et al. 2016]• どういう「プログラミング言語」を使うかが、性能に大きく影響• RGoal のテーブルをプログラムと見なすと、それはどのような性質を持つのか？
– それを知るのが記述実験のもう１つの目的

20

例題：単純化した積み木の世界
手
物体１ r
c 物体２
座標

0

1

2

手の状態： H∈ {open, hld1, hld2}
物体１、物体２の形： O1,O2∈ {r, c}
手、物体の座標： P0,P1,P2∈ {0,1,2}
環境の状態 = (H, P0, O1, P1, O2, P2)
Cf. オブジェクトファイル[Kahneman et al. 1992]
21

エージェントの動作• 現在の状態 s 、サブゴール g のとき、
[s,g,A] とマッチするルールを１つ選択。
• 単一化の結果得られた行動 A を実行する。
– プリミティブならそれを実行。
– サブルーチン呼び出し g(m) なら現在のサブ
ゴール g をスタックに積み、 サブゴールを mに設定。
注：前回発表[一杉 2018年8月 汎用人工知能研究会] の• これを繰り返す。

RGoal にはスタックがないが、今回はスタックを導入

prolog 言語で「インタープリタ」を書いて記述したプログラムの動作を確認

22

ルールの例sgam([hld1,0,O1,0,O2,P2], [hld1,1,O1,1,O2,P2], right).

物体２

物体１

座標

0

1

2

物体２

物体１

座標

0

1

2

座標０で物体１をつかんだ状態から座標１で物体１をつかんだ状態に移るためには
手を右に動かせばよい。

23

サブルーチンを呼び出すルールの例
sgam([open,P0,O1,P1,O2,P2], [open,P2,O1,P2,O2,P2], g([open,P1,O1,P1,O2,P2)]

座標

0

物体１

物体２

1

2

座標

0

1

2

座標

0

1

2

物体１を座標２に移動するためには、
まず手を座標１に移動させればよい。
24

プリミティブ行動を実行するルール
基本的な手の動かし方のルール。
他のプログラムから基本ライブラリのように利用される。
m([open,P1,O1,P1,O2,P2], [hld1,P1,O1,P1,O2,P2], hold1).
m([open,P2,O1,P1,O2,P2], [hld2,P2,O1,P1,O2,P2], hold2).
m([hld1,P1,O1,P1,O2,P2], [open,P1,O1,P1,O2,P2], release).
m([hld2,P2,O1,P1,O2,P2], [open,P2,O1,P1,O2,P2], release).
m([open,0,O1,P1,O2,P2], [open,1,O1,P1,O2,P2], right).
m([open,0,O1,P1,O2,P2], [open,2,O1,P1,O2,P2], right).
m([open,1,O1,P1,O2,P2], [open,0,O1,P1,O2,P2], left).
m([open,1,O1,P1,O2,P2], [open,2,O1,P1,O2,P2], right).
m([open,2,O1,P1,O2,P2], [open,1,O1,P1,O2,P2], left).
m([open,2,O1,P1,O2,P2], [open,0,O1,P1,O2,P2], left).
m([hld1,0,O1,0,O2,P2], [hld1,1,O1,1,O2,P2], right).
m([hld1,0,O1,0,O2,P2], [hld1,2,O1,2,O2,P2], right).
m([hld1,1,O1,1,O2,P2], [hld1,0,O1,0,O2,P2], left).
m([hld1,1,O1,1,O2,P2], [hld1,2,O1,2,O2,P2], right).
m([hld1,2,O1,2,O2,P2], [hld1,1,O1,1,O2,P2], left).
m([hld1,2,O1,2,O2,P2], [hld1,0,O1,0,O2,P2], left).
m([hld2,0,O1,P1,O2,0], [hld2,1,O1,P1,O2,1], right).
m([hld2,0,O1,P1,O2,0], [hld2,2,O1,P1,O2,2], right).
m([hld2,1,O1,P1,O2,1], [hld2,0,O1,P1,O2,0], left).
m([hld2,1,O1,P1,O2,1], [hld2,2,O1,P1,O2,2], right).
m([hld2,2,O1,P1,O2,2], [hld2,1,O1,P1,O2,1], left).
m([hld2,2,O1,P1,O2,2], [hld2,0,O1,P1,O2,0], left).

ルールの書き方：s から g に a を経由して到達可能であれば
m(s,g,a).
と書く。
今回は価値は省略。
大文字で始まる識別子は変数、小文字で始まる識別子や数値は定数

25

タスク１
物体１を、物体２がある場所に移動するタスク

タスク１を解くプログラム：

物体１

物体２

r

c

座標 0

1

2

% 1. 手を P1 に移動する。
m([open,P0,O1,P1,O2,P2], [open,P2,O1,P2,O2,P2], g([open,P1,O1,P1,O2,P2])).
% 2. O1 をつかむ。
m([open,P1,O1,P1,O2,P2], [open,P2,O1,P2,O2,P2], g([hld1,P1,O1,P1,O2,P2])).
% 3. 手を P2 に移動する。
m([hld1,P1,O1,P1,O2,P2], [open,P2,O1,P2,O2,P2], g([hld1,P2,O1,P2,O2,P2])).
% 4. 手をはなす。
% 定義不要。

g([...]) という行動は、サブルーチン呼び出し

26

実行結果
物体１を座標 0 から 2 に移動する。

実行結果（各ステップにおける (s, g, a) の組）：

物体１

物体２

r

c

座標 0

1

2

?- episode([open,1,r,0,c,2], [open,2,r,2,c,2],Log), printList(Log).
[[open,1,r,0,c,2],[open,2,r,2,c,2],g([open,0,r,0,c,2])][[open,1,r,0,c,2],[open,0,r,0,c,2],left][[open,0,r,0,c,2],[open,0,r,0,c,2],ret][[open,0,r,0,c,2],[open,2,r,2,c,2],g([hld1,0,r,0,c,2])][[open,0,r,0,c,2],[hld1,0,r,0,c,2],hold1][[hld1,0,r,0,c,2],[hld1,0,r,0,c,2],ret][[hld1,0,r,0,c,2],[open,2,r,2,c,2],g([hld1,2,r,2,c,2])][[hld1,0,r,0,c,2],[hld1,2,r,2,c,2],right][[hld1,1,r,1,c,2],[hld1,2,r,2,c,2],right][[hld1,2,r,2,c,2],[hld1,2,r,2,c,2],ret][[hld1,2,r,2,c,2],[open,2,r,2,c,2],release][[open,2,r,2,c,2],[open,2,r,2,c,2],ret]

27

タスク２
• ２つの物体を同じ場所に移動する。どちらを先に移動してもよい。

座標

0

物体１

物体２

1

2
28

タスク２を解くプログラム

物体１ 物体２

座標

0

1

2

% 物体 O1 を場所 P0 に移動する。
m([open,P0,O1,P1,O2,P2], [open,P0,O1,P0,O2,P0], g([open,P0,O1,P0,O2,P2])).
% 物体 O2 を場所 P0 に移動する。
m([open,P0,O1,P1,O2,P2], [open,P0,O1,P0,O2,P0], g([open,P0,O1,P1,O2,P0])).
% 物体 O1 を場所 P0 に移動するサブルーチン。
m([open,P0,O1,P1,O2,P2], [open,P0,O1,P0,O2,P2], g([open,P1,O1,P1,O2,P2])).
m([open,P1,O1,P1,O2,P2], [open,P0,O1,P0,O2,P2], g([hld1,P1,O1,P1,O2,P2])).
m([hld1,P1,O1,P1,O2,P2], [open,P0,O1,P0,O2,P2], g([hld1,P0,O1,P0,O2,P2])).
% 物体 O2 を場所 P0 に移動するサブルーチン。
m([open,P0,O1,P1,O2,P2],[open,P0,O1,P1,O2,P0], g([open,P2,O1,P1,O2,P2])).
m([open,P2,O1,P1,O2,P2],[open,P0,O1,P1,O2,P0], g([hld2,P2,O1,P1,O2,P2])).
m([hld2,P2,O1,P1,O2,P2],[open,P0,O1,P1,O2,P0], g([hld2,P0,O1,P1,O2,P0])).
サブルーチン呼び出しがネストし、スタックが必要になる例
29

実行結果

物体１ 物体２?- episode([open,0,r,1,c,2],[open,0,r,0,c,0],Log), printList(Log).
01

解１：物体１、物体２の順に移動

解２：物体２、物体１の順に移動[[open,0,r,1,c,2],[open,0,r,0,c,0],g([open,0,r,0,c,2])][[open,0,r,1,c,2],[open,0,r,0,c,2],g([open,1,r,1,c,2])][[open,0,r,1,c,2],[open,1,r,1,c,2],right][[open,1,r,1,c,2],[open,1,r,1,c,2],ret][[open,1,r,1,c,2],[open,0,r,0,c,2],g([hld1,1,r,1,c,2])][[open,1,r,1,c,2],[hld1,1,r,1,c,2],hold1][[hld1,1,r,1,c,2],[hld1,1,r,1,c,2],ret][[hld1,1,r,1,c,2],[open,0,r,0,c,2],g([hld1,0,r,0,c,2])][[hld1,1,r,1,c,2],[hld1,0,r,0,c,2],left][[hld1,0,r,0,c,2],[hld1,0,r,0,c,2],ret][[hld1,0,r,0,c,2],[open,0,r,0,c,2],release][[open,0,r,0,c,2],[open,0,r,0,c,2],ret][[open,0,r,0,c,2],[open,0,r,0,c,0],g([open,2,r,0,c,2])][[open,0,r,0,c,2],[open,2,r,0,c,2],right][[open,1,r,0,c,2],[open,2,r,0,c,2],right][[open,2,r,0,c,2],[open,2,r,0,c,2],ret][[open,2,r,0,c,2],[open,0,r,0,c,0],g([hld2,2,r,0,c,2])][[open,2,r,0,c,2],[hld2,2,r,0,c,2],hold2][[hld2,2,r,0,c,2],[hld2,2,r,0,c,2],ret][[hld2,2,r,0,c,2],[open,0,r,0,c,0],g([hld2,0,r,0,c,0])][[hld2,2,r,0,c,2],[hld2,0,r,0,c,0],left][[hld2,1,r,0,c,1],[hld2,0,r,0,c,0],left][[hld2,0,r,0,c,0],[hld2,0,r,0,c,0],ret][[hld2,0,r,0,c,0],[open,0,r,0,c,0],release][[open,0,r,0,c,0],[open,0,r,0,c,0],ret][[open,0,r,1,c,2],[open,0,r,0,c,0],g([open,0,r,1,c,0])][[open,0,r,1,c,2],[open,0,r,1,c,0],g([open,2,r,1,c,2])][[open,0,r,1,c,2],[open,2,r,1,c,2],right][[open,1,r,1,c,2],[open,2,r,1,c,2],right][[open,2,r,1,c,2],[open,2,r,1,c,2],ret][[open,2,r,1,c,2],[open,0,r,1,c,0],g([hld2,2,r,1,c,2])][[open,2,r,1,c,2],[hld2,2,r,1,c,2],hold2][[hld2,2,r,1,c,2],[hld2,2,r,1,c,2],ret][[hld2,2,r,1,c,2],[open,0,r,1,c,0],g([hld2,0,r,1,c,0])][[hld2,2,r,1,c,2],[hld2,0,r,1,c,0],left][[hld2,1,r,1,c,1],[hld2,0,r,1,c,0],left][[hld2,0,r,1,c,0],[hld2,0,r,1,c,0],ret][[hld2,0,r,1,c,0],[open,0,r,1,c,0],release][[open,0,r,1,c,0],[open,0,r,1,c,0],ret][[open,0,r,1,c,0],[open,0,r,0,c,0],g([open,1,r,1,c,0])][[open,0,r,1,c,0],[open,1,r,1,c,0],right][[open,1,r,1,c,0],[open,1,r,1,c,0],ret][[open,1,r,1,c,0],[open,0,r,0,c,0],g([hld1,1,r,1,c,0])][[open,1,r,1,c,0],[hld1,1,r,1,c,0],hold1][[hld1,1,r,1,c,0],[hld1,1,r,1,c,0],ret][[hld1,1,r,1,c,0],[open,0,r,0,c,0],g([hld1,0,r,0,c,0])][[hld1,1,r,1,c,0],[hld1,0,r,0,c,0],left][[hld1,0,r,0,c,0],[hld1,0,r,0,c,0],ret][[hld1,0,r,0,c,0],[open,0,r,0,c,0],release][[open,0,r,0,c,0],[open,0,r,0,c,0],ret]

230

どのくらい圧縮されたのか？
• 下記パターン１つで O1,O2,P2 のすべての値の組み合わせ 2 x 2 x 3 = 12 通りを表現。
m([hld1,0,O1,0,O2,P2], [hld1,1,O1,1,O2,P2], right).

• タスク１、タスク２を解くプログラムはどちらも
P0,P1,P2,O1,O2 のすべての値の組み合わせ
3 x 3 x 3 x 2 x 2 = 108 通りの状況で動くように書かれており、汎用性がある。
手の状態： H∈ {open, hld1, hld2}
物体１、物体２の形： O1,O2∈ {r, c}
手、物体の座標： P0,P1,P2∈ {0,1,2}
環境の状態 = (H, P0, O1, P1, O2, P2)

31精度の低下について• プリミティブ行動のルールに関しては、精度の低下はない。
• タスク１、タスク２を解くプログラムでは移動元と移動先が抽象化されており、実際の移動距
離は実行ごとに異なるため、学習される値はその平均となり、精度は落ちる。
– 学習速度と精度のトレードオフ。

32

プログラミング言語としての課題• 再利用性のためにスタックが必要だった。
• さらに再利用性（汎化性能）を上げるために必要な言語機能：– ワーキングメモリへの読み書き– インデックスレジスタ、高階関数（関数ポインタ）– メタプログラミング– データ抽象– サブルーチンの終了条件
33

まとめ• 単一化を用いた行動価値関数のテーブル圧縮手法を提案– 脳での実現方法の１つの案を提示– 「記述実験」により圧縮効果を予備的評価– RGoal をプログラミング合成システムと見なし、その特徴について考察• 今後：– RGoal アーキテクチャをさらに拡張し、説得力のあるデモを動かす。
34