はとむぎ研究室

大学生の備忘録でした

基本情報技術者試験(CBT形式)受けた

はじめに

今回の試験が初めて。 本当は去年の4月に受ける予定だったけど...

勉強方法とかは軽くしか書きません。 応用受けるときの自分用メモです。 今から忙しくなり次回の受験まで時間が空くので...

結果

追記:たぶん合格

追記(2021/04/27):合格

なんと"午前"の採点結果が出てないんです。 問い合わせたところ、翌日までには届くらしいです。 "午前"と"午後"の間に、プロメトリックの登録情報で「各種お知らせ」を希望しないにしていたことに気づき、 希望するに変更して"午後"を受けた直後、午後の結果は送られてきました。 しかし、問い合わせたところ関係ないみたいです。設定関係なく全員に届くそう。待ちます。

追記:どうも他にも同じ現象にあっている方がいらっしゃるようです(リンク)。

追記(2021/03/12):6時にメールが来てました。得点は86.25点でした。

  • ストラテジ系 ... 70%
  • マネジメント系 ... 90%
  • テクノロジ系 ... 92%

”午後”の結果は以下の通りです。計算したら86.9点でした。

  • 1 ... 80%
  • 2~5 ... 100%, 86%
  • 6 ... 72%
  • 7~11 ... 100%

感想

CBT形式、楽でよかったです。紙媒体でやったことないけど。

図や表に書き込みできないのは面倒ですが、解答漏れが発生しないのはいいのかなと。メモ(頼めば2枚以上OK)とペンは用意されていたので、計算も困りませんでした。レスポンスも特に不満はありませんでした。

午前と午後を別日に受けられるというメリットは取りませんでした。会場が遠いので。 でもそれでよかった気がします。勉強のモチベ切れそう。

”午前”より”午後”のが簡単だった。

易化したと言われていますが、あまりそうは思いませんでした。確かに合格率は例年より高いですが。結果を見ると、”午前”過去問演習時より正解率たけーなとは思いましたが、受験時は頭抱えてましたからね。”午後”の過去問は1つの大問10~20分で解いていて、本番は前半3つで40~50分くらいだったので、そんなものかと。なので今後、今期を受ける方も油断はしてはいけないと思います。

対策勉強について

まず前提として、私は情報系の大学生なので、ある程度はテクノロジ系はある程度知ってました。 しかし、今回の勉強で知識がガタガタであることを思い知りました...特にネットワーク。 あと、情報系でも生命系なので、ハード面は講義であまりやってません。院試対策で独学でやってたけど。

今年の2月の初めに友人から誘われ、勉強を始めました。1日0~5時間程度だったと思います。約1ヶ月間の勉強で合計100時間あるかないかです。去年の3月くらいに少しやりましたが、参考書の1章分くらいしかやってなかったのでノーカウントです(忘れてたし)。

使った本:

理由:本屋で手に取った本の中で一番楽そうだったから。2020/04に受ける予定でその時に買ったので、2020年版でした。訂正、2019年版でした。勉強しようと思った時の最新版買えばいいと思います。

感想:サラサラいけます。要点も抑えられてる。ただ、(仕方のないことだけど)足りないところもあります。軽く2周して、あとは試験前にチェックしていたところを確認しました。

使ったサイト:

www.fe-siken.com

理由:解説がしっかりしている。チェック機能あり。問題の絞り込み機能あり。

感想:過去問の本買ったけど、これだけで十分だった。特にCBTだと、PCでこのサイトを利用するのが対策として一番いいのかも。7回分を解けるまでやりました。

方法("午前"):非計算問題・計算問題で絞り込み、前者を一周したあと後者も一周、そして間違えた(赤チェックした)問題を復習。不安な(黄チェックした)問題を復習した。

最後に

”午後”の勉強はほとんどしていません。 「情報セキュリティ」「ハードウェア」「ソフトウェア」「データベース」「ソフトウェア設計」は2日間で8回分やりました。 ここで時間がなくなったので、他はぶっつけ本番でした。

結果を見ると、”午後”についてはそんなに過去問しなくてもいいなという感想です。同じ問題もあまり出ないそうですし、範囲は”午前”と変わりませんからね。ただし形式慣れには良いかもしれません。

本番の所要時間は、”午前”も”午後”も約90分でした。1時間残しての退出ですね。各自で終了ボタンを押して退出できるのはCBTのメリットですね。

以上です。

NNにおけるSigmoid関数とReLU関数の比較

はじめに

某大学院の院試の過去問に、「DNNにおいて中間層を増やすとSigmoid関数よりReLU関数の方が優れている理由を述べよ」といった問題があったので、調べてみた。

Sigmoid関数

Sigmoid関数は次のような式で表される。

y=\frac{1}{1+e^{-x}}

Sigmoid関数

メリット

Sigmoid関数は入力に対して連続なので微分ができる。この微分ができるという点は、誤差逆伝播法による学習を伴うニューラルネットワークにとって重要である。

導関数は以下の通りで、簡単に計算ができる。

y'=(1-y)y

デメリット

  1. 入力が極限に大きく、または小さくなると勾配が消える。

  2. 誤差逆伝播によるパラメータの更新において、入力層に近づくほど、学習量が小さくなり、学習が進まなくなってしまう。

  3. 微分値の最大値が0.25であり、学習の収束が遅い。

ReLU関数

別名ランプ関数と呼ばれ、入力が0以下の時は0を、それ以外(0より大きい)時はその値を出力する関数である。

y=max(0,x)

ReLU関数

x=0において、非連続で微分不可能であるが、その他の領域では微分可能なので、微分可能な活性化関数として扱われることが多い。

メリット

  1. 微分値が定数なので、計算量を圧倒的に減らせ、誤差逆伝播の計算効率が良い。

  2. 微分値が一定であることから、誤差逆伝播による勾配の消失問題を防ぐことができる。

デメリット

  1. 入力が負の時、微分値が0なので、重みパラメータの更新がされない。

考察

2つの関数のメリット・デメリットをそれぞれみていくと、どうも勾配の消失問題に答えがありそうだ。

勾配消失問題とは、誤差逆伝播法が下位層に向かって進んでいくにつれて、勾配がどんどん緩やかになっていく。そのため、勾配降下法による更新では下位層のパラメータはほとんど変わらず、訓練は最適値に収束しなくなるといった問題のことである。

勾配が消えていく理由は、シグモイド関数微分係数の最大値が0.25(範囲: 0.0~0.25)であり、そのシグモイド関数を重ねれば重ねるほど勾配の値は小さくなっていくからである。

試しに、0.255を計算すると……9.8 \times 10^{-4}と、かなり小さい値になる。

一方で、ReLU関数の導関数は、x<0のとき0、x>0のとき1である(x=0のときは微分不可能)。

よって、ReLu関数では勾配消失問題が起きることがないため、題意のようになる。

参考文献

fresopiya.com

www.atmarkit.co.jp

qiita.com

【数値計算#1】根を求める

根ってなんだよ

 ある関数f(x)が0になるときのxの値のこと。
例:f(x)=x^{2}-1の根は\pm{1}である。

二分法

概要

 初期区間[ x_l,x_r]のどちらかを中点\frac{x_1+x_2}{2}に適切に置き換え、どんどん幅を狭めて根を求めていく。
 長所:確実である
 短所:収束は遅い

詳しく説明してみる

 y=x^{2}-2について考えてみる。次のグラフは、y=x^{2}-2 ()とy=0 (黒)を図示している。

f:id:heart_mugi:20201001212228j:plain
二分法(1)
 さて、初期値[ x_l,x_r]を[ 1,2]とする。これも図示してみる。
f:id:heart_mugi:20201001212347j:plain
二分法(2)
 次に、x_lx_rの中点x_m=を求める。中点x_m=\frac{x_l+x_r}{2}=\frac{1+2}{2}=1.5となり、これも図示してみる。
f:id:heart_mugi:20201001212533j:plain
二分法(3)
 ここで、f(x_l)(x_m)f(x_m)(x_r)について考える。もし、とある2点からなる幅の間に根があるとき、その2点をそれぞれ関数に代入した値どうしの積は負の値になるはず(正\times=負)である。f(x_l)f(x_m)\lt 0, f(x_m)f(x_r)>0より、[ x_l(=1),x_m(=1.5)]を採用。なので、x_r=x_mと置き換える。
f:id:heart_mugi:20201001213550j:plain
二分法(4)
 以下繰り返し。f(a)f(b)\lt 0かつ|a-b|\lt \epsilonとなったとき、探索を終了する。直前の中点が答えになる。

Pythonソースコード

def bisection(func, xl, xr):
    epsilon = 1.0e-6
    i = 0
    while(abs(xr-xl) > epsilon):
        sl = func(xl)
        sr = func(xr)
        xm = (xl + xr) / 2    # 中点
        sm = func(xm)
        if(sl*sm < 0.0):
            xr = xm
        else:
            xl = xm
        i += 1
        print('iteration:{}, value:{}'.format(i,xm))
    
    return xm

実際に動かしてみる

関数y=x^{2}-2

def func(x):
    return x**2-2


実行

bisection(func, 1, 2)
iteration:1, value:1.5
iteration:2, value:1.25
iteration:3, value:1.375
iteration:4, value:1.4375
iteration:5, value:1.40625
iteration:6, value:1.421875
iteration:7, value:1.4140625
iteration:8, value:1.41796875
iteration:9, value:1.416015625
iteration:10, value:1.4150390625
iteration:11, value:1.41455078125
iteration:12, value:1.414306640625
iteration:13, value:1.4141845703125
iteration:14, value:1.41424560546875
iteration:15, value:1.414215087890625
iteration:16, value:1.4141998291015625
iteration:17, value:1.4142074584960938
iteration:18, value:1.4142112731933594
iteration:19, value:1.4142131805419922
iteration:20, value:1.4142141342163086

GANの仕組み

GANの仕組み

 与えられた画像が本物か偽物かを見分ける識別器 vs 識別器を騙す画像を作る生成器

 

識別器の学習

 下図の通り、[0,1]のノイズを与えられた生成器が作成した偽物の画像と、学習させたい本物の画像を用意する。<本物の画像, 正解ラベル(全て1)>と<偽物の画像, 正解ラベル(全て0)>の2組を識別器に与えて、識別器を学習させる。

f:id:heart_mugi:20200914230939j:plain

識別器の学習の様子

 

生成器の学習

 下図の通り、ノイズから作成した偽物の画像と全て1(つまり全て本物とする)正解ラベルを識別器に与え、生成器を学習させる。つまり、生成器は作成した画像が全て本物だと誤認されるよう学習している。注意点として、このとき識別器は学習していない。

f:id:heart_mugi:20200914231348j:plain

生成器の学習の様子

 

参照

 

実践GAN ~敵対的生成ネットワークによる深層学習~ (Compass Booksシリーズ)

実践GAN ~敵対的生成ネットワークによる深層学習~ (Compass Booksシリーズ)

 

 

重みの正則化

重みの正則化

 より単純なモデルのほうが、より複雑なモデルよりも過学習に陥りにくいため、単純なモデル(パラメータの数が少ないモデル)をつくりたい。
 ネットワークの複雑さに歯止めをかけるように重みの値を制限すると、重みの値の分布がより正則化される。これを重みの正則化と呼ぶ。重みを正則化するには、大きな重みを使用する場合のコストをネットワークの損失関数に追加する。このコストには、次の2種類がある。

L2正則化を実際にやってみる

from keras import regularizers

model = models.Sequential()
model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
                                        activation='relu', input_shape=(10000,)))
model.add(layers.Dense(16, kernel_regularizer=regularizers.l2(0.001),
                                        activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))


 l2(0.001)は、その層の重み行列の係数毎に、ネットワークの全損失に0.001 * weight_coefficient_valueを足すことを意味する。このペナルティが追加されるのは訓練時だけなので、このネットワークの損失値はテスト時よりも訓練時の方がずっと大きくなる。

f:id:heart_mugi:20200911183245j:plain
L2正則化が損失に与える影響(過学習を抑制している)

他の正則化のコード

from keras import regularizers

# L1正則化
regularizers.l1(0.001)
# L1正則化とL2正則化の同時適用
regularizers.l1_l2(l1=0.001, l2=0.001)


参考

ai-trend.jp