2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
微分は傾き(全1記事)
リンクをコピー
記事をブックマーク
安原祐二氏:Unityの安原です。今回は「微分」についてお話ししていきたいと思います。
微分、どうですか? なんか難しそうだなと思うかもしれません。でもちょっとかっこいいなとも思うかもしれません。今回は、まず微分の数学的なところを簡単に説明をしてから、プログラムでどう使うのかを話していきたいと思います。
ではまず、微分の説明からいってみましょう。こんなグラフがあったとしましょう。これはy=f(x)というグラフです。ある点に注目してみましょう。(スライドを示して)ここが例えば4だったとすると、ここはf(4)になりますよね。これは難しくないと思うんですが、この点の傾きに注目するのが微分です。傾きをちょっと考えてみましょう。
傾きと聞いて角度で表すのかなと思ったら、それは間違いです。傾きはこういう角度では表さないんですね。
ではどうやって表すか。a/bで表すのが傾きになります。今の場合、傾きの線が右に上がっていますよね。この場合、a/bはプラスになります。0より大きい。右に下がっている場合は、a/bはマイナスの値を取ることになります。水平だったら傾きは0です。この3パターンを理解するのはとても大事です。
こういうふうに垂直になっているのは数学では考えません。aが0になっているので、これだと0で割っていることになります。これは数学では考えないんですね。
というわけでこの傾き、a/bをどうやって出そうかな。これはなかなかわからない。どうしたらいいのかわからない。こんな時にはやり方があります。ちょっと離れた点を考えます。4を止めてxにしましょう。この点をx+h。hだけズラすわけですね。するとここはf(x+h)になります。
まだこの黄色の傾きはわかりませんが、この2点を通る傾きならわかるじゃないですか。だって、これ分のこれですからね。
じゃあ「これ分のこれ」を計算してみましょう。ここはhなので、これ引くこれ(※f(x+h)−f(x)/h)。とりあえずはこれがこの白い線の傾きになります。
この時にこのhをグーッと小さくしていって、すごく小さければこの黄色い線と同じになるでしょうというのが微分の考え方になるわけです。
ここで新しい記号を数学的には導入しました。hが0に行くよ。limと言うんですが、この記号を使って表現された式が、この傾きということになるわけです。
まだピンと来ないかもしれません。ちょっと具体的な例で考えてみましょう。f(x)=x^2(※xの2乗)というシンプルな関数で考えた時にこれを計算してみましょう。
はい、こうなります。分母にhがある時に、0に上っていく計算はなかなかできませんが、計算していくと分母のほうのhが消えていくんですね。このhは0に持って行けるので、答えは2xになります。
例えばf(x)=x^2(※xの2乗)の関数のxが4の時の傾きは8。f(x)=x^2(※xの2乗)の関数のxが20の時の傾きは40という感じになるわけです。
ここで書き方があります。'(ダッシュ)を付けるんです。プライムと言うのですがf'(x)、これはxを微分するとも言って、導関数という言い方をします。つまり、f(x)=x^2(※xの2乗)の導関数は2x。微分すると2xという言い方もできます。
どんな関数もこのやり方をすれば導関数は出ます。いろいろあるので見てみましょう。x^2(※xの2乗)は2xでした。微分すると2xになるんだよという話。これを導関数と呼びました。x^3(※xの3乗)は3x^2(※3xの2乗)になるんですよね。実はこれには法則性があって、x^n(※xのn乗)だったらそのnを前に持ってきて、次数を1つ下げるんですね。3乗だったら2乗、2乗だったら1乗。
では123みたいな定数だったらどうなるのか。どのxのポイントも123だから、これはグラフでいうと水平線になります。これは常に傾きが0だから、微分すると0になります。xは、45度の傾きの線ですね。どの点を取っても傾きは1になります。
これがおもしろいんですが、三角関数のsin(x)を微分するとcos(x)になるんですね。じゃあcos(x)を微分するとどうなるかというと、−sin(x)になるというおもしろい性質があります。三角関数はおもしろいんですが、特に微分する時のこの挙動が非常におもしろいと僕は思っています。ここまでは学校で習うような話でした。
プログラムで理解するとよりわかるので、ちょっとこんなデモを見てみましょう。これはSharpLabというもので、サイトを開くといきなりこうなっているんですが、C#の実行環境です。Unityでもよかったんですが、これがお手軽なのでやってみましょう。SharpLabは書いているそばからコンパイルされて、すぐに結果が出るというすごく便利なサイトです。
まずいらないところは削って、Console.WriteLineで適当な数を出してみましょうか。100とかにすると、いきなりコンパイルされて横に100が出ていますね。便利ですね。
func()で、xを引数とする関数を作ってみましょう。xの2乗を返す。それでこの関数を呼んでみましょう。float y = func(3f)で3にしてみましょうか。3を入れると、答えはどうなるかというと3×3が9、2乗が出ていますよね。9が出るということになります。いいですね。
ではここから導関数を実装してみましょう。導関数の実装はどうするか。導関数は英語でderivativeと言います。derivativeで引数xを取って、ここに何を書けばいいでしょう。上で定義をしたfunc()を呼びます。その時、func(x+h)で呼びます。hを上で定義したほうがいいですね。先に定義しておきましょう。小さな値の0.1にしておきましょう。
このとおりに実装します。func(x+h)からfunc(x)を引いてその全体をhで割る。これで完成です。この導関数を呼んでみましょう。どうなるでしょうか。ここにまた3を入れてみましょうか。いったいいくつが出るでしょうか。先ほどx^2(※xの2乗)の導関数で2xとやりましたね。ということは、3を入れたら何が出るかというと、6なんですね。6に近い値が出ました。プログラム中には、2xとは書いていないですね。だけどこのようにきちんと定義どおりに書くと、6に近い値が出ます。
ではこの0.1をより小さくしたらどうなるのかやってみましょう。0.01、すると答えはより6に近づいてきました。0.001にしたらさらに6に近づきました。
つまりこのhは、“精度に影響する”という言い方ができると思います。もちろん浮動小数の限界があるので、いくらでも精度を上げられるわけではありませんが、こういう挙動を示すということは理解しておいたほうが良いでしょう。
プログラムでやってより理解が深まったと思いますが、実はゲームを作ったり、プログラムを組む中で、関数が与えられてその導関数を作ることはあまりないんですよね。
実は微分はそういう使われ方はあまりありません。じゃあどう使われるかというと、例えばこんな例です。ある地点の傾斜を知りたい。デコボコした地形があって、その地形は関数で与えられているわけではないので導関数を作れません。だけど、傾斜が知りたい時があると思うんですよ。プレイヤーの立っているところはどのくらい傾いているのか。
どの地点も高さがわかっているという条件があるなら、みなさんやり方が思いつくんじゃないでしょうか。ある地点の高さがわかっていて、ちょっと離れたところの高さを調べる。そこを引き算すれば傾きが出そうじゃないですか。これはみなさんも思いつくと思うんですよね。差を取るだけで傾きが出るし、ゲームもたぶん完成するでしょう。
だけど、hで割るという微分の知識があれば、精度だけに影響するということがわかるので、後で調整できるんですよね。こういうことを知っておくと便利だと思います。x軸の傾きが出たので、z方向にも傾きが取れますよね。結果的に2つの値が傾きのベクトルになるでしょう。
今、偏微分の記号が入っていて、これはgradientという名前が付いたりもします。難しそうに見えて、実はそんなに大したことじゃないんですね。
どんな時に使えるか。例えばパーリンノイズで作られたノイズが流れていく、落ちていく時、gradientを使って傾きの力をかけてあげればこんなふうに流れが作れます。
そうすると、水のエフェクトを作ったとしても、こういう窓ガラスをつたって流れる感じのエフェクトがよりリアルになっていくんじゃないでしょうか。
というわけで、プログラムで使う時は実はすごく難しいことを知らなくても普通にやっちゃうことなんですね。ですが、たまにこういう勉強をしておくことでわかることはあります。ちょっとそんな例を見てみましょう。
Unityのシェーダーグラフです。いろいろなノイズ関数をここに出していますが、ノイズ関数の中は実装を見ることができます。見てみるとこうなっています。そんなに長いプログラムではありません。これが全体です。上から1、2、3行目を見てみると、これはいったい何だろう。何をしているんだろう。初見でこれがわかる方は、なかなか少ないんじゃないかなと思うので、ちょっとこれを解明してみましょう。
こんなグラフがあったとしましょう。f(x)=xという単純な、常に傾きが1のグラフです。当然(1,1)のポイントを通ります。
ここが角ばっているのが嫌。(スライドを示して)ここが角ばっているのが嫌。何を言っているかというと、始まりを水平にしたい。終わりも水平にしたい。
こんな関数で置き換えたら滑らかになるんじゃないかなと思ったとしましょう。
この関数をg(x)にしましょう。このg(x)の正体、どんな関数かを考えてみましょう。3点を通るので、3つ条件が簡単に出ます。(0,0)を通るし(1,1)を通るし、(1/2,1/2)を通ると。
次に導関数。0のところの傾きを0にしたい。1のところの傾きも0にしたいというわけで、5つの条件があることになります。5つあるので変数は5つまで大丈夫で、仮にg(x)をこう過程してみましょう。
a、b、c、d、eの5つがわからない数字として、x^4(※xの4乗)の係数にaが入っているという関数を考えてみましょう。
そうするとこれで導関数がわかりますね。あとはこの2つの式にこれ(5つの変数)を全部突っ込んで、連立方程式を解けばa、b、c、d、eがわかります。そうすると結果はこうなります。bとc以外は0ですが、結果としてg(x)というのはこういうかたちをしています。これが答えということになります。
グラフで見るとこんな感じですね。これがf(x)=−2x^3+3x^2(※2xの2乗+3xの2乗)のグラフになります。
では先ほどのプログラムにもう1度戻ってみましょう。これはこの関数そのものだったんですね。このプログラムではこんなノイズが出ていました。
では仮にこの3行目をコメントアウトしたらどうなっちゃうのかな。やってみるとこんなふうになるんですね。ガクガクしてあまりきれいじゃないノイズが出ている気がしませんか?
あまりきれいじゃないものを滑らかにする効果がここにあったわけですね。つまり0と1の値で導関数を使って傾きが0になるように、調整した関数に置き換えていたということになります。こんなふうに微分を使って、こういう関数を導くことができますよという話でした。
いかがでしたか。微分の話はここまでです。そんなに難しい話じゃなかったと思います。なんか使い方がわかってきたような気がしませんか? ぜひみなさんUnityでプログラムを組む時に、微分の考え方を使ってすてきなアプリケーションを作ってください。以上です。
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05