見出し画像

量子コンピューターで機械学習を学ぼう!「QC4U2」に参加してみた-第2回目- 後編

こんにちは、デザイナーのヤマモモです!🙇‍♂️
今日も引き続き、大関さんが量子コンピューターを無料で教えてくれるというオンライン講座の第二回目のレポートの後編を書きます😄
今回は内容モリモリ!正直、前半の記事との配分ミスったw
なので簡略化してる部分もあります、あしからず🙏

初見で講義を聞いたヤマモモの心境

コメントでも書いてる人いたけど、まじで初見で聞いた時、宇宙猫w
でも1回最後まで見て、そのあと何回か見直すと少しずつ理解できてきたので、頑張って書きます🐱

↑前回の記事

会員登録してない人でもこの動画視聴できますので、是非御覧ください!


【前回のおさらい】データをまとめる

前回、テンソルという形式に置き換えました。
これでパイトーチ君(機械学習のライブラリ)が扱えるデータになりました。

私たちが今回のやりたいことは、コンピュータが「この関数かな?」と自動的に動かし、ぴったりの関数を見つけることです👀

前回の関数

動かしてこの関数とピッタリ合えば大正解🎉というわけです。

トレーニングデータとテストデータにわける

でもそのデータって本当に合ってる?と不安になるので、データをトレーニングデータとテストデータに分けます✏️ (2:29:24)

  • トレーニングデータ → この関数どんな感じ?と調べてもらうこと

  • テストデータ → 予測した関数は合ってる?というテストをすること

トレーニングデータとテストデータのイメージ図

学校でもドリルをやって終わりではなく、テストをやって、本当に理解してる?って先生が確認しますね。
ここでいうテストというのはドリルとは似てるけど違う問題をやるような事だそうです。

n_train = int(len(dataset) * 0.8)
n_test = len(dataset) - n_train
  • n_train → トレーニングデータ

  • n_test  → テストデータ

今回は100問中、80%のデータをトレーニングデータとしてコンピュータに学習させます📚✍🏻
残りをテスト問題として出すよという風に指示します💯📝

ニューラルネットワーク(NN)を作ろう!

私たちは、「コンピュータが動かせるパラメータがある形」で用意しなくてはいけないようです。うん、難しい😇
ここで私の苦手な関数が再び登場…🫠

一次関数の説明

【一次関数】
このaとbというのは関数を操作できるパラメータ
  • a=傾き=角度を動かすパラメータ

  • b=切片=縦に動かすパラメータ

一次関数って中学生で習うよね。解説受けるまで本当に忘れてた…
改めて勉強になりました、どうもありがとうございます🙇‍♀️🙇‍♀️

上でも書いたように、私たちは点で表された関数にピッタリの関数を作ってもらうのが今回の目的です👀
その為に、まずは「y=ax+b」でどうよ?と関数を用意してあげる。
aとbはパラメータなので自由に動かせるよね?じゃあ動かして一番近いものを探そうよ🤙
↑ というのがニューラルネットワークの考え方だそうです。
理解できたような、できないような🤔

線形変換させる

大関さんが説明
self.fc1 = nn.Linear(1, 1)

↑Linearとは線形変換(足し算と掛け算)のこと。
これは、xに1個の数字を入力したら、線形変換をして、aから1個の数字を出力してねと指示👉
これによって、先程の一次関数のaとbが動かせる状態になるそうです。(2:46:45)

bの説明

あれ、bは?と思ったのだけど、bはこのように求められるよね?と説明をしてくれました。
でも私にはよくわからなかった(大関さん…ごめんなさい😭)

シグモイド関数を設定する

大関さん「ただ一次関数だと難しくないし微妙だよね?もっと複雑な関数扱いたいでしょ?😄」

その時のヤマモモの心境

でも一次関数(直線)だけであの三角関数の曲線を表現するのは無理だそうで😅
もうちょっと複雑な関数を使ってフィッティングしてねという事なんだって。(2:49:41)

これがシグモイド関数

シグモイド関数は0〜最大1までS字に増加し、0.5を通るものらしい。

2つの関数を使って、目的の関数を表現したい

Sigmoid(ax+b)
このようにax+bをSigmoidで囲んだことによって、値が変わるそうです。
一次関数のax(傾き)とb(原点)を動かす事と、シグモイド関数の形を変える事で、目的の関数を頑張って表現できるようにします💪

線形変換と非線形変換を繰り返す

class NN(nn.Module):
  def __init__(self):
    super(NN, self).__init__()
    self.fc1 = nn.Linear(1, 1)
    self.sig = nn.Sigmoid()

  def forward(self, x):
    h = self.fc1(x)
    y = self.sig(h)
    return y

↑大関さんからのコピペなんだけど、こういうコードが完成しました。(2:52:55)

どんなこと書いてるかと訳すとこんな感じ

一次関数とシグモイド関数を使ってニューラルネットワーク君が結果( y )を出せるようになりました!

ニューラルネットワーク

ちょっと内容難しいので大関さんの言葉をお借りします🙇‍♂️

線形変換させて非線形変換させてそれを結果としなさい。
AとBを動かすことによってy=f(x)を再現しましょう。
再現できたらっそのときのAとBの数字を使えば、この先「y=f(x)」に似た関数をコンピュータ上で作り出す事ができる。
このコードは基本形でとても大事。

by大関さん

このコードは超初歩的な基本形という事です。
この基本形を繰り返す事を、入れ子構造といいます🪆
この入れ子構造を何重にもすることをニューラルネットワークと言うそうです🪆🪆🪆

複雑な関数はミルフィーユのようなもの by大関さん

入れ子構造みたいにする事で、何回も線形変換→非線形変換→線形変換→非線形変換ってやるらしいんだけど、大関さん曰く「パイ生地を捏ねるようなイメージ」らしいw
そして出来上がるのがミルフィーユのように何層もあり、姿が全く違う関数。
何層にも深い→だからディープラーニングと言うんだって!
なるほど😳

正解との誤差を調べる

criterion = nn.MSELoss()

ここまで、ニューラルネットワークが結果( y )を出せるようなコードを書きました。
でもその答えって本当に合っているの?という事で「結果= y 」と「正解= t =当ててほしい関数」の誤差を調べるそうです。(3:08:04)

平均二乗誤差

平均二乗誤差を説明してくれる大関さん

MSE=平均二乗誤差とは
「t(正解)」と「y(ニューラルネットワークの出力結果)」を二乗して、ズレを引いて調べる事。
「 i 」というのは色んなデータがあるよ、ということ。
「 i 」が1〜100個あるので、全部足して100で割って平均出してね。
どこかズレてたらダメです!できるだけ誤差がない方がいいですよ!ということ。

By大関さん

難しい言葉出てきた…🥲
まぁ、ズレが少ない方がいいよって事ですね!(考える事を放棄)

誤差からチューニングしていく

ここまで、正解と結果の誤差を調べました。
次にその誤差からチューニングを加えていくそうです。(3:10:56)

optimizer = optim.SGD(net.parameters(), lr=0.1)

SGD=Stochastic Gradient Descent
→直訳すると「確率 勾配 降下」です。

確率勾配降下法

左右にいくほど傾きが大きい=誤差が多い
  1. 「傾きa」というものがあります。右に行けばいくほど、傾きが大きくなります。左も同じ。(ピンク色の線)

  2. そこに「データ」というものが横並びであったとしましょう。(データ=グレーの●)

  3. その時、「データ」と「傾き」で誤差が少ないのは真ん中のフラットな状態です。

誤差の大きさは傾き調べればわかる

確率勾配降下法とは
傾きが大きいものほど誤差が多い、傾きが小さいほうが誤差が小さい。
真ん中の誤差がない状態にしたいので、傾きに従って下がればいい=だから、坂道下れる方向を調べなさい。

by大関さん

またまた言葉が難しいけど、下に(誤差が少ない方)転がりたい感じなんですかね🤔
これでニューラルネットワーク君は答えを調整をするらしいです。

ちなみに傾きがなさすぎるとニューラルネットワーク君もどっちに行ったらいいかわからなくて学習できなくなってしまう事もあるらしいよ😰(勾配消失問題という)
動画では微分とかの説明や、もっと詳しいこと話してたので、見てくださいw(3:16:31

データを与えて学習させる

ここも説明が難しくて…🤨
大関さんが概念を説明してくれたので、それをまとめて書きますw

Tall = 100

↑まず何回学習させるか設定します。今回は100回。

for epoch in range(Tall):
  sum_loss = 0
  for batch in train_loader:
    optimizer.zero_grad()
    xtrain,ttrain = batch
    ytrain = net(xtrain)
    loss = criterion(ytrain, ttrain)
    loss.backward()
    optimizer.step()
    sum_loss += loss.item()

  train_loss_value.append(sum_loss/len(train_loader))

  sum_loss = 0
  for batch in test_loader:
    xtest, ttest = batch
    ytest = net(xtest)
    loss = criterion(ytest, ttest)

    sum_loss += loss.item()

  test_loss_value.append(sum_loss/len(test_loader))

↑このコードの説明を「いらすとやさん」の素材をお借りして表現してみました↓

【GIFアニメ】大関さんの説明っぽいこと

ニューラルネットワーク君=🧠にしました。
最後の方手抜きだけど、多分こんな感じ😅
前半部分はトレーニングデータの事で、後半がテストデータに変えてるだけだからコードもそんなに変わらないのだよね。

ここまでで、ニューラルネットワークへの学習は終了!
さぁどうなったかな!?ぽちっとな🫵

エラーが出たよ

まさかのエラーが!?

えええなんで!??😱何回も大関さんのコード見直したよ。?インデントもズレてないし!
でも何回もエラー出してくるのよ!😩
くっそーーー何が違うんじゃあああああ!😡怒
コンピュータ君、ぶっ壊れてませんか!??🤬

もうわからないので、QC4U2に参加されてる先輩方に質問しました🙇‍♀️

「ニューラルネットワークの基本形」の部分のインデントずれてた

そしたらね、まさかのインデントがずれておりました…
コンピュータ君ごめん、疑って…😂

コンピュータ君、お気持ち表明

でもさ、エラーが出たら、エラーが出た直近のコードを疑うじゃない??💦
そしたら何個か上のコードのインデントエラーなのよw
じゃあその時にエラー出してくれよぉ😂
初心者の方は気をつけてね🥹

コラボラトリーの設定

他の参加者さんに、コラボラトリーの設定 > エディタ > インデントのガイド表示「オン」 にするといいよと教えて頂いたので、さっそく使っています!!
QC4U2の皆さん優しいです😊 本当にありがとうございました✨

誤差がどれくらい減ったかな?

エラーも無事解決したので、次に進みます!!
ドリルとテストをやって学習したニューラルネットワーク、どのくらい理解しているのでしょうか?(3:55:00)

「誤差が減ってきている」を表したグラフなので
まだ結果の関数ではないですよ⚠

グラフが平らになればなるほど、誤差が少なくなっています。
右に進むほど(問題数をこなす毎に)平らになってくれていますので、少しずつ賢くなってくれているようです😊

結果発表

ついに関数の結果を見ます👀 (3:58:08)
実際にニューラルネットワークはどんな関数を描いているのでしょう?

私のニューラルネットワークが書いた関数

出た出た!
点(正解)に線を合わせようとニューラルネットワーク君が頑張っている…のか?💦
つーか、お前シグモイド関数のまんまじゃねぇか!🙀
そもそも本当に学習できてるの…?と疑問🤔

1回しか学習させてない子はテキトー

そんな疑ってる人のために大関さんが、同じ内容を1回しか学習させてないニューラルネットワークの結果を出してくれたよ!
これは…あまりにもテキトーでやる気ねぇ🤣wwww
まるで私みたいなやつだな…😎

ニューラルネットワークを修正する

これだと学習内容が足りない💦ってことで、先程私がインデントをミスった(ニューラルネットワークの基本)部分に戻り、再度修正をします!

class NN(nn.Module):
  def __init__(self):
    super(NN, self).__init__()
    self.fc1 = nn.Linear(1, 5)
    self.fc2 = nn.Linear(5, 5)
    self.fc3 = nn.Linear(5, 1)
    self.sig = nn.Sigmoid()

  def forward(self, x):
    h = self.fc1(x)
    h = self.sig(h)
    h = self.fc2(h)
    h = self.sig(h)
    y = self.fc3(h)
    return y

xに数字を入れたら、それをまず5個に分けちゃおう。さらに5個に分けて、最後1個にまとめようというふうに指示しました。

シグモイド関数の部分は別の関数にもできるんだって。
私はわからないので、シグモイド関数のままいきますw
(大関さんの動画だと別の関数入れてるから、興味ある方は見てみてね。 4:02:31〜)

修正した関数

おお!さっきより、点に沿って描画してくれている!✨
やればできるじゃあないか!🤓

極めたい方はシグモイド関数を他の関数にしたり、もっと調整したりするみたい。私はこれで満足ですw

以上がニューラルネットワークを作るという今回の講義でした。
次回は、量子機械学習をするそうです!👍

【おまけ】手書き文字認識

ちなみにこちら↓の第二回講義の解説ではMNISTという手書き文字認識についても解説してくれてます😆

ヤマモモは元気があればやってみます。
だってこのレポート書いてる時に、もう3回目の講義終わってるから全然追いつかないんだよおぉぉぉ😭😭😭

受講感想

機械学習って難しいんだね。(並の感想)
講義を受ける前まではAI生成みたいに、打ち込んだら自動で出してくれるものかと思ったけど、裏にはこうやってニューラルネットワークを調教というか、人の手が加えられてるんだと気付きました。

それにコードが独特すぎて、今のとこと0からは書けないわ…😓
どうしてこのコードを書いてるのかとかはイマイチ理解してませんw
でも大関さんの翻訳のおかげで、フワッとは理解できています😇(上手く説明はできないけど)

QC4U2参加者さんに感謝!

あとインデントエラーもQC4U2の参加者さんに教えてもらわなかったら、絶対わからないまま終わっていたよ😱
圧倒的感謝です!みなさん、ありがとうございました🥹

AdobeExpressでAI生成したんだよ

冒頭で出した「宇宙猫」は実はAI生成してました。
この生成サービスの裏側にも何層ものミルフィーユがあるんだろうな…🤤

では ノシ

↑次の記事

この記事が参加している募集

この記事が気に入ったらサポートをしてみませんか?