post Image
ゆるふわ強化学習1

はじめに

強化学習について日本語で説明したゆるふわ入門があればいいなと思ったので書きます。ちょっと冗長だったので、簡潔にしました。

重要な注意点として、今回の記事では、環境のモデル(MDPの全ての要素)が分かっている場合を扱います。後に環境のモデルが不明な場合を扱いますが、そのための数学的なバックグラウンドとなるものが今回の記事で扱われます。

強化学習とは

強化学習が何かについては、たくさんの人がゆるふわな紹介を行っているので、飛ばします。代わりに、数学的な定義を説明します。

マルコフ決定過程(MDP)

強化学習において、環境の定義が必要となる。この環境の定義には、通常、マルコフ決定過程またはMarkov(ian?) Decision Process(MDP)を用いる。

MDPは5-tuple $(\mathcal{S}, \mathcal{A}, p, r, \gamma)$によって定まる。ここで、$\mathcal{S}$ は状態空間と呼ばれる有限集合、$\mathcal{A}$ は行動空間と呼ばれる有限集合、 $p:\mathcal{S} \times \mathcal{A} \rightarrow \mathcal{M}(\mathcal{S})$は遷移確率、$r:\mathcal{S} \times \mathcal{A} \times \mathcal{S} \rightarrow \mathbb{R}$は報酬関数、そして$\gamma \in [0,1)$は割引率である。ただし$\mathcal{M}(\mathcal{S})$は$\mathcal{S}$上の全ての確率分布の集合である。つまり、入力$s \in \mathcal{S}$と$a \in \mathcal{A}$に対して$p(\cdot|s,a)$という確率分布を出力するような写像となる。これらは、次のように理解する。エージェントが状態$s$にいる。そこで行動$a$を行った。すると、$s’$に確立$p(s’|s,a)$で遷移する。この遷移にともない、$r(s,a,s’)$の報酬が貰える。

いくつか注意点を述べる。$\mathcal{S}$と$\mathcal{A}$については、有限個の要素数だとする方が数学的に楽なので、そうすることが多い。連続値にすると測度がうんぬんとかめんどくさいことになるが、大体の理論については連続にしても良い。例外として、方策反復は連続の行動空間に適用できない。また重要な事として、$p(s’|s,a)$は過去の履歴に依存しない。つまり、現在の状況と行動さえ与えられれば、次時刻の確率分布は完全に決定されることを仮定する。これがマルコフ性と呼ばれる性質であり、マルコフ決定過程という呼び名の由来である。$r(s,a,s’)$ は確率変数にも出来るが、理論はほぼ変わらないので確率変数としては扱わない。もちろん、報酬もマルコフ性を満たさなければならない。

価値関数

価値関数は状態の価値や行動の価値を測る関数である。これらは、次のように考えると分かりやすい。戦略ゲームをしている時、盤面の状況をぱっと見ると、勝てるか負けるかの判断がつくと思う。つまり、盤面という状況に対して、その盤面の価値が分かる。これが状態価値関数である。また、自分の行動によってその盤面は変わる。つまり、行動自体も価値を持つ。これが行動価値関数である。ここで重要なのが、盤面の状況に対して、ここから勝てるか負けるかというのは本人の手腕による。つまり、自分の行動方法に依存している点だ。

もう少し詳しく述べよう。エージェントは、方策(行動の確率分布である)$\pi(a|s)$に従って行動を選んでおり、エージェントの目的は、次のような関数を任意の状態に対して最大とする方策を見つけ出すことである。

v^\pi(s) = \mathbb{E}^\pi \left[ \sum_{t=0}^\infty \gamma^t r(s_t,a_t,s_{t+1}) | s_0=s \right].

ただしこの期待値は、 $s$ から行動を開始して方策 $\pi$ で行動を選んでいった時の期待値という意味である(和は無限大の時刻まで行っているが、実際応用では有限で止めて良い)。分かりにくいなら、次のように考えるといい。今、エージェントを $s$ に何度も置けるとしよう。この時、エージェントを方策に従って行動させるという事を繰り返す。この時、報酬の和が何度も得られる。これらを平均した値が上記の期待値だ。ただし、得られた時刻に従って報酬が割引されている。上記の $v$ 関数が状態価値関数である。

一方、行動価値関数 $q$ は

q^\pi(s,a) = \mathbb{E}^\pi \left[ \sum_{t=0}^\infty \gamma^t r(s_t,a_t,s_{t+1}) | s_0=s, a_0=a \right].

ただしこの期待値は、$s$において、行動$a$を行い、そこから方策$\pi$で行動を選んでいった時の期待値という意味である。つまり価値関数たちは$v^\pi(s) = \sum_a \pi(a|s) q^\pi(s, a)$で結ばれる。

ここで疑問になるのが、最適な行動は現在の状態のみから定まるのか?ということだ。つまり、方策を$\pi(a_t|s_0,a_0,\cdots,s_t)$という過去の履歴すべてに依存するものから選ばなくてもいいのかということだ。これについては、この本の最初の方に証明されているように、状態遷移が過去の履歴に依存しないなら、現在の状態に依存した方策の集団に最適方策が含まれる事が証明される。つまり、過去より未来を見て生きていけばいい。そして、ここに書いてあることは上記の本に大体書いてある。またさらに、最適方策が決定的な関数、つまり$\pi: \mathcal{S} \rightarrow \mathcal{A}$に含まれていることも証明できる(POMDPの時にはダメ)。よって実は方策は、時間に依存しない決定的関数としてもよい。だが方策が確率分布だとしたほうが一般的なので、方策は確率分布としておこう。

方策改善定理

状態価値関数を用いて、方策に順番を定めることが出来る。つまり、ある$\pi$と$\pi’$が次の条件を満たす時、$\pi$は$\pi’$よりも良いとされる: 任意の状態$s$について$v^\pi(s) \geq v^{\pi’}(s)$。正確に言うと、$\pi$は$\pi’$よりも悪くないだが、そこは数学的なノリで無視する。もしも厳密に良いと言った場合には、先の条件に加え、次の条件を要求する: ある状態$s$が存在して$v^\pi(s) \geq v^{\pi’}(s)$。

では、どのようにしてより良い方策を見つけるのか?それには、グリーディー(greedy)方策が重要な役割を果たす。(最近はグリーディー方策ではなく、コンサバティブ方策を用いたアルゴリズムが人気だが、それについては、いずれ説明しよう。)ある方策に対する行動価値関数 $q^\pi$ を考えよう。グリーディー方策とは、$\pi'(a|s) = 1 \iff a=\text{arg}~\max_b q^\pi(s,b)$となる方策の事である。より正確には $q^\pi$ に対するグリーディー方策と呼ぶ。このグリーディー方策が確かによりよい方策であるかは、ベルマン方程式を先に紹介しなければならないが、ここに記しておく。ベルマン方程式を学んでから読んでも良いが、簡単なので、価値関数の復習がてら証明を追うのも良い。

v^\pi(s) = \sum_{a_0} \pi(a_0|s_0=s) q^\pi(s, a_0) \leq \sum_{a_0} \pi'(a_0|s_0=s) q^\pi(s, a_0).

ここで $q^\pi(s,a_0) = \sum_{s_1} p(s_1|s_0=s, a_0=a_0) \left[ r(s, a_0, s_1) + \gamma v^\pi(s_1) \right]$ なので

v^\pi(s) \leq \sum_{a_0} \sum_{s_1} p(s_1|s_0=s, a_0=a_0) \pi'(a_0|s_0=s) \left[ r(s, a_0, s_1) + \gamma \sum_{a_1} \pi'(a_1|s_1) q^\pi(s_1, a_1) \right].

これを続けていけば、$v^\pi(s) \leq \mathbb{E}^{\pi’} \left[ \sum_{t=0}^\infty \gamma^t r(s_t,a_t,s_{t+1}) | s_0=s \right] = v^{\pi’}(s)$が得られる。つまり、$\pi’$は$\pi$より良い方策となる。

ベルマン方程式(Bellman Equation)

では、どのようにして価値関数を学習するのか?もっとも単純な方法は、実際に $\sum_{t=0}^\infty \gamma^t r(s_t,a_t,s_{t+1})$ を何度もサンプルして平均を計算する事だ。これはモンテカルロ法と呼ばれる。もちろん真の値に収束するが、問題としては、 $\sum_{t=0}^\infty \gamma^t r(s_t,a_t,s_{t+1})$ の分散が大きく、収束が遅い(と言われている)。以下では、ベルマン方程式を用いる方法を説明しよう。実際の応用では、行動価値関数の学習を行うことが多い。なぜならグリーディー方策で方策の改善を行いたいからだ。そのため、主に行動価値関数の学習について説明する。

行動価値関数の学習には、ベルマン方程式を用いる方法がよく使われる。ベルマン方程式は次の等式だ。

q^\pi(s, a) = r(s, a) + \gamma \sum_{s'} p(s'|s, a) v^\pi(s')

ただし、 $r(s, a) = \sum_{s’} p(s’|s,a) r(s, a, s’)$。状態価値関数の学習は、行動価値関数の学習とほぼ変わらないので、行動価値関数の学習について以下では述べる。

議論を簡潔にするため、次の列ベクトル $\mathbf{q}^\pi = (q(s_1, a_1), \cdots, q(s_{N_\mathcal{S}}, a_1), q(s_1, a_2), \cdots q(s_{N_\mathcal{S}}, a_{N_\mathcal{A}}))^T$ が使われることが多い。簡単に言うと、このベクトルは、各状態-行動対に対する行動価値関数を要素とする列ベクトルである。(しかしながら、適切なヒルベルト空間を考えると以下の議論はほぼ同様に成り立つ。つまり、価値関数をヒルベルト空間の要素と考える。)また、行列$\mathbf{P}^\pi$を

\mathbf{P}^\pi \mathbf{q}^\pi = (\sum_{s'} p(s'|s_1,a_1) v^\pi(s'), \cdots, \sum_{s'}  p(s'|s_{N_\mathcal{S}},a_{N_\mathcal{A}}) v^\pi(s'))^T

となる行列とする。ただし、状態-行動対の順番は元のベクトルと同様とする。この$\mathbf{P}^\pi$は確率行列となる。上記の式は、$s_i$において行動$a_j$をとった時の次時刻での状態価値関数の期待値である。これを用いると、ベルマン方程式は簡潔に

\mathbf{q}^\pi = \mathbf{r} + \gamma \mathbf{P}^\pi \mathbf{q}^\pi

となる。ただし、$\mathbf{r}$は$r(s, a)$を要素とする$\mathbf{q}^\pi$と同様の順番のベクトル。

ベルマン作用素

研究者はめんどくさがりなので、ベルマン方程式をさらに簡潔にするため

\mathbf{q}^\pi = \mathbf{T}^\pi \mathbf{q}^\pi

と書く。つまり $\mathbf{T}^\pi$ はベクトルに $\gamma \mathbf{P}^\pi$ をかけて、 $\mathbf{r}$ を足すような演算である。これはベルマン作用素と呼ばれる。これをベクトルに左からかける事を作用させるという。

次に、グリーディー方策という考え方を用いてベルマン最適作用素 $\mathbf{T}$ を定義しよう。ベルマン最適作用素とは、任意の $\mathbf{q}$ に対し

\left( \mathbf{T} \mathbf{q} \right) (s, a) = r(s,a) + \gamma \sum_{s'} p(s'|s,a) \max_a q(s', a')

となる作用素として定義される。つまり、 $\mathbf{q}$ に対するgreedy方策を $\pi$ とすると、

\mathbf{T} \mathbf{q} = \mathbf{T}^\pi \mathbf{q} = r(s,a) + \gamma \sum_{s'} p(s'|s,a) q(s', \text{arg}~\max_a q(s', a))

となる。ここで気づいて欲しいのは、$\mathbf{q}$ に依存して $\mathbf{T}$ が定義されることである。つまり、任意の $\mathbf{q}$ に対して、ある方策 $\pi$ が存在して $\mathbf{T} \mathbf{q} = \mathbf{T}^{\pi} \mathbf{q}$ となるのだが、その他の $\mathbf{q}’$ に対して $\mathbf{T}$ を作用させるときには、 $\mathbf{T}$ は $\mathbf{q}’$ に対して定義されるため $\mathbf{T} \mathbf{q}’ = \mathbf{T}^\pi \mathbf{q}’$ とは限らない。また、そのために、 $\mathbf{q}$ に対してベルマン最適作用素を二度作用させる場合にも注意が必要となる。つまり $\left( \mathbf{T} \right)^2 \mathbf{q} = \left( \mathbf{T}^{\pi} \right)^2 \mathbf{q}$ とは限らない。もしも、 $\mathbf{T} \mathbf{q} = \mathbf{q}$ ならば $\left( \mathbf{T} \right)^2 \mathbf{q} = \mathbf{T} \mathbf{q} = \mathbf{q}$ となって成立するが。

価値関数の一意性とベルマン誤差に関する定理

とても直感的なアイデアとして次の事が考えられる。適当なベクトル $\mathbf{q}$ を選ぶ。このとき、真の状態価値関数はベルマン方程式を満たすので、 $\mathbf{q}$ をベルマン方程式が満たされるように変更すれば真の状態価値関数になるのではないか。実は、この直感は正しい。これは以下のようにして確かめられる。真の行動価値関数 $\mathbf{q}^\pi$ の他に $\mathbf{q}$ がベルマン方程式を満たすとしよう。このとき

\begin{align}
\mathbf{q}^\pi - \mathbf{q} &= \mathbf{T}^\pi \mathbf{q}^\pi - \mathbf{T}^\pi \mathbf{q}\\
&= \gamma \mathbf{P}^\pi \left( \mathbf{q}^\pi - \mathbf{q} \right)\\
&= \gamma^n \left( \mathbf{P}^\pi \right)^n \left( \mathbf{q}^\pi - \mathbf{q} \right)
\end{align}

となる。ただし $n$ は任意の整数。ここで、右辺のベクトルの要素のうち、最大の絶対値を見てみよう。これはノルムとなり

\left\| \mathbf{u} \right\|_\infty = \max_i | u_i |

と記述される。じつは、$\mathbf{P}^\pi$ はベクトルを長くできない事が知られている(この事実はすごく頻繁に使われる)。つまり、任意のベクトルに対して

\| \mathbf{P}^\pi \mathbf{q} \|_{\infty} \leq \| \mathbf{q} \|_{\infty}

となる。これは、

\| \mathbf{q}^\pi - \mathbf{q} \|_{\infty} \leq \gamma^n \| \mathbf{q}^\pi - \mathbf{q} \|_{\infty}

を意味するが、これを満たすには

\| \mathbf{q}^\pi - \mathbf{q} \|_\infty=0

でなければならない。つまり、ベルマン方程式を満たすベクトルは一意で、真の状態価値関数となる。

実は、もっと嬉しい定理も存在する。それは、WilliamsとBairdによって示された次の定理である。

\| \mathbf{q}^\pi - \mathbf{q} \|_\infty \leq \frac{1}{1-\gamma} \| \mathbf{T}^\pi \mathbf{q} - \mathbf{q} \|_\infty

つまり、ベルマン方程式との誤差により、真の行動価値関数との差が上から抑えられる。この右辺をベルマン誤差と呼ぶ。ところで、各状態毎の二乗誤差をその状態の出現確率で重み付けしたノルムについて上記のような定理があるともっと嬉しいが、実は、そのような定理も存在する(この論文内では証明は書かれていないが、実際に成立する)。また、重要な点として、 $\mathbf{q}^\pi$ は方策 $\pi$ に従った時の真の状態価値関数であり、求めたいものなのだから観測できない。それが左辺にのみ現れている。そして右辺には、$\mathbf{q}$のみが現れている。つまり、右辺は観測できる。

WilliamsとBairdの定理は簡単であるが、後の式変形でも重要なテクニックが使われているので、丁寧に証明しておこう。

\begin{align}
\| \mathbf{q}^\pi - \mathbf{q} \|_\infty
&= \| \mathbf{q}^\pi - \mathbf{T}^\pi \mathbf{q} + \mathbf{T}^\pi \mathbf{q} - \mathbf{q} \|_\infty\\
&\leq \| \mathbf{q}^\pi - \mathbf{T}^\pi \mathbf{q} \|_\infty + \| \mathbf{T}^\pi \mathbf{q} - \mathbf{q} \|_\infty\\
&= \| \mathbf{T}^\pi \mathbf{q}^\pi - \mathbf{T}^\pi \mathbf{q} \|_\infty + \| \mathbf{T}^\pi \mathbf{q} - \mathbf{q} \|_\infty\\
&= \gamma \| \mathbf{P}^\pi \left( \mathbf{q}^\pi - \mathbf{q} \right) \|_\infty + \| \mathbf{T}^\pi \mathbf{q} - \mathbf{q} \|_\infty\\
&\leq \gamma \| \mathbf{q}^\pi - \mathbf{q} \|_\infty + \| \mathbf{T}^\pi \mathbf{q} - \mathbf{q} \|_\infty
\end{align}

となり、あとは整理すれば定理が得られる。

ベルマン作用素の性質

このベルマン最適作用素については、 $\mathbf{T} \mathbf{q} = \mathbf{q}$ となる $\mathbf{q}$ があれば、それが最適方策の行動価値関数であることが知られている。それを見るには、まず、ベルマン作用素の単調性について知らなければならない。つまり、任意の方策 $\pi$ に対して

\forall \mathbf{q}_1, \mathbf{q}_2, \left[ \mathbf{q}_1 \leq \mathbf{q}_2 \Rightarrow \mathbf{T}^\pi \mathbf{q}_1 \leq \mathbf{T}^\pi \mathbf{q}_2 \right]

となる($\mathbf{q}_1 \leq \mathbf{q}_2 $は、ベクトルの任意の要素に対して$\leq$が成立することを意味する)。これは、元の定義をよく見ればすぐに分かる。証明は省くが $\mathbf{T}$ に対しても成立する。

次に、ベルマン作用素の固定点について説明する。 $\mathbf{q}^\pi$ がベルマン方程式を満たす、つまり、 $\mathbf{T}^\pi \mathbf{q}^\pi = \mathbf{q}^\pi$ としよう。すると、任意のベクトル $\mathbf{q}$ に対して

\begin{align}
\| \mathbf{q}^\pi - \mathbf{T}^\pi \mathbf{q} \|_\infty
&= \| \mathbf{T}^\pi \mathbf{q}^\pi - \mathbf{T}^\pi \mathbf{q} \|_\infty\\
&= \gamma \| \mathbf{P}^\pi \left( \mathbf{q}^\pi - \mathbf{q} \right) \|_\infty\\
&\leq \gamma \| \mathbf{q}^\pi - \mathbf{q} \|_\infty
\end{align}

これが意味するのは、 $\mathbf{T}^\pi \mathbf{q}$ は $\mathbf{q}$ よりも $\mathbf{q}^\pi$ に近いということだ。この議論を繰り返すと分かるように、

\lim_{n \rightarrow \infty} \left( \mathbf{T}^\pi \right)^n \mathbf{q} = \mathbf{q}^\pi

となる。証明は省くが、 $\mathbf{T}$ についても同様な事が言える。ただし、$q^\pi$ではなく、他の固定点が存在する。

これらを踏まえ、 $\mathbf{T} \mathbf{q} = \mathbf{q}$ となる $\mathbf{q}$ があれば、それが最適方策の行動価値関数であることを証明しよう。まず

\mathbf{T}^\pi \mathbf{q} \leq \mathbf{T} \mathbf{q} = \mathbf{q}

が成立することに気づいて欲しい。この不等式の両辺に $\mathbf{T}^\pi$ を作用させると $\left( \mathbf{T}^\pi \right)^n \mathbf{q} \leq \mathbf{q}$ が任意の $n$ に対して成ることが分かり、$\lim_{n \rightarrow \infty} \left( \mathbf{T}^\pi \right)^n \mathbf{q} = \mathbf{q}^\pi \leq \mathbf{q}$ となるので、 $\mathbf{q}$ が任意の方策の行動価値関数よりも悪くないことが分かる。

このとき、$\mathbf{q}$にグリーディーな方策$\pi’$を考える。すると、

\mathbf{q} \leq \mathbf{T} \mathbf{q} \leq \mathbf{T}^{\pi'} \mathbf{q}.

先ほどと同様の議論で、$\mathbf{q} \leq \mathbf{q}^{\pi’}$が得られる。これは、$\mathbf{q} = \mathbf{q}^{\pi’}$を意味し、$\pi’$が最適方策かつ$\mathbf{q}$の行動価値を持つことを示している。多くの文献で、最適方策を$\pi^{*}$と書き、その価値関数を$v^{*}$と書く$q^{*}$と書く。

ダイナミックプログラミング

最適方策を見出すためのアイデアとして、方策反復(Policy iteration)と呼ばれる手法がある。今、方策 $\pi_k$ を用いて $q^{\pi_k}$ を求めたとしよう。このとき、任意の $s,a$ に対して $q^{\pi_{k+1}}(s,a) \geq q^{\pi_k}(s,a)$ となる方策が見つかったとすると、明らかに $\pi_{k+1}$ を使ったほうがいい。では、これを改善がなくなるまで繰り返せば最適方策が見つかるのではないか、というのが方策反復(Policy iteration)と呼ばれるものである。つまり方策反復では、ある方策 $\pi_0$ から始め、

\mathbf{q}^1 = \lim_{n \rightarrow \infty} \left( \mathbf{T}^{\pi_0} \right)^n \mathbf{q}^{\pi_0}

を求める。そして、 $\mathbf{q}^1 $に対してグリーディーな方策 $\pi_1$ に方策を更新し

\mathbf{q}^2 = \lim_{n \rightarrow \infty} \left( \mathbf{T}^{\pi_1} \right)^n \mathbf{q}^{1}

を求める。そして、上記を繰り返す。

では、方策反復の収束を証明しよう。まず、$\mathbf{T}^{\pi_{k+1}} \mathbf{q}^{\pi_{k}} \geq \mathbf{q}^{\pi_k}$ なのは定義から明らか。次に不等号の両辺に $\mathbf{T}^{\pi_{k+1}}$ を作用させ、単調性を用いると、

\mathbf{q}^{\pi_k} \leq \lim_{n \rightarrow \infty} \left( \mathbf{T}^{\pi_{k+1}} \right)^n \mathbf{q}^{\pi_k} = \mathbf{q}^{\pi_{k+1}} \leq \frac{1}{1-\gamma} \max_{s,a,s'} r(s,a,s')

となる。今、有限個の行動と状態しかないので、方策の組み合わせも有限である。つまり、あるところで改善が止まる。しかし、改善が止まったということは、その時の行動価値関数 $\mathbf{q}$ に対して $\mathbf{T} \mathbf{q} = \mathbf{q}$ となる。これは、 $\mathbf{q}$ が最適方策に対する行動価値関数という事を示している。なので、その行動価値関数に対してグリーディーな方策が最適方策である。

ここでキモとなのが、 $\mathbf{T}$ を作用させても変わらない関数に収束していることである。では、そもそも $\mathbf{T}$ だけを使えばよいのではないかというのはもっともだ。その方法を価値反復と呼ぶ。つまり、ある行動価値関数 $\mathbf{q}$ から始め

\mathbf{q}^* = \lim_{n \rightarrow \infty} \left( \mathbf{T} \right)^n \mathbf{q}

を求め、 $\mathbf{q}^{*}$ に対するグリーディー方策を求める。


『 機械学習 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。