くますきIT日記

IT系資格、競技プログラミングの情報を書いていきます。

E資格の勉強⑥深層学習day4

目次

本投稿の目的

深層学習(day4)に関する学習のまとめ

Section1:強化学習

【要点】

強化学習

 最終的な報酬を最大化する、というエージェントを作ることを目的とした機械学習

 → 競技プログラミングで例えると動的プログラミングのイメージ。
 例:顧客が100人存在するとして、誰にキャンペーンのメールを送るか。

   上記の場合、「キャンペーンの売り上げ - 送るコスト」 を最大化するようなエージェントを作成する。

   ・ 全員に送ると送るコストが不要に大きくなる。

   ・ 全員に送らないとキャンペーンの売り上げがない。

   → 最適な行動を見つける必要がある。

 

【実装演習】

 実装演習が無いため、以下サイトを参考に、演習を行った。www.tcom242242.net

 

~問題の設定〜

 

――――――――――――――――――――――――

演習①4×4の迷路。ゴールに到着=報酬100。トラップに到着=報酬-100。

――――――――――――――――――――――――

情報:迷路の状態

self.filed_type = {
"N": 0, # 通常
"G": 1, # ゴール
"W": 2, #
"T": 3, # トラップ
}
self.map = [[3, 2, 0, 1],
[0, 0, 0, 2],
[0, 0, 2, 0],
[2, 0, 2, 0],
[0, 0, 0, 0]]

情報:使用した設定

# 定数
NB_EPISODE = 100 # エピソード数
EPSILON = .1 # 探索率
ALPHA = .1 # 学習率
GAMMA = .90 # 割引率
ACTIONS = np.arange(4) # 行動の集合

 

実行結果

f:id:you_it_blog:20211122232808p:plain

→ 4×4のシンプルな迷路であるため、20回目ほどでエージェントが最大の報酬を獲得できるようになっている。

 ※試行回数をエピソードと呼ぶ。

 

――――――――――――――――――――――――

演習②4×5の迷路。(迷路を大きくする。トラップの数も増やす)

――――――――――――――――――――――――

情報:迷路の状態

def __init__(self):

self.filed_type = {
"N": 0, # 通常
"G": 1, # ゴール
"W": 2, #
"T": 3, # トラップ
}
self.map = [[3, 2, 0, 3, 0],
[0, 0, 0, 2, 0],
[0, 0, 2, 0, 1],
[0, 0, 0, 0, 0]]

情報:使用した設定

# 定数
NB_EPISODE = 100 # エピソード数
EPSILON = .6 # 探索率 ※.1で確認した結果が良くなかったため修正。
ALPHA = .1 # 学習率
GAMMA = .90 # 割引率
ACTIONS = np.arange(4) # 行動の集合


実行結果①

f:id:you_it_blog:20211122234533p:plain

→ 50回目くらいで、ようやく最適解を得れるようになった(難しくなった)

 

実行結果②探索率.1の場合

f:id:you_it_blog:20211122234932p:plain

→ 最適解にたどり着けないまま終了している。

 ※パラメータ設定の重要性が分かる結果となった。

 

【関連記事レポート】

以下サイトには、実装演習のみでなく理論も記載されている。

www.tcom242242.net

強化学習エージェントにて行動選択に使用される関数の説明も読み込んでおくべき。

 ・ε-greedy行動選択

  ε-greedy法とは~制御工学の基礎あれこれ~
  →上記サイトが分かりやすかった。まずはランダムに選んで、

   結果を確認してから最適解を探していく・・というまさに貪欲法の手法。

 ・softmax行動選択

  【強化学習】softmax行動選択

  → 高期待値の選択肢を選ぶ確率を上げていく手法。

 

Section2:AlphaGo

【要点】

AlphaGo:

 Google DeepMindが開発した、囲碁AI。※

 教師有り学習と強化学習を使用して、3つのネットワークを学習させている。

 ※AlphaGo(Lee)は囲碁だが、後継のAlphaGoZeroは将棋やチェスも可能とのこと。

 

www.sbbit.jp

 

Alpha Go の学習ステップ:
①PolicyNetの教師あり学習
 教師データ:3000万局面分の棋譜データ。教師と同じ手を指せるように学習。
 ※教師1、その他0とした19×19の配列を分類問題として学習させたとのこと。

②PolicyNetの強化学習
 PolicyNetとPolicyPool(500イテレーション単位で強化学習の結果を保管した物)で対局を行い、その結果を用いた方策勾配法で学習。
 ※ミニバッチ学習(単位:128)を1万回実施したとのこと。

③ValueNetの学習
 PolicyNetで対局を行い、途中まで①のモデル、途中から②のモデルを使用。
 その勝敗結果をラベルとした教師データを作成して学習。
 ※ミニバッチ学習(単位:32)を5000万回実施したとのこと。

 

【実装演習】

実装演習が無いため、以下サイトを参考に、演習を行った。

PythonでAlphaZeroを実装する場合のサンプル・・探すのに時間を要した。

 囲碁の盤面(19×19)でなく、Connect4(6×7)の実装。※Connect4:4目並べ

github.com


(Google翻訳アドオンで日本語に訳している。今回はgoogle colaboratoryを使用。pipの対象バージョンを若干変えないと動かない・・)

f:id:you_it_blog:20211123212506p:plain

実行結果(ニューラルネットワークの学習状態を確認)

f:id:you_it_blog:20211123212430p:plain

 

【関連記事レポート】

AlphaGoの作成元であるdeepmindのページを読み込んだ。

deepmind.com

 

・NNの内「ポリシーネットワーク」は、次に再生する動きを選択する。
  もう1つのNNである「バリューネットワーク」は、ゲームの勝者を予測する。
  → 概要であるが、各NNの役割が記載されている。
・AlphaZero:チェス、将棋、囲碁のゲームをマスターする方法をゼロから学ぶ、かつ世界チャンピオンのコンピュータープログラムを打ち負かす、単一のシステム。
  → 要点、にも記載している内容。AlphaZeroは「Go」でない→ 囲碁以外でも利用できる。
・MuZeroとして知られる最新バージョンのアルゴリズムは、AlphaZeroのパフォーマンスに匹敵すると同時に、
  ゲームのルールの説明なく、視覚的に複雑なゲームに対応する。
  → まだ開発初期の段階とのことであるが、より複雑なゲームにも対応できるモデル「MuZero」が開発中とのこと。

 

Section3:軽量化・高速化技術

【要点】

高速化:

 分散深層学習:並列で学習を行うことで学習の時間を短縮する。

軽量化:

 寄与度の低いパラメータの削除、パラメータの精度の削減などで精度を維持しつつ、メモリの使用量などを削減する。

 

――高速化1:並列化――

①データ並列化:

 ワーカー(学習に使用する端末)にモデルをコピー。

 データを分割して、各ワーカーで並列に学習を行う。

 同期型:

  全てのワーカーから結果が返ってくるまで待つ。

  結果が帰ってから、平均の勾配を計算してマスターとなるモデル(親モデル)を更新。その後、各ワーカーが最新のマスターを使用して学習を行う。

 非同期型:

  各ワーカーから結果が返ってき次第、マスターに勾配を反映。

  各ワーカーは、順次最新のマスターを使用して学習を行う。

 

 → 同期型は遅いが精度が高い。非同期型は早いが精度が安定しない。

  現在は同期型が主流とのこと。

 

②モデル並列化

 親モデルを分割して各ワーカーにコピー。(中間層を分割するイメージ)

 各ワーカーで並列に全てのデータを学習する。

 

→データが多い場合がデータ並列化。

 モデルが大きいときはモデル並列化。を使用するべき。

 

――高速化2:GPU――

GPU:元々は画像描画のための演算器。CPUより個々の性能が低いが並列処理は強い。

 → 並列化との相性が非常に良い。

 

――軽量化1:量子化――

パラメータの精度を落とす。(例:64bit浮動小数点 → 32bit)

NNはパラメータ数が膨大であるため、単純に半分にするだけでも効果が大きい。

なおかつ、64bit浮動小数点 → 32bit程度では精度が落ちない。

※落としすぎると極端に精度が落ちる。適切な調整が必要。

 

――軽量化2:蒸留――

高精度のモデルを基に、新たな軽量のモデルを作成する。

※高精度のモデルを教師に使用するイメージ。高精度のモデルの予測 と 新たなモデルの結果 の差異を利用して、新たなモデルの重みを更新する。

 

――軽量化3:プルーニング――

刈り込み、という意味。一定より重みが低い(= 寄与度の低い)パラメータを消してしまう方法。

※かなり大胆な削除も可能で、全体の90%近くのパラメータを削除 → 精度は90%以上を維持できる、という例もある。

 

【実装演習】

実装演習が無いため、以下サイトを参考に、演習を行った。

※テーマは色々あるが、今回は「量子化」の確認を行った。

www.tensorflow.org

 

量子化(64bit → 16bit)の効果を確認する。

f:id:you_it_blog:20211123221812p:plain

 

実行結果

INFO:tensorflow:Assets written to: /tmp/tmpqrhrrf6i/assets
INFO:tensorflow:Assets written to: /tmp/tmpqrhrrf6i/assets
WARNING:absl:Buffer deduplication procedure will be skipped when flatbuffer library is not properly loaded
Float model in Mb: 0.08052444458007812 ← 量子化前。
Quantized model in Mb: 0.02333831787109375 ← 量子化後。(サイズが1/4となっている)

 

【関連記事レポート】

www.tensorflow.org

 

――注目した部分――

重要度に基づいて重みのプルーニングを行い、トレーニング プロセスの過程でモデル内の複数の重みを徐々にゼロに指定することで、モデルのスパース性を実現します。スパースモデルは圧縮しやすく、ゼロの部分については推論の際にスキップできるため、レイテンシを改善できます。

この手法では、モデルの圧縮により改善が行われます。将来的には、フレームワークでこの手法をサポートすることで、レイテンシを改善する予定です。モデル圧縮により、精度の低下を最小限に抑えながら、最大で 6 倍の改善が確認されました。

→ 高速化、軽量化、には様々な手法が存在するが、将来的には特に実装を意識しなくても、手法を利用できるようになると思われる。※少なくとも、プルーニングについては将来的にTensorFlowでフレームワーク化されるとのこと。

 

 

Section4:応用モデル

【要点】

以下の3つのモデルについて記載する。

 ・MobileNet

 ・DenseNet

 ・WaveNet

 

――MobileNet――

軽量化・高速化・高精度化を実現した画像認識のモデル。

スマートフォンなどで利用できる軽さが強み。(名前の由来?)

→深さ別の畳み込み、と点別の畳み込み、の組み合わせで軽量化している。

 

・深さ別の畳み込みのイメージ(1チャネル1フィルタ)

※資料が分かりずらかったので、処理数の削減が分かるように紫の線と囲みを追加。 

f:id:you_it_blog:20211123234725p:plain

 

・点別の畳み込みのイメージ

※資料が分かりずらかったので、処理数の削減が分かるように紫の線を追加。

f:id:you_it_blog:20211123233818p:plain

 

通常の畳み込みの代わりに、上記の2つの畳み込みを使う事でほぼ同じ処理を高速に行っている。(Depthwise Separable Convolution)

以下の図が分かりやすい。

f:id:you_it_blog:20211123235047p:plain

 

 

――DenseNet――

NNでは中間層が増えるほど、前の層の学習が難しくなる。(=勾配消失問題)

その対策を行ったモデルがDenseNet。

 

以下の様に、後半の中間層の入力に、前半の入力層の出力を使用している。

→ 逆伝搬の際、後半の中間層からダイレクトに前半の入力層に繋がる道がある。

 → 経由する層を抑えつつ、先頭の層に逆伝搬を行うことができる。

f:id:you_it_blog:20211123235506p:plain



 

――WaveNet――

音声波形を作成するモデル。(Waveフォーマットが由来?)

特徴として、時系列データを畳み込むことで、広い範囲のデータを入力に使用している。(= 受容野を増やしている。)結果、時系列を考慮した非常に適切な出力を行うことができている。この畳み込みを「Dilated Convolution」と呼ぶ。

 

f:id:you_it_blog:20211124215312p:plain

 

【確認テスト】

――①(あ)に当てはまる単語を選択する――

深層学習を用いて結合確率を学習する際に、効率的に学習が行えるアーキテクチャを提案したことがWaveNet の大きな貢献の1 つである。

提案された新しいConvolution 型アーキテクチャは(あ)と呼ばれ、結合確率を効率的に学習できるようになっている。

 ・Dilated causal convolution
 ・Depthwise separable convolution
 ・Pointwise convolution
 ・Deconvolution

→正解は一番上の「Dilated causal convolution」

 

――②(い)に当てはまる単語を選択する――

(あ)を用いた際の大きな利点は、単純なConvolution layer と比べて(い)ことである。

 ・パラメータ数に対する受容野が広い
 ・受容野あたりのパラメータ数が多い
 ・学習時に並列計算が行える
 ・推論時に並列計算が行える

→正解は一番上の「パラメータ数に対する受容野が広い」。

 比較的少ないパラメータで、広い範囲の時系列を考慮した出力を行うことができる。

 

【実装演習】

実装演習が無いため、以下による演習を行った。

※今回はMobileNetを対象にした。

 

Google Colab(MobileNet)

 

試した点

元々のプログラムは「パンダの画像をパンダと判定する」内容であるが、

動作の確認のため「猫の画像」に変更した。

f:id:you_it_blog:20211124214654p:plain

使用した猫の画像(パンダと同様にWikipediaの画像を使用)

 

実行結果

f:id:you_it_blog:20211124214847p:plain

――――――――――――――――――――――――

INFO:tensorflow:Restoring parameters from mobilenet_v2_1.0_224.ckpt
Top 1 prediction:  282 tabby, tabby cat 0.6503355

――――――――――――――――――――――――
画像を「tabby cat(トラ猫)」と判定できている。

 

【関連記事レポート】

MobileNetに関する資料(V2のリリースの記事)

shiropen.com

――注目した部分――

MobileNetV2は、レイテンシ、サイズ、精度をトレードオフし、バッテリー消費を低減した低消費電力を実現しており、小規模、低遅延、低電力のモバイルファースト・コンピュータビジョンモデルとして機能させます。

TensorFlow-Slim Image Classification Libraryの一部としてリリースされます。クラウドに送るのではなく、モバイル上でニューラルネットワークを実行する利点としては、セキュリティ、プライバシ、レイテンシが緩和されること、そして、いつでもどこでもアクセスできるユーザーエクスペリエンスの向上が言えます。

→ MobileNetは軽量化・高速化・高精度化を実現した画像認識のモデル。と記載したが、その目的はここ。サーバへデータを投げることなく、スマートフォンなどの端末で機械学習が完結できるのであれば、サーバにデータを送り、処理を依頼する必要が無くなる。結果、通信の遅延やセキュリティの問題を気にする必要が無くなる。極端な話、オフラインでも利用する事ができるようになる。

 

Section5:Transformer

【要点】

Transformer:

 Seq2seqよりも高速かつ高精度な翻訳に利用できるモデル。

 Attentionを利用するのみで、RNNを利用しない。

 Encoder-Decoder Model。Encoderで入力をencode → encode結果をDecoderでDecoderする。(どちらも6層を持つ)

Attention:

 文中の単語の意味を理解する際に、どの単語をキーとすればよいか、という情報。

 例:it という単語は単体では解釈できない。前後の単語(human、he、penなど)をキーとする必要がある。

 

【実装演習】

実装演習が無いため、以下による演習を行った。

Transformerのチュートリアル(提供元:TensorFlowコミュニティ)

ポルトガル語を英語に翻訳するチュートリアル

 

実行結果

f:id:you_it_blog:20211124223803p:plain

比較:Google翻訳の結果

f:id:you_it_blog:20211124223908p:plain

→ 比較的簡単な文章であるものの、ポルトガル語を適切に英語に翻訳できている。

 

【関連記事レポート】

japan.zdnet.com

――注目した部分――

Googleは米国時間5月18日、自然言語分野における最新のブレークスルーとして、自然な会話を実現する新たな言語モデル「LaMDA」(Language Model for Dialogue Applications:対話アプリケーション用の言語モデル)について発表した。
最近の「BERT」や「GPT-3」といった言語モデルと同様に、LaMDAは「Transformer」をベースにしている。TransformerはGoogle Researchが生み出したニューラルネットワークアーキテクチャーであり、2017年にオープンソース化されている。

→ Transformerは2017年にオープンソース化してから、2021年、5年後の最新のモデルのベースにも使用されている。そのため、Transformerの動作の基礎を抑えておくことは、とにかく最新のモデルの仕組みを抑える、という方法よりも有益と思われる。

 

Section6:物体検知・セグメンテーション

【要点】

物体検知:

 画像の中から、物体の場所、種類、数を検知する技術。

 分類、物体検知、意味領域分割、個体領域分割などに分けることができる。

 ※それぞれのイメージは、確認テスト①を参照すること。

 

物体検知のデータセット

 VOC12、ILSVRC17、MS COCO18、OICOD18等、様々なデータセットが存在する。

 ※データセット:この場合、分類対象の画像や正解(ラベル)をまとめた物。

  同じデータセットに対する結果 = モデルの性能を客観的に比較できる。

  ただし、実務で使用するモデルを選ぶ際などは、用途に応じたデータセットに対する結果を参考にすること。

  例えば、オークションの画像(≒ 中央に1つの物体)を識別するために、

  自然の写真(≒ 様々な場所に様々な物体)に対する精度が高いモデルを使用しても、

  想定通りの精度は得られない。

 

評価指標:

 評価指標として、実際の結果(True or False) × 分析結果(True or False)の4パターンの

 要素が土台となる。以下は必ず覚える必要がある。 

f:id:you_it_blog:20211124230053p:plain

 

 クラス分類:

  出力は「~が存在する確率※(0~1の範囲)」となる。

  そのため、「~が存在すると断言する」閾値が変われば、同じモデルでも結果が変わる。

 物体検出:

  出力は「何が、どこに、どれくらいの確率※(0~1の範囲)で存在するか」となる。

  ※厳密には確率ではない・・。

 

物体検出の場合は、IoUという指標も評価に使用される。

一言で説明すると、「予測と実際の積結合 / 予測と実際の和結合」 の値。これも0~1の範囲となる。

 

FPS

 物体検知の場合、精度だけでなく速度も問題となる。

 例:分析に100ミリ秒等を要するモデルの場合・・

    定期的に物体の数を集計したい場合 → 十分な速度。

    自動運転で障害物を検知したい場合 → 遅すぎる。

 速度の指標として「FPS:Flames per Second」が存在する。

 一言で説明すると、「1秒間で何枚の画像を処理できるか」

 

物体検知のフレームワーク

 大分類すると以下の2つに分類できる。

  2段階検出器:

   候補領域の検出とクラス推定を別々に行う。高精度だが遅い。

   → まず画像から物体を抜き出し、その後物体を分類、というイメージ。

  1段階検出器:  

   候補領域の検出とクラス推定を同時に行う。精度が安定しないが早い。

   → 画像から物体の抜き出しと分類を同時に行うイメージ。

 

【確認テスト】

――①それぞれの物体認識タスクにおける出力は何か?――

f:id:you_it_blog:20211124224725p:plain

 

→分類:

  画像に対する単一or複数のラベル。

  例:風船、窓、木など。

 物体検知:

  各物体の範囲を示す四角形

  例:各風船を囲む四角形

 意味領域分割:

  各物体に対するピクセル単位のクラスラベル

  例:風船に対する色付け

 個体領域分割:

  各物体に対するピクセル単位のクラスラベル

  例:風船に対する色付け。なおかつ、風船ごとに異なる色を付ける。

    (各風船を区別する)

 

【実装演習】

実装演習が無いため、未実施。

代替として、資料に記載されている確認テストを一通り学習した。

 

【関連記事レポート】

物体検知のフレームワーク(YOLO)の情報

ichi.pro

――注目した部分――

CarND車両検出は、 Udacity自動運転車Nanodegreeプログラムのプロジェクトです。このプロジェクトの目的は、ダッシュカメラのビデオで車両を検出することです。この実装では、バッチ処理なしで21FPSを実現できます。

→ リアルタイム検知の重要性。例えば完全な自動運転の場合、

 ①物体検知(例:障害物がある)

 ②適切な処理の選択と実行(例:ブレーキペダルを押す)

 ③実際に動作が反映される(例:車が減速する) という流れになるが、

 「①物体検知」が一番ボトルネックになると思われる。自動運転の完全化には、物体検知の速度の向上が一番重要なのではないだろうか。(もちろん精度も重要)

 

以上

 

 

 

E資格の勉強⑤深層学習day3

目次

本投稿の目的

深層学習(day3)に関する学習のまとめ

Section1:再帰ニューラルネットワークの概念

【要点】

再帰ニューラルネットワーク

 時系列データに対応可能なニューラルネットワーク

 時系列データ=データに前後関係がある。例えばボードゲーム

 今の盤面は「直前(一手前)の盤面」の延長。さらに「直前(一手前)の盤面」は「直前(二手前)の盤面」の延長・・。

 この時系列を考慮するために、3つの重みを使用する。

 ①入力→中間層の重み。

 ②入力→出力層の重み。

 ③ひとつ前の中間層→中間層の重み。(ここがRNNの特徴)

 この3つの重みを時系列データの開始時点→終了時点まで再帰的に処理する。

 ※技術者的には「recursive neural network = RNN」と覚えるとよさげ。

 

BPTT:

 時間をさかのぼる誤差逆伝搬。

 といっても特殊な事ではなく、微分の連鎖率を使用して、

 「最後の時間の誤差」→「最後-1の時間の誤差」・・→「最初の時間の誤差」

 を何度も求めることなく少ない計算で求めること。

 

【確認テスト】

RNNのネットワークには大きくわけて3つの重みがある。

1つは入力から現在の中間層を定義する際にかけられる重み、

1つは中間層から出力を定義する際にかけられる重みである。

残り1つの重みについて説明せよ。

(回答)

 【要点】に記載した③の部分。ひとつ前の中間層→中間層の重み。

 

【演習チャレンジ:再帰ニューラルネットワーク

以下は再帰ニューラルネットワークにおいて構文木を入力として再帰的に文全体の表現ベクトルを得るプログラムである。ただし、ニューラルネットワークの重みパラメータはグローバル変数として定義してあるものとし、_activation関数はなんらかの活性化関数であるとする。木構造再帰的な辞書で定義してあり、rootが最も外側の辞書であると仮定する。(く)にあてはまるのはどれか。

(1)W.dot(left + right)

(2)W.dot(np.concatenate([left, right]))

(3)W.dot(left * right)

(4)W.dot(np.maximum(left, right))

 →答え:(2)。木構造のルートの右側と左側の一覧を全て抜き出し、結合したリストを活性化関数に使う。※「+」や「*」をしてしまうと、単語間の前後の繋がりを失ってしまう。

 

【演習チャレンジ:BPTT】

左の図はBPTTを行うプログラムである。

なお簡単化のため活性化関数は恒等関数であるとする。

また、calculate_dout関数は損失関数を出力に関して偏微分した値を返す関数であるとする。(お)にあてはまるのはどれか。

(1)delta_t.dot(W)

(2)delta_t.dot(U)

(3)delta_t.dot(V)

(4)delta_t* V

 →答え:(2)。過去にさかのぼるたびにUを掛ける必要がある。

 

【実装演習】

サンプルプログラムの実行結果。

①サンプルプログラムをそのまま実行。(中間層の活性化関数=シグモイド関数)

iters:0
Loss:1.4592344781314095
Pred:[1 1 1 1 1 1 1 1]
True:[0 1 1 0 1 1 1 0]
59 + 51 = 255
------------
iters:100
Loss:1.0581959125913671
Pred:[0 1 1 0 0 0 0 0]
True:[1 0 1 0 0 0 1 1]
47 + 116 = 96
------------
iters:200
Loss:0.8673602168782221
Pred:[0 1 1 0 0 0 1 0]
True:[0 1 0 0 0 0 1 1]
12 + 55 = 98
------------



------------
iters:9800
Loss:0.0012348486845701505
Pred:[1 1 0 0 0 1 0 1]
True:[1 1 0 0 0 1 0 1]
116 + 81 = 197
------------
iters:9900
Loss:0.0011690369308675372
Pred:[1 0 1 0 0 0 0 1]
True:[1 0 1 0 0 0 0 1]
120 + 41 = 161

→最終的に、誤差が0.001近くまで減少している。そして予測[Pred]と答え「True」が全て一致している(=正しく学習できている)。

 

②中間層の活性化関数をシグモイド関数 → ReLuに変更してみた。

iters:0
Loss:1.877133925079352
Pred:[0 0 0 0 0 0 0 0]
True:[1 0 0 1 0 0 1 1]
83 + 64 = 0
------------
iters:100
Loss:1.4036311687506768
Pred:[1 1 0 1 1 0 0 0]
True:[1 0 0 1 0 0 0 0]
104 + 40 = 216
------------
iters:200
Loss:1.0
Pred:[1 1 1 1 1 1 1 1]
True:[0 1 1 1 1 0 1 1]
6 + 117 = 255
------------



------------
iters:9800
Loss:2.0
Pred:[1 1 1 1 1 1 0 1]
True:[1 0 1 0 1 0 1 1]
117 + 54 = 253
------------
iters:9900
Loss:2.25
Pred:[1 1 1 1 1 1 0 0]
True:[0 1 1 0 0 0 0 0]
92 + 4 = 252
------------

→誤差が減っていない。最終的な精度も良くない。

 (=勾配の消失か発散が発生している?)

 誤差の推移を見た結果、大きな上下を繰り返している。

 勾配の消失?おそらく違う。消失なら、誤差が概ね一定になるはず。

 勾配が発散?おそらく当たっている。勾配爆発が発生していると考えられる。

(誤差の推移)
――――――――――――――――――――――――――

f:id:you_it_blog:20211107212139p:plain

――――――――――――――――――――――――――

 

Section2:LSTM

【要点】

RNNの課題:

 時系列が多い → 中間層が多い、という状態と同じ。

 →時系列が長いほど、初めの部分が出力層から遠くなる。

  →勾配消失問題が発生する。

   →活性化関数の変更や正則化などの対応と異なり、構造自体の変更で対応したものがLSTM。

 

LSTM:

 以下の部品を使用する。

  ・CEC勾配を1とした自己ループを行うゲート(勾配が1なら勾配は消失も発散もしない)

  ・入力ゲート、出力ゲート:CECの欠点(学習が行えない)に対応するため、設けられた層。

  ・忘却ゲート:CECが保持している情報の内、不要となった情報を削除するための層。

 

【確認テスト:RNNの課題】

シグモイド関数微分した時、入力値が0の時に最大値をとる。

その値として正しいものを選択肢から選べ。

(1)0.15

(2)0.25

(3)0.35

(4)0.45

 →答え:(2)。最大でも0.25なので、例えば3回さかのぼる場合、勾配は最大でも0.25^2≒0.0015まで小さくなる。

  中間層(RNNの場合時系列)が多いほど勾配が消えることが分かる。

 

【確認テスト:LSTM】

以下の文章をLSTMに入力し空欄に当てはまる単語を予測したいとする。

文中の「とても」という言葉は空欄の予測においてなくなっても影響を及ぼさないと

考えられる。このような場合、どのゲートが作用すると考えられるか。

「映画おもしろかったね。ところで、とてもお腹が空いたから何か____。」

 →答え:忘却ゲート。

 

【演習チャレンジ:RNNの課題】

RNNや深いモデルでは勾配の消失または爆発が起こる傾向がある。

勾配爆発を防ぐために勾配のクリッピングを行うという手法がある。

具体的には勾配のノルムがしきい値を超えたら、勾配のノルムをしきい値に正規化するというものである。

以下は勾配のクリッピングを行う関数である。(さ)にあてはまるのはどれか。

(1)gradient * rate

(2)gradient / norm

(3)gradient / threshold

(4)np.maximum(gradient, threshold)

 →答え:(1)。値が大きすぎる(ノルムを超える)場合、正規化されるという内容から推測できる。

 

【演習チャレンジ:LSTM】

以下のプログラムはLSTMの順伝播を行うプログラムである。

ただし_sigmoid関数は要素ごとにシグモイド関数を作用させる関数である。

(け)にあてはまるのはどれか。

(1)output_gate* a + forget_gate* c

(2)forget_gate* a + output_gate* c

(3)input_gate* a + forget_gate* c

(4)forget_gate* a + input_gate* c

 →答え:(3)。

 

Section3:GRU

【要点】

LSTMの課題:

 パラメータ数が多く、計算の負荷が高い。この課題に対応するための構造がGRU。

GRU:

 ゲート付き回帰ユニット。リセットゲート、更新ゲートと呼ばれる2つのゲートを持つ。(LSTMより1つゲートが少ない)

 LSTMと同等以上の精度、かつパラメータ(重み)の数を減らした構造。

 

【確認テスト:LSTMの課題】

LSTMとCECが抱える課題について、それぞれ簡潔に述べよ。

 →答え:

   LSTM:パラメータ数が多く、計算の負荷が高い。

   CEC:学習ができない。(結果、入力、出力ゲートが必要になる)

 

【確認テスト:GRU】

LSTMとGRUの違いを簡潔に述べよ。

 →答え:ゲート数が異なる。(LSTM:3ゲート、GRU:2ゲート)

     また、GRUの方が軽量である。

 

【演習チャレンジ】

GRU(Gated Recurrent Unit)もLSTMと同様にRNNの一種であり、

単純なRNNにおいて問題となる勾配消失問題を解決し、長期的な依存関係を学習することができる。

LSTMに比べ変数の数やゲートの数が少なく、より単純なモデルであるが、

タスクによってはLSTMより良い性能を発揮する。以下のプログラムはGRUの順伝播を行うプログラムである。

ただし_sigmoid関数は要素ごとにシグモイド関数を作用させる関数である。

(こ)にあてはまるのはどれか。

(1)z * h_bar

(2)(1-z) * h_bar

(3)z * h * h_bar

(4)(1-z) * h + z * h_bar

 →答え:4。新しい中間状態は、1ステップ前の中間表現と計算された中間表現の線形和で表現される。つまり更新ゲートzを用いて、(1-z) * h + z * h_barと書ける。

 

Section4:双方向RNN

【要点】

双方向RNN:

 双方向、つまり過去だけでなく未来の情報も考慮することで精度を向上させるモデル。文章の翻訳などに使用される。(文章の場合で説明すると、翻訳に「直前の文脈」だけでなく、「直後の文脈」も使用しよう、というモデル)

 

 

【演習チャレンジ】

以下は双方向RNNの順伝播を行うプログラムである。

順方向については、入力から中間層への重みW_f, 一ステップ前の中間層出力から中間層への重みをU_f、逆方向に関しては同様にパラメータW_b, U_bを持ち、両者の中間層表現を合わせた特徴から出力層への重みはVである。

_rnn関数はRNNの順伝播を表し中間層の系列を返す関数であるとする。

(か)にあてはまるのはどれか

(1)h_f + h_b[::-1]

(2)h_f * h_b[::-1]

(3)np.concatenate([h_f, h_b[::-1]], axis=0)

(4)np.concatenate([h_f, h_b[::-1]], axis=1)

 →答え:4。まず、「+」や「*」では前後の特徴が混ざってしまう。=concatenateを使用するべき。次に、「h_f(過去→未来)」のデータと「h_b[-1](未来→過去の反転)」のデータを結合するため、axis=1とする。これにより、例えば1,2,3というデータの場合、以下のような行列を作成できる。

 [1(過去→未来方向)、1(未来→過去方向)],

 [2(過去→未来方向)、2(未来→過去方向)],

 [3(過去→未来方向)、3(未来→過去方向)]

 

【参考】

引数(axis)のイメージ:

deepage.net

 

Section5:seq2seq

【要点】

seq2seq:

 Encoder-Decoderモデルの一種。以下2つの深層学習モデルで構成される。

  ・入力を中間表現(圧縮したベクトル)に変換(encode)するモデル(Encoder-RNN)。

  ・中間表現(圧縮したベクトル)を変換(decode) して出力を作成するモデル(Decoder-RNN)。

 

Encoder-RNN:

 入力(例えば、テキストデータ)を、単語等のトークンに区切って渡す。

 Taking:文章を単語等のトークン毎に分割し、トークンごとのIDに分割する。

 Embedding:上記のIDから、そのトークンを表す分散表現ベクトルに変換する。

Decoder-RNN:

 Encoder-RNNの個々の出力を受け取り、出力するデータを生成する。

 

seq2seqの課題:

 最終の入力に対する一問一答しかできない。それまでの文脈などが考慮できない。

 →HRED、VHRED、VAE等の会話モデルがある。

 

HRED:

 過去n-1の入力から次の出力を生成できる。

 →最終の入力が「はい」や「いいえ」でも、直前の入力から適切な出力が行える可能性がある。(seq2seqより人間らしいやり取りができる)

 →課題。同じ流れの会話には同じ回答しかできない。短い回答(Yes、No)などを選びがち。

 

VHRED:

 HREDに、VAEの潜在変数の概念を追加して、HREDの課題に対応したもの。

 

VAE:

 Variational Autoencoder(変動オートエンコーダー) 。

 データを潜在変数zの確率分布という構造に押し込めることができる。

 (以下のリンクを読むと分かる) 

qiita.com

 

【確認テスト:seq2seq】

下記の選択肢から、seq2seqについて説明しているものを選べ。

(1)時刻に関して順方向と逆方向のRNNを構成し、それら2つの中間層表現を特徴量として利用するものである。

(2)RNNを用いたEncoder-Decoderモデルの一種であり、機械翻訳などのモデルに使われる。

(3)構文木などの木構造に対して、隣接単語から表現ベクトル(フレーズ)を作るという演算を再帰的に行い(重みは共通)、文全体の表現ベクトルを得るニューラルネットワークである。

(4)RNNの一種であり、単純なRNNにおいて問題となる勾配消失問題をCECとゲートの概念を導入することで解決したものである。

 →答え:2。(1は双方向RNN。3は純粋なRNN。4はLSTM)

 

【確認テスト:VHRED】

seq2seqとHRED、HREDとVHREDの違いを簡潔に述べよ。

 →答え:

  seq2seqとHRED:seq2seqは一問一答。HREDは直前の入力を使用した出力が可能。

  HREDとVHRED:HREDは短い回答が多い。また、同じ流れの場合同じ回答。VHREDはVAEにてHREDの課題に対応する。

 

【演習チャレンジ:seq2seq】

演習チャレンジ機械翻訳タスクにおいて、入力は複数の単語から成る文(文章)であり、それぞれの単語はone-hotベクトルで表現されている。

Encoderにおいて、それらの単語は単語埋め込みにより特徴量に変換され、そこからRNNによって(一般にはLSTMを使うことが多い)時系列の情報をもつ特徴へとエンコードされる。

以下は、入力である文(文章)を時系列の情報をもつ特徴量へとエンコードする関数である。ただし_activation関数はなんらかの活性化関数を表すとする。

(き)にあてはまるのはどれか。

(1)E.dot(w)

(2)E.T.dot(w)

(3)w.dot(E.T)

(4)E * w

 →答え:1。Eは単語の埋め込みの一覧表(word embedding matrix)。単語ごとの特徴ベクトルが書かれた表のイメージ。この特徴ベクトルと重みを掛けた値を返せばよい。

 

【確認テスト:VAE】

VAEに関する下記の説明文中の空欄に当てはまる言葉を答えよ。

自己符号化器の潜在変数に____を導入したもの。

 →答え:確率分布z∼N(0,1)

 

Section6:Word2vec

【要点】

word2vec:

 文字は人間が作成した単なる記号であり、金額や色(RGBA)、物のサイズのような大小関係や連続性が無い = 文字のままではNNに使用できない。

 各単語をone-hotベクトル※に変換する必要がある。が、世界中の全単語をone-hotベクトルする事は物理的に不可能、かつ、one-hotベクトルでは単語の類似度などを把握できない。

 ※one-hot ベクトル:1つの成分が1、残りの成分は全て0のベクトル。

 word2vecは「単語の確率分布は、周辺の単語によって決定される」という分布の仮説に基づいて、単語をone-hotベクトルでないベクトルに変換する方法。

 

Section7:Attention Mechanism

【要点】

Attention Mechanism:

 sec2secは中間表現(圧縮したベクトル)を使用して出力を作成する。

 →中間表現(圧縮したベクトル)はサイズが決まっているので、入力が短い文章でも、長い文章でも使用できるベクトルの次元数は同じ。

  →長文に弱い。(表現を持ちきれない)

   →中間表現(圧縮したベクトル)を使用して出力を作成するタイミングで、元々の入力を参照できるようにする方法。

 

【確認テスト】

RNNとword2vec、seq2seqとAttentionの違いを簡潔に述べよ。

 →答え:

  RNNは時系列データに対応可能なニューラルネットワーク。処理対象だけでなく、処理対象の前のデータ(中間層の出力)も用いて、処理に使用する。

  ※直前~現在の流れを考慮した処理を行える。

  word2vecは文章(単なる人が作成した記号であり、NNで利用するにはベクトルに直す必要がある)をone-hot-ベクトルでなく、単語ごとの関連性を持たせたベクトルに変換する手法。

  seq2seq:Encoder-Decoderモデルの一種。2つのNNを持ち、文字に対する一問一答が可能である。

  Attention:seq2seqの課題(長文に弱い)に対応するために、seq2seqのDecoderへの入力として、「Encoderの成果物」に加えて、「入力」も使用して、入力データに柔軟なを可能とする

E資格の勉強④深層学習day2

目次

本投稿の目的

深層学習(day2)に関する学習のまとめ

Section1:勾配消失問題

勾配消失問題

【要点】

勾配消失問題:

 誤差伝搬法では、パラメータの更新量は「出力層 → 入力層」方向に計算していく。

 しかし、パラメータの更新量 = 傾きが0になる値を微分で求めるが、

 活性化関数に「シグモイド関数」を使用している場合、入力値が大きいと傾きがほぼ0になり更新量が消えてしまう。

 結果、階層(入力層に近い層)のパラメータが一切更新されなくなり、学習が止まってしまう。

 これが勾配消失問題。

 

【考察結果】

確認テスト1:シグモイド関数微分した時、入力値が0の時に最大値をとる。その値として正しいものを選択肢から選べ。

(1)0.15
(2)0.25
(3)0.35
(4)0.45

(回答)

 (2)0.25

(補足)

 シグモイド関数:f(x) = [1 / (1 + exp^x)]

 シグモイド関数微分:f'(x) = f(x)(1−f(x))

 → これにx=0を代入すると、0.5× (1-0.5) = 0.25

 数値の0乗 = 1になるため、簡単に計算できた。

 ※最大でも0.25と小さい。

  仮に、入力値が「5」の場合、微分結果は「0.00664・・」まで小さくなる。

  → パラメータの更新量がほぼ0となってしまう。

  

keisan.casio.jp

 

勾配消失問題の解決法

【要点】

複数の解決方法が存在する。

 ①活性化関数の選択:

  ReLu関数を使用する。

    入力が0以下 :0

    入力が0を超える:入力

   → 微分結果が大きくなるので、勾配消失を防止できる。

 ②重み(W)の初期値設定

  Xavier(ザビエル)を使用する。
   → 重みの要素を、前層のノード数の平方根で割った値

 ③バッチ正規化

  ミニバッチ単位で、データを正規化(最大1、最小0)する。

 

【考察結果】

確認テスト1:重みの初期値に0を設定すると、どのような問題が発生するか。簡潔に説明せよ。

(回答)

 重みの初期値に0を設定(正しく表現すると、重みに同じ値を設定する)と

  順準伝搬の結果が同一となる

   → 逆伝搬法による更新量も同一となる

    → 全く同じ動作をするノードが複数存在することになる。

     (ノードを多数持つ意味が無くなってしまう)

 

確認テスト2:一般的に考えられるバッチ正規化の効果を2点挙げよ。

(回答)

 ①ミニバッチごとに発生する入力データの差を抑制できる。

  →ミニバッチごとの学習のブレを(過剰や過少な学習)を防止できる。

   →学習の速度と精度の向上を期待できる。

 ②入力の分布によっては、勾配消失が発生する可能性がある。

  →入力データを適切な範囲に変換することで、適切な更新量を維持できる。

   →勾配消失問題の抑制。

(参考)

https://www.renom.jp/ja/notebooks/tutorial/basic_algorithm/batch_normalization/notebook.html

ichi.pro

 →考察:バッチ正規化の目的 = バッチごとにバラつく可能性がある入力を安定させて、学習も安定させてしまおう、という考え。

 

Section2:学習率最適化手法

【要点】

 学習率:

  更新量を反映させる際の割合。適切な値を設定する必要がある。

   学習率が大きすぎる場合:

    → 最適解にたどり着かない。

     ※ふり幅が大きすぎる振り子のイメージ。

   学習率が小さすぎる場合:

    → 最適解にたどり着つまでに時間を要する。局所最適解から動けなくなる。

      ※ふり幅が小さすぎる振り子のイメージ。

 

  → 基本的な方針として、学習率を動的にして、

    初めは大きく、学習が進むにつれて小さくする。

 

 学習率最適化手法:

  学習率を調整する方法。

   ・モメンタム(慣性):勾配降下法の調整に加えて、以下を加算する。

    → 絶対値[現在 - 前回の重さ] × 慣性(前回動いた分の慣性が働くイメージ)

   ・AdaGrad

   ・RMSProp

   ・★Adam★ ←最も主流の手法。モメンタムとRMSPropの長所を持っている。

 

【考察結果】

確認テスト1:モメンタム・AdaGrad・RMSPropの特徴をそれぞれ簡潔に説明せよ。

 (回答)

 ・モメンタム:

  学習率が一定。最適解に近づく時間が早い。大域的最適解に移動できる。

 ・AdaGrad:

  学習率が可変。モメンタムより事前設定必要なハイパーパラメータが少ないため、設定が容易。

  (モメンタム=学習率と慣性。AdaGrad=学習率のみ)

  学習が進むほど学習率が低下する。鞍点問題※の問題がある。

  ※馬の鞍のように、なだらかな地点(精度が上がる点が遠くにある)場合、

   学習を行えなくなる問題。(学習量が小さい → 精度が上がる点までたどり着けない → 学習できない)  

 ・RMSProp:

  学習率が可変。AdaGradを改善した物。

 

【演習】

SGD

(実行結果)

f:id:you_it_blog:20211020160552p:plain

→ 学習データ、検証データ共に精度が上がらない。

 

(実行結果※バッチ正規化あり)

f:id:you_it_blog:20211020162232p:plain

→ ある程度改善した。60%の割合で正解できる。

 

②momentum

(実行結果)

f:id:you_it_blog:20211020160816p:plain

→ 学習データ、検証データ共に精度が上がらない。

 

(実行結果※バッチ正規化あり)

f:id:you_it_blog:20211020162327p:plain

→ 大きく改善した。(90%近い精度)

 

③AdaGrad(momentumのアルゴリズムを基に作成してみた)

(作成したアルゴリズム)

for key in ('W1', 'W2', 'W3', 'b1', 'b2', 'b3'):

# ===========================================
# momentum
# ===========================================
# if i == 0:
# h[key] = np.zeros_like(network.params[key])
# h[key] = momentum * h[key] - learning_rate * grad[key]
# network.params[key] += h[key]
# ===========================================
# AdaGrad
# ===========================================
if i == 0:
h[key] = np.full_like(network.params[key], 1e-4)
else:
h[key] += np.square(grad[key])
network.params[key] -= learning_rate * grad[key] / (np.sqrt(h[key]))

(実行結果)

f:id:you_it_blog:20211020163238p:plain

→ 学習データ、検証データ共に精度が上がらない。

 

(実行結果※バッチ正規化あり)

f:id:you_it_blog:20211020162737p:plain

→ 大きく改善した。(80%の精度)

 

④RMSProp

(実行結果)

f:id:you_it_blog:20211020163152p:plain

→ バッチ正規化なしでも、非常に高い精度。

 

⑤Adam

(実行結果)

f:id:you_it_blog:20211020160459p:plain

→ バッチ正規化なしでも、非常に高い精度。

Section3:過学習

【要点】

過学習については、機械学習で学習済み。(忘れている場合、機械学習のレポートを参照する)

ここでは、「正則化 = 過学習を防止する方法」について、記載する。

 ・L1正則化、L2正則化
  誤差関数に各ノルムを加えて重みを抑える方法。ノルムは以下が参考になる。

  ※L1ノルム:ダイヤ型(マンハッタン距離)、L2ノルム:円(ユークリッド距離)と認識しておく。
manabitimes.jp

 

 ・ドロップアウト

  ノードをランダムに削除して学習させる。

  ※一般的には隠れ層(中間層)の場合は50%ほどのノードを無効化するとよい、とのこと。

sonickun.hatenablog.com

 

【考察結果】

確認テスト1:線形モデルの正則化の手法の中にリッジ回帰という手法があり、その特徴として正しい物を選択しなさい。

 (a)ハイパーパラメータを大きな値に設定すると、全ての重みが限りなく0に近づく。

 (b)ハイパーパラメータを0に設定すると、非線形回帰となる。

 (c)バイアス項についても、正則化される。

 (d)リッジ回帰の場合、隠れ層に対して正則加工を加える。

 

(回答)

 (a)ハイパーパラメータを大きな値に設定すると、全ての重みが限りなく0に近づく。

(考察)

 リッジ回帰(L2ノルム)のハイパーパラメータを大きくする → 罰則が大きい → 重みが小さくなる。

 

確認テスト2:下図について、L1正則化を表しているグラフはどちらかを答えよ。

f:id:you_it_blog:20211020225627p:plain

(回答)

 L1ノルム = マンハッタン距離なのでダイヤ型。答えは右の図。

 

【演習】

過学習が発生しているデータ。

 → 練習用データの精度は高いが、テスト用データの判定率が低い。

f:id:you_it_blog:20211020231127p:plain

 

②L2正則化

f:id:you_it_blog:20211020231301p:plain

 

③L1正則化

f:id:you_it_blog:20211020231412p:plain

 

ドロップアウト

パターン1:ドロップアウト割合=15%

 →比較的、適切に学習できるようになっているが、最終的に精度が乖離(≒過学習)となっている。

f:id:you_it_blog:20211020231458p:plain

 

パターン2:ドロップアウト割合=50%

 →全く学習が進んでいない。(ドロップアウトしすぎている)

f:id:you_it_blog:20211020233158p:plain

 

ドロップアウト + L1正則化

パターン1:ドロップアウト割合=8% かつ 正則化強度=0.004

 →L2正則化に近い形となっている。

f:id:you_it_blog:20211020231658p:plain

 

パターン2:ドロップアウト割合=12% かつ 正則化強度=0.006 (パターン1の1.5倍)

 →精度を上げ切れていない。正則化が強すぎると思われる。

f:id:you_it_blog:20211020233635p:plain

 

Section4:畳み込みニューラルネットワーク(CNN)の概念

【要点】

CNN:画像や動画認識で広く使われるモデル。以下のような構造を持つ。

 ・入力層→畳み込み層→プーリング層→全結合層→出力層

ja.wikipedia.org


※学習のターゲットとして、LeNetを題材としている。

ja.wikipedia.org

 

【各層の説明】

畳み込み層:

 3次元の空間画像も学習できるような層。

 出力 = 活性化関数(入力 * フィルター(≒重み) + バイアス)

 ★用語★

 バイアス:

  バイアス項と同じ。

 パディング:

  入力(中途半端なサイズ)を処理しやすいサイズに調整する。(埋める)

  調整分は0埋めか、周囲と同じ値などを設定する。

 ストライド

  フィルターの移動量。

 チャンネル:

  入力を判定するフィルターの数の様な物。異なる複数のフィルターを使用して、

  識別性能を向上させる。

 

プーリング層:

 入力(=畳み込み層の出力)から、特定の値を取得する。(最大値や平均値)

 単語の意味を把握すると覚えやすい。

 

 

※プーリング:統計学には「グループをたばねる」という意味。

toukeigaku-jouhou.info

 

【考察結果】

確認テスト1:サイズ6×6の入力画像を、サイズ2×2のフィルタで畳み込んだ時の出力画像のサイズを答えよ。なお、ストライドとパディングは1とする。

 (回答)

 5×5

 (イメージ)

以下の★部分が縦横1マスずつ動くイメージ。

――――――

★★〇〇〇〇

★★〇〇〇〇

〇〇〇〇〇〇

〇〇〇〇〇〇

〇〇〇〇〇〇

〇〇〇〇〇〇

――――――

 

【演習】

★畳み込み層★

・畳み込み層の実装

'''
input_data: 入力値
filter_h: フィルターの高さ
filter_w: フィルターの横幅
stride: ストライド
pad: パディング
'''
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
# N: number, C: channel, H: height, W: width
N, C, H, W = input_data.shape
out_h = (H + 2 * pad - filter_h)//stride + 1
out_w = (W + 2 * pad - filter_w)//stride + 1

img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))

for y in range(filter_h):
y_max = y + stride * out_h
for x in range(filter_w):
x_max = x + stride * out_w
col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]

col = col.transpose(0, 4, 5, 1, 2, 3) # (N, C, filter_h, filter_w, out_h, out_w) -> (N, filter_w, out_h, out_w, C, filter_h)

col = col.reshape(N * out_h * out_w, -1)
return col

 

・畳み込み層の使用

input_data = np.random.rand(2, 1, 4, 4)*100//1 # number, channel, height, widthを表す
print('========== input_data ===========\n', input_data)
filter_h = 3
filter_w = 3
stride = 1
pad = 0
col = im2col(input_data, filter_h=filter_h, filter_w=filter_w, stride=stride, pad=pad)
print('============= col ==============\n', col)

 

・出力

========== input_data ===========
[[[[77. 89. 22. 24.]
[51. 27. 81. 89.]
[87. 71. 64. 12.]
[12. 34. 17. 85.]]]

[[[20. 92. 53. 41.]
[66. 54. 6. 29.]
[ 3. 59. 64. 23.]
[18. 82. 92. 37.]]]]
============= col ==============
[[77. 89. 22. 51. 27. 81. 87. 71. 64.]
[89. 22. 24. 27. 81. 89. 71. 64. 12.]
[51. 27. 81. 87. 71. 64. 12. 34. 17.]
[27. 81. 89. 71. 64. 12. 34. 17. 85.]
[20. 92. 53. 66. 54. 6. 3. 59. 64.]
[92. 53. 41. 54. 6. 29. 59. 64. 23.]
[66. 54. 6. 3. 59. 64. 18. 82. 92.]
[54. 6. 29. 59. 64. 23. 82. 92. 37.]]

→入力 ※イメージ:4×4ピクセルの画像2枚の、赤の強さ(RGBのR)

→出力 ※イメージ:3×3のフィルタで入力を抜き出した結果。

 

★プーリング層★

・プーリング層の実装

def forward(self, x):
# FN: filter_number, C: channel, FH: filter_height, FW: filter_width
FN, C, FH, FW = self.W.shape
N, C, H, W = x.shape
# 出力値のheight, width
out_h = 1 + int((H + 2 * self.pad - FH) / self.stride)
out_w = 1 + int((W + 2 * self.pad - FW) / self.stride)

# xを行列に変換
col = im2col(x, FH, FW, self.stride, self.pad)
# フィルターをxに合わせた行列に変換
col_W = self.W.reshape(FN, -1).T

out = np.dot(col, col_W) + self.b
# 計算のために変えた形式を戻す
out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)

self.x = x
self.col = col
self.col_W = col_W

return out

 

★CNN全体★

※PCの性能が低いのでデータを大幅に削減する。

# 処理に時間のかかる場合はデータを削減
x_train, d_train = x_train[:50], d_train[:50]
# x_train, d_train = x_train[:5000], d_train[:5000]

x_test, d_test = x_test[:10], d_test[:10]
x_test, d_test = x_test[:1000], d_test[:1000]

 

Section5:最新のCNN

【要点】

AlexNet:

 2012年の画像認識コンテストで優勝したモデル。
 サイズ4096の全結合層の出力にドロップアウトを使用して、過学習を防止している。ja.wikipedia.org

 

【考察】

GPUを用いて高速な学習を実現している。とのこと。

→このあたりになると、単なる個人PCでは難しいと思われる。

※本Sectionのみ、確認テスト、実装なし。

 

E資格の勉強③深層学習day1

目次

1 本投稿の目的

深層学習(day1)に関する学習のまとめ

2 Section1:入力層~中間層

入力層 → 中間層 → 出力層

【要点】

入力層:

 ニューラルネットワークが入力を受け取る部分。

 任意の数の変数(ノード)を受け取る。(x1,x2,・・xN)と表現。

中間層: 

 入力層→出力層の間にある層。

 ※入力層からの最初の出力は中間層(1層目)が受け取る。

 この時、各変数に個別に設定された重み(w1,w2・・wN)を掛けた合計値(+バイアス項もある)を入力とする。

 入力に対して活性化関数を実施した値を、次の層(中間層or出力層)に渡す。

 

【考察結果】

確認テスト1:各変数に動物分類の実例を入れてみよう。

入力層:

 x1,x2,・・xN → 身長(cm)、体重(g)、耳の長さ(mm)。

中間層の入力:

 上記に各重み(w)を掛けた値の合計(総入力)

 ※ポイント:重みは要素の重要度に依存する。重要度(高)の要素ほど重みが大きくなる。

 

確認テスト2:以下数式をPythonで書け。

 W =[W1,W2,W3,W4]

 X =[W1,W2,W3,W4]

 u = W1X1 + W2X2 + W3X3 + W4X4 + b ← この数式(行列の掛け算+b)

 (回答)

import numpy as np
u = np.dot(x, W) + b # np.dot(行列のドット積)

 

確認テスト3:中間層の出力を定義しているソースを抜き出せ。

 (回答)

# 2層の総入力
u2 = np.dot(z1, W2) + b2

# 2層の総出力
z2 = functions.relu(u2)

 

【実装演習】

演習ソース

# 重み
W = np.array([
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6]
])

print_vec("重み", W)

# バイアス項
b = np.array([0.1, 0.2, 0.3])
print_vec("バイアス", b)

# 入力値
x = np.array([1.0, 5.0, 2.0, -1.0])
print_vec("入力", x)

# 総入力
u = np.dot(x, W) + b
print_vec("総入力", u)

# 中間層出力
z = functions.sigmoid(u)
print_vec("中間層出力", z)

 

実行結果

*** 重み ***
[[0.1 0.2 0.3]
[0.2 0.3 0.4]
[0.3 0.4 0.5]
[0.4 0.5 0.6]]

*** バイアス ***
[0.1 0.2 0.3]

*** 入力 ***
[ 1. 5. 2. -1.]

*** 総入力 ***
[1.4 2.2 3. ]

*** 中間層出力 ***
[0.80218389 0.90024951 0.95257413
 

→ 総入力 =「入力」と「重み(W)」のドット積 + バイアス項

 中間層出力 = シグモイド関数(総入力)

 となっている事を確認できる。

 ※シグモイド関数:入力を「0~1の範囲」の数値に変換する関数。後述するのでここでは詳しく記述しない。

 

3 Section2:活性化関数

入力層中間層 出力層

【要点】

活性化関数:値を非線形に変換する関数。出力を次の層に渡す前に使用する。

Section1で行っていた「 W1X1 + W2X2 + W3X3 + W4X4 + b・・」は線形の処理。これを線形の出力に変換する事が目的。

 

中間層で利用する活性化関数。

・ステップ関数(現在はほぼ利用されていない)

 ある一定の点を境に、出力が変わる関数。(0 or 1)

シグモイド関数

 数式:f(u) = 1/ (1+ e^-w)

 値を0~1の範囲に変換する関数。ネイピア数を使用しており、微分が容易にできる。

・ReLU関数

 ある一定の点を境に、出力が変わる関数。

  ある一点を満たしていない = 0

  ある一点を満たす = 0~1の範囲

 

出力層で利用する活性化関数。※「出力層の活性化関数」を参照。

・ソフトマックス関数

・恒等写像

シグモイド関数

 

【考察結果】

確認テスト1:線形と非線形の違いを図に書いて簡易に説明せよ。

 

線形:直線としてグラフに表示できる。

f:id:you_it_blog:20211012233852p:plain

非線形:直線としてグラフに表示できない。※厳密には「線形が満たす条件を満たしていない」もの。

f:id:you_it_blog:20211012234114p:plain

※グラフの作成には以下を使用した。

www.geogebra.org

 

確認テスト2:配布されたソースコードの該当する箇所を抜き出せ。

※活性化関数の使用箇所

 (回答)

y = functions.sigmoid(u2)

 

【実装演習】

演習ソース

# 重み
W = np.array([
[0.1, 0.2, 0.3],
[0.2, 0.3, 0.4],
[0.3, 0.4, 0.5],
[0.4, 0.5, 0.6]
])

# バイアス項
b = np.array([0.1, 0.2, 0.3])

# 入力値
x = np.array([1.0, 5.0, 2.0, -1.0])

# 総入力
u = np.dot(x, W) + b
print_vec("総入力", u)

# 中間層出力
z = functions.sigmoid(u)
print_vec("中間層出力", z)

 

実行結果

*** 総入力 ***
[1.4 2.2 3. ]

*** 中間層出力 ***
[0.80218389 0.90024951 0.95257413

→「総入力」と「中間層出力」の違いに注目。

 シグモイド関数により、値の大小関係を維持したまま、値が0~1の範囲に変換されている。

 

4 Section3:出力層

入力層 → 中間層 出力層

【要点】

出力層:

 最終的なデータを出力する層。

 「中間層の出力 → 次の層の入力に使用するための値」であるが、

 「出力層の出力 → 人間が使用したい値」

 分類問題の場合は、該当の分類である確率であったり、

 回帰問題の場合は、想定される値(数値) となる。

誤差関数:

 出力層の出力と、正解(ラベル)の誤差を比較する関数。

 ※学習で使用した誤差関数は二乗和誤差。全ての誤差を2乗したものの総和 / 2

出力層の活性化関数:

 中間層の活性化関数とは異なる。(中間層とは出力する値の使い方が異なるため)

・恒等写像

 回帰問題の場合に使用する。値を何も加工しない。

 ※ 確率などでなく、値を知りたい(出力させたい)ため、加工する必要が無い。

 使用する誤差関数は2乗和誤差。

シグモイド関数

 分類問題(2クラス)の場合に使用する。値を0~1の範囲に変換する関数。

 使用する誤差関数はクロスエントロピー

・ソフトマックス関数

 分類問題(3クラス)の場合に使用する。値を0~1の範囲に変換する、かつ全確率の総和を1とする関数。

 使用する誤差関数はクロスエントロピー

 

【考察結果】

★誤差関数について★

確認テスト1:なぜ、引き算でなく2乗するか。また、「/2」はどういう意味を持つか。

 (回答:2乗する理由)

 符号の違いの考慮を無くすため。2乗すると、値は2乗されが、ラベルと出力の純粋な距離を取得できる。

 (回答:「/2」する理由)

 誤差から重みとバイアス項を修正する(誤差逆伝搬)のときに、微分を簡単にするため。本質的な意味はない。

 

★活性化関数について★

確認テスト1:ソフトマックス関数の数式に該当するソースコードを示し、1行ずつ処理の説明をせよ。

(ソフトマックス関数の数式)

f:id:you_it_blog:20211013110236p:plain

※数式取得元は以下。

ja.wikipedia.org

(回答 ※「★」=追加した説明コメント)

# ソフトマックス関数
def softmax(x):
# ★:ミニバッチの場合(概ね実装は同じ)
if x.ndim == 2:
x = x.T
x = x - np.max(x, axis=0)
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T

# ★:ミニバッチ以外の場合
x = x - np.max(x) # オーバーフロー対策
# ★:np.exp(x) → 数式の分母にあたる部分
# ★:np.sum(np.exp(x)) → 数式の分子にあたる部分
return np.exp(x) / np.sum(np.exp(x))

 

★誤差関数について★

確認テスト1:交差エントロピーの式に該当するソースコードを示し、1行ずつ処理の説明をせよ。

(回答 ※「★」=追加した説明コメント)

def cross_entropy_error(d, y):
if y.ndim == 1:
d = d.reshape(1, d.size)
y = y.reshape(1, y.size)

# 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換
if d.size == y.size:
d = d.argmax(axis=1)

batch_size = y.shape[0]
# ★:重要なのは「-np.sum(np.log(y[np.arange(batch_size), d] + 1e-7))
# ★:y:ラベル(正解:1、不正解:0) dnnの出力
# ★:1e-7:対数関数の答が「-∞」になることを防止するための値。
# ★:最終的に値を「-」することでlogの「-」を正数に変換する。
return -np.sum(np.log(y[np.arange(batch_size), d] + 1e-7)) / batch_size

 

【実装演習】

演習ソース:

誤差関数(2乗和誤差)の実装

# 平均二乗誤差
def mean_squared_error(d, y):
return np.mean(np.square(d - y)) / 2

誤差関数を使用

# 入力値
x = np.array([1., 2.])
network = init_network()
y, z1 = forward(network, x)
# 目標出力
d = np.array([2., 4.])
# 誤差
loss = functions.mean_squared_error(d, y)
## 表示
print_vec("出力", y)
print_vec("訓練データ", d)
print_vec("誤差", loss)

実行結果

*** 出力 ***
[1.02 2.29]

*** 訓練データ ***
[2. 4.]

*** 誤差 ***
0.9711249999999999

→yとdの誤差量が「誤差」として出力される。

 

5 Section4:勾配降下法

入力層 → 中間層 → 出力層

入力層中間層 ← 出力層 ※重みやバイアス項の修正に関係する。

【要点】

勾配降下法:

 深層学習※のそもそも目的 → 学習結果を通じて、重さ(W)やバイアス項(B)を「最も誤差が発生しない値 = 傾きが0になる値」に修正すること。

 ※深層学習 = 層が4層以上存在するNN。= 中間層が2層以上存在するNN。

 勾配降下法は、重さ(W)やバイアス項(B)を修正するための方法。

  

学習率: 

 誤差を反映させるときの割合。適切な値に設定する事が重要。

  →大きすぎる場合:振り子を強く振ったように、振り幅がどんどん大きくなる =発散してしまう。

  →小さすぎる場合:振り子を弱く振ったように、振り幅は小さい(最適解にゆっくり近づく。)が、ふり幅が弱いと、「誤差が小さいが最適解でない場所(=局所解)」から動けなくなる可能性がある。

 

勾配降下法の種類:

確率的勾配降下法(SGD):

 エポックごとに、学習データから一部をランダムに選んで学習する。

 確率的勾配降下法は、このような事が無い。また、オンライン学習(後述の確認テストを参照)も利用可能。

・バッチ勾配降下法:

 全データを一括学習 → 誤差を一気に修正する方法。

 ※データの追加時、全データを再度使用する必要がある。

・ミニバッチ勾配降下法:

 バッチ学習と確率的勾配降下法(SGD)の混合のような手法。

 データを一定単位のミニバッチにまとめる。

 ミニバッチ単位で学習を行い、全ミニバッチの誤差の平均を用いて誤差を修正する。

 → バッチ勾配降下法は「1命令1データ」 = 並列実行が不可能であるが、

  ミニバッチ勾配降下法は「1命令複数データ」 = 並列実行が可能。

 

【考察結果】

確認テスト1:オンライン学習とは何か。2行でまとめよ。

(回答)

 学習データの追加時に、都度パラメータを修正して、学習する方法。

 ※全データを一気に使用するバッチ学習では行えない。(毎回全データを使用することになり、現実的でない)

 

確認テスト2:勾配降下法の以下数式の意味を図に書いて説明せよ。

「W(t+1) = W(t) - ε∇Et」

 

(回答)

※Wに関する説明なので、バイアス項(B)についての説明は省略している。

―――――――――――――――――――――――――

エポック|  重み

―――――――――――――――――――――――――

t   |  Wt →→↓

    |      ↓ - ε∇Et (※誤差×学習率 = 改善)

t+1 |  Wt+1  ← ※前回のWに改善を行った値=次エポックのW

・   |  ・

t+n |  Wt+n

―――――――――――――――――――――――――

※考察

 この説明については「超AI入門講座」の「スタートテスト(一般)」で見た記憶がある。万一分からない場合、「超AI入門講座」にて復習する事にする。

 

 

6 Section5:誤差逆伝搬法

入力層 → 中間層 → 出力層

入力層中間層 ← 出力層 ※重みやバイアス項の修正に関係する。

【要点】

数値微分で更新量を求めると、入力層側ほど、更新量を求めるのが大変。

出力層側の同じ計算を何回も行うことになる・・。

 

誤差逆伝搬では、一度求めた更新量を再利用して、更新量を簡単に、高速に求める事ができる。(微分の連鎖率を使用する)

※この説明については「超AI入門講座」で分かりやすい解説がある。

連鎖率はプログラム関係ない数学の知識。以下が参考になる。

※このサイトは数学に関して何かとお勧めである。

manabitimes.jp

 

 

 

 

【考察結果】

確認テスト1:誤差逆伝搬法では不要な再帰処理を避けることができる。既に行った計算方法を保持しているソースコードを抽出せよ。

(回答 ※「★」=追加した説明コメント)

# 誤差逆伝播
def backward(x, d, z1, y):
print("\n##### 誤差逆伝播開始 #####")

grad = {}

W1, W2 = network['W1'], network['W2']
# 出力層でのデルタ
delta2 = functions.d_sigmoid_with_loss(d, y) ★ここ。「delta2」★
# b2の勾配
grad['b2'] = np.sum(delta2, axis=0)
# W2の勾配
grad['W2'] = np.dot(z1.T, delta2)
# 中間層でのデルタ
delta1 = np.dot(delta2, W2.T) * functions.d_relu(z1) ★「delta2」を流用★

→delta2を流用して、中間層の更新量の取得に使用している。

 これにより、計算量を「層の数-1」に抑えることができる。

 単純な数値微分では、計算量は「(層の数+1) × 層数/2」になる。

 ※いわゆるガウスの足し算。

mosipro.com

 

確認テスト2:2つの空欄に該当するソースコードを探せ

①∂E/∂y  ∂y/∂u

(回答)

delta2 = functions.d_mean_squared_error(d, y)

 

②∂E/∂y  ∂y/∂u  ∂u/∂w2ji

(回答)

# W2の勾配
grad['W2'] = np.dot(z1.T, delta2)

 

→上記は微分の連鎖例なので「/」に注意。割り算でない。「a/b」→「aをbで微分した物」という意味。あとは、重み(W)とバイアス項(B)の微分を行う際、偏微分を行っていることに注意。(分からないなら、「超AI入門講座」を再確認する)

 

 

E資格の勉強②機械学習レポート

目次

1 本投稿の目的

機械学習に関する学習のまとめ

2 線形回帰モデル

【概要】

教師データありの回帰手法(回帰問題を解くためのモデルの1つ)

入力:m次元のパラメータ

出力:入力の線形結合※予測値は^(ハット)をつける。

パラメータの誤差は最小二乗法で推定する。

 

【ハンズオン】

ボストンの住宅データセットから住宅価格の最適な査定を行ってみる。

######################
# 線形回帰
######################
# モジュールをインポート
from sklearn.datasets import load_boston
from pandas import DataFrame
import numpy as np
from sklearn.linear_model import LinearRegression # 線形回帰モジュール

# データセットインスタンス
dataset = load_boston()
# print(dataset) # {'data': array([[6.3200e-03, 1.8000e+01],・・

# データフレーム作成
df = DataFrame(data=dataset.data, columns=dataset.feature_names)
df["PRICE"] = np.array(dataset.target)

######################
# パターン①線形単回帰分析(説明変数が1)
######################
# 説明変数(部屋数)と目的変数を設定
data = df.loc[:, ["RM"]].values
target = df.loc[:, ["PRICE"]].values

# 線形回帰インスタンス生成
model = LinearRegression()
# model.get_params() パラメータの確認
model.fit(data, target) # パラメータの推定

# 未知のデータを予測(部屋数1の価格は?)
print(model.predict([[1]]))
# [-25.5685118] → 価格が負数(明らかにおかしい) → 部屋数1という学習データが無いため予測ができない(外挿)

# 未知のデータを予測(外挿でない「部屋数6」の価格は?)
print(model.predict([[6]]))
# [19.94203311] → 妥当かもしれない価格を取得できた。

######################
# パターン②線形重回帰分析(説明変数が複数)
######################
# 説明変数(犯罪率と部屋数)と目的変数を設定
data = df.loc[:, ["CRIM", "RM"]].values
target = df.loc[:, ["PRICE"]].values

# 線形回帰インスタンス生成
model = LinearRegression()
# model.get_params() パラメータの確認
model.fit(data, target) # パラメータの推定

# 未知のデータを予測1(犯罪率0.3で部屋数4の価格は?)
print(model.predict([[0.3, 4]]))
# 4.24007956
# 未知のデータを予測2(犯罪率0.3で部屋数5の価格は?)
print(model.predict([[0.3, 5]]))
# 12.6311478
# → 部屋数が1つ増えると価格は急激に上昇。部屋数の方が重要度が高い?と思われる。

【ハンズオン後の考察】

外挿問題について、今回は「価格が負数」という分かりやすい問題となっていたが、

分析データによっては、外挿問題が発生していることに気付かない可能性もあると思われる。学習結果について、以下のような方法で検証が必要と思われる。

 ・正常と不正な出力の基準を明確にして、不正な結果が出力されないか。

 ・実務担当者による判定結果と比較して、想定外の差異が無いか。

 

 

【関連記事】

後述のロジスティック回帰は教師データありの分類手法。
回帰と分類の違いは、以下URLが分かりやすかった。

aiacademy.jp

 

3 非線形回帰モデル

【概要】

線形でない現象に対する回帰手法

入力、出力、パラメータの誤差:線形回帰と同様

汎化性能を失う過学習に注意する必要がある。(線形回帰も注意が必要)
過学習の防止にはいくつか手法があるが、オーソドックスなものは正則化法(罰則法)

 ・L2ノルムを利用したRidge推定量でパラメータを0に近づける

 ・L1ノルムを利用したLasso推定量でパラメータを0にする

過学習が発生する場合、汎化性能を失う→学習データ以外の分析精度が低下する。

 

【ハンズオン】

非線形のデータを適切に予測できるモデルを作成する。

######################
# 非線形回帰
######################
# モジュールをインポート
import numpy as np
import matplotlib.pyplot as plt
from sklearn.kernel_ridge import KernelRidge


def true_func(x):
return 1 - 48 * x + 218 * x ** 2 - 315 * x ** 3 + 145 * x ** 4


# データ(散布)生成
n = 100
data = np.random.rand(n).astype(np.float32)
data = np.sort(data)
target = true_func(data) # 非線形のグラフを作成
# 散布にノイズを付与
target = target + 0.5 * np.random.randn(n)

# データ(散布)を描画
plt.scatter(data, target, color='blue', label='data')
plt.title('NonLinear Regression')

# 非線形回帰(カーネルリッジ回帰)インスタンスを生成
clf = KernelRidge(alpha=0.0002, kernel='rbf')
data = data.reshape(-1, 1) # 2次元1列の配列への変形
target = target.reshape(-1, 1) # 2次元1列の配列への変形
# 学習
clf.fit(data, target)
p_kridge = clf.predict(data)

# 学習結果を描画
plt.plot(data, p_kridge, color='red', linestyle='-', linewidth=3, markersize=6, label='kernel ridge')
plt.legend()

plt.savefig("test.png")

作成した画像ファイルは以下の通り。
(非線形の分布にフィットしたグラフを作成できている!)

f:id:you_it_blog:20211005233937p:plain

 

【関連記事】

非線形回帰の理解には以下サイトがとっかかりとして良かった。

www.gixo.jp

 

4 ロジスティック回帰モデル

【概要】

教師データありの分類手法(分類問題を解くためのモデルの1つ)

※名称に「回帰」とついているが、分類手法。紛らわしい・・。

入力:数値とm次元パラメータの線形結合をシグモイド関数※に入力

   ※入力値を0~1の範囲の数値に変換する関数の一つ。

    シグモイド関数は1/( 1+exp ^-ax)。

    「a」を使用する場合、aが1以下で小さいほど、緩やかな出力となる。

出力:0 or 1の2択に対して1となる確率。コインの裏表や、~する、しない等。

誤差関数には尤度関数を使用する。

 

【ハンズオン】

タイタニック号の乗客の生存状況を学習して、特定の条件[男性、30歳]にて生存できるか確認する。

######################
# ロジスティック回帰
######################
# モジュールをインポート
import numpy as np
from sklearn.datasets import fetch_openml
from sklearn.linear_model import LogisticRegression

# sklearnに付属している実験用データセットを読み込む
# データセットについての説明:https://www.openml.org/d/40945
titanic = fetch_openml(data_id=40945, as_frame=True)

# 必要な説明変数を取得(2列目:性別 、3列目:年齢)
x = titanic.data.to_numpy()[:, [2, 3]]
# 性別を数値に変換する。(male1,female0)
x[:, 0] = (x[:, 0] == 'male').astype(float)
x = x.astype(float)

# 欠損値が存在しない添え字の一覧を取得
# 一覧 = ~[反転](性別が欠損している索引の一覧 or 年齢が欠損している索引の一覧)
idx = ~(np.isnan(x[:, 0]) + np.isnan(x[:, 1]))
# 説明変数を絞り込み。(欠損値が存在しない索引に絞り込み)
x = x[idx]
# 目的変数を取得(欠損値が存在しない索引を取得)
y = titanic.target.to_numpy().astype(float)[idx]

# インスタンスを生成
model = LogisticRegression()
# 学習
model.fit(x, y)
# 未知のデータを判定。(男性、30)
print(model.predict([[1, 30]]))
# →[0.] = 生存できない

 

【関連記事】
使用したデータセットに関する説明。

説明変数と目的変数についての説明や、データの分布を確認できる。

www.openml.org

 

5 主成分分析

【概要】

複数の変数を1つに変換する。(次元の圧縮)

正しく利用することで、以下を実現する事ができる。

 ・使用する変数を減らして計算を簡単にする。

 ・(2~3次元に圧縮できる場合)データの可視化(=図への変換)が可能となる。

 

変換する際、線形変換後の値の分散が最大となる軸を探索する必要がある。

※線形変換後に全く値が散らばらない軸を使用すると、

 変換した値による分析が不可能となる。

 

探索はラグランジュ関数を微分して行う。

【用語】

寄与率:線形変換後の値が元々の情報と比較してどれほどの情報量を持っているか。

累積寄与率:各主成分の寄与率を大きい順に足し込んだ値。

 

【ハンズオン】

乳がん検査データ(32次元)を2次元に圧縮する。

また、圧縮したデータで適切に判定を実施できるか確認する。

######################
# 主成分分析
######################
# モジュールをインポート
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

# 乳がんデータセットを読み込む
cancer_ds = load_breast_cancer()

df_target = pd.DataFrame(cancer_ds.target, columns=["target"])
df_data = pd.DataFrame(cancer_ds.data, columns=cancer_ds.feature_names)
df = pd.concat([df_target, df_data], axis=1)

# 必要な説明変数を取得(備考:列番号でなく列名でも取得できる)
# dfから「全行」かつ「mean radius」列以降の列の情報を取得
# このデータセット1列目がtargetなので、上記の絞り込みで、目的変数を除いた全ての説明変数を取得できる。
x = df.loc[:, "mean radius":]
# 目的変数を取得(今回は欠損値が存在しない前提)
y = df.target

# データの標準化(データの大小を異なる項目間で比較できるようにする)
# ※主成分分析はデータの標準化を必ず実施する※
# https://free.kikagaku.ai/tutorial/basic_of_machine_learning/learn/machine_learning_unsupervised
x = StandardScaler().fit_transform(x)
# データを学習用とテスト用に分割する(train_test_split:デフォルトでは25%がテスト用、75%が学習用となる)
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=0)

# 主成分分析のインスタンス生成
pca = PCA(n_components=2)
x_train_pca = pca.fit_transform(x_train)

# 主成分の寄与率は以下で確認可能。
# print(pca.explained_variance_ratio_)
# → [0.43711585 0.19513199]
# 第一成分で元データの43.3%、第二成分で元データの19.5%の情報を持っている。累積寄与率は62.8%

# 主成分分析した結果を図で確認してみる。
# 結果をデータフレーム化
df_pca = pd.DataFrame(x_train_pca, columns=["PC{}".format(x + 1) for x in range(2)])
# データフレームに解析結果も追加(主成分分析は教師なし学習であるが、今回は色分けするため追加)
df_pca['Outcome'] = y_train.values

# 目的変数ごとに色分けして描画するため、分割する。
malignant = df_pca[df_pca['Outcome'] == 0] # 悪性データ
benign = df_pca[df_pca['Outcome'] == 1] # 良性データ
# 描画
plt.scatter(x=malignant['PC1'], y=malignant['PC2'], label='malignant', c='r', marker='x', alpha=0.5)
plt.scatter(x=benign['PC1'], y=benign['PC2'], label='benign', c='b', marker='x', alpha=0.5)
plt.legend()
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.savefig("aa.png")

描画結果は以下。概ね正しく分類できていると判断できる。
※かたよらずに混ざっている場合、分類が正しく実施できていないと判断する。

f:id:you_it_blog:20211009000447p:plain


さらに、主成分分析の結果を利用したクラスタリングを行う。
(主成分分析の目的はこれ。次元を減らして終わり・・ではない)
k平均法(k-means clustering)を使用する。

from sklearn.cluster import KMeans

# クラスター数は2(悪性、良性)
model = KMeans(n_clusters=2)
# クラスタリング
y_pred = model.fit_predict(x_train_pca)
# データフレームにクラスタリング結果を追加。
# 乳がんデータセットの目的変数は「0:悪性、1:良性」。KMeansの実行結果は「0:良性、1:悪性」なので、値を反転させた物を追加する。
df_pca['Outcome_pred'] = y_pred
df_pca['Outcome_pred'] = df_pca['Outcome_pred'].map({1: 0, 0: 1}).astype(int)

# 正解と学習結果を描画して目で確認する。
# ※主成分分析を用いてクラスタリングした結果と、正解データを描画する。今回は教師データが存在するため可能。
pred_kmeans_1 = df_pca[df_pca['Outcome_pred'] == 0]
pred_kmeans_2 = df_pca[df_pca['Outcome_pred'] == 1]
# 教師データを基にしたデータを描画(色付きの「×」を描画)
plt.scatter(x=malignant['PC1'], y=malignant['PC2'], label='malignant', c='r', marker='x')
plt.scatter(x=benign['PC1'], y=benign['PC2'], label='benign', c='b', marker='x')
# クラスタリングの結果を描画
plt.scatter(x=pred_kmeans_1['PC1'], y=pred_kmeans_1['PC2'], label='Ir1', c='b', alpha=0.5)
plt.scatter(x=pred_kmeans_2['PC1'], y=pred_kmeans_2['PC2'], label='Ir2', c='r', alpha=0.5)
plt.legend()
plt.xlabel('PC 1')
plt.ylabel('PC 2')
plt.savefig("aaa.png")

描画結果は以下。概ね正しく分類できているが・・境界付近に誤りがある。
※「□」と「×」の色が異なる部分が誤り。

ただ、一定の精度を保ったまま32次元 → 2次元まで圧縮できたため効果はある。

f:id:you_it_blog:20211009094859p:plain



【関連記事】

分かりやすい説明が記載されている。

一読すると、主成分分析をよく理解できた。

logics-of-blue.com

qiita.com

 

 

6 アルゴリズム_1(k近傍法-KNN)

【概要】

教師有り学習の分類手法。

識別対象データを受け取った際、識別対象データに最も近い(最近傍)のデータをk個取得。取得したk個のデータの分類を集計して、最も多い分類を返す。

例:k=3の場合

 ①識別対象データの最近傍を3個取得。

 ②「分類A:2個、分類B:1個」の場合 → 識別対象データの分類はAである、と判定する。

 ※「①」で取得するデータを、事前に学習させておく必要がある。

 

上記の通りなので、kの値が変われば結果が変わる。

kが増えるほど、取得する最近傍のデータが増えるため、識別結果は平均的になる。

言い換えるならば、kが増えるほど、識別範囲の境界線が滑らかな線になる。

 

【ハンズオン】

人口のデータ(と仮定したデータ)を分類する。
まず、学習データの作成。

######################
# k近傍法(KNN)
######################
# モジュールをインポート
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats


# 訓練データ生成処理(乱数なので、結果は毎回変わる)
def generate_data():
# 説明変数生成
x0 = np.random.normal(size=50).reshape(-1, 2) - 1 # 分類A
x1 = np.random.normal(size=50).reshape(-1, 2) + 1 # 分類B
# 作成した説明変数を結合
x = np.concatenate([x0, x1])
# 目的変数を生成して結合
y = np.concatenate([np.zeros(25), np.ones(25)]).astype(np.int)
return x, y


# 訓練データの作成 + 作成したデータの描画(確認のため)
x_train, y_train = generate_data()
plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train)
plt.savefig("aa.png")

 

k近傍法に最適そうなデータを作成できた。

f:id:you_it_blog:20211009165234p:plain

次に、予測を行ってみる。(見やすくするため、判定の境界も描画する)
①numpyでの実装

# 距離を計算する関数(2乗するので符号の考慮が不要となる)
def distance(x1, x2):
return np.sum((x1 - x2) ** 2, axis=1)


# 予測処理
def knc_predict(x_train, y_train, X_test):
y_pred = np.empty(len(X_test), dtype=y_train.dtype)
for i, x in enumerate(X_test):
distances = distance(x, x_train)
nearest_index = distances.argsort()[:3] # 練習としてk=3を使用する。
mode, _ = stats.mode(y_train[nearest_index])
y_pred[i] = mode
return y_pred


# 結果を描画する関数
def plt_resut(x_train, y_train, y_pred):
xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
# 散布図を描画
plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train)
# 塗りつぶし2次元等高線図を描画。(判定の境界を確認できる)
plt.contourf(xx0, xx1, y_pred.reshape(100, 100).astype(dtype=np.float), alpha=0.2, levels=np.linspace(0, 1, 3))
plt.savefig("aaaa.png")


xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
x_test = np.array([xx0, xx1]).reshape(2, -1).T

y_pred = knc_predict(x_train, y_train, x_test)
plt_resut(x_train, y_train, y_pred)

f:id:you_it_blog:20211009165540p:plain

 

②scikit-learnでの実装

from sklearn.neighbors import KNeighborsClassifier

xx0, xx1 = np.meshgrid(np.linspace(-5, 5, 100), np.linspace(-5, 5, 100))
xx = np.array([xx0, xx1]).reshape(2, -1).T
knc = KNeighborsClassifier(n_neighbors=3).fit(x_train, y_train) # 練習としてk=3を使用する。
plt_resut(x_train, y_train, knc.predict(xx))

f:id:you_it_blog:20211009170019p:plain

※結果に差異があるが、これはそもそもの教師データ(ランダム値)が実行の度に変わるため。教師データが同じであれば、結果も同じとなる。

 →scikit-learnの利便性が高いことを実感できる。

 

7 アルゴリズム_2(k平均法-K-mean)

【概要】

教師なし学習の分類手法。

受け取ったデータをk個のクラスタに分類する。

 

【処理の手順】

以下を、収束(= 結果が変化しなくなる)するまで繰り返す。

 ①各データからクラスタの中心となるデータを設定する。(初回はランダム)

 ②各データを最も距離の近いクラスタに分類する。

 ③分類したクラスタの平均ベクトル(中心)を計算する。

 ④クラスタの中心を更新して、再度①~③を行う。

 

【ハンズオン】

「主成分分析」で使用したため省略する。

 

8 SVM(サポートベクターマシン)

【概要】

2クラス分類問題の代表的な手法の1つ。

→回帰問題や教師なし学習でも応用されている。

※ここでは、線形分類をハンズオン対象とするが、

 カーネル関数と呼ばれる関数を用いることで、非線形の分類も可能。

 

【用語】

マージン最大化:

 分類問題なので、「k近傍法」に記載した図のように、分類の境界となる線が発生する。この線とデータの距離をマージンと呼び、マージンが大きいほど、適切な境界が設定できている。SVMでは、このマージンが最大となる境界を探す。この考え方をマージン最大化と呼ぶ。

ハードマージン:

 分類を完璧に識別できる境界が設定可能、という前提の分類。

ソフトマージン:

 分類を完璧に識別できない(誤差がある)、という前提の分類。

 ※現実としては、全ての情報を完璧に分類できる、という事はありえない。

 ソフトマージンにおける誤差を表す変数を「スラック変数」と呼び、

 誤差を最小化したうえで、マージンが最大となる境界を探す。

サポートベクトル:

 境界に最も近いデータのこと。SVMはマージンが最大となる境界を探すため、

 境界から離れているデータは、境界作成に全く影響しない。(あっても無くても結果に影響しない)

 境界に最も近いデータの = 境界の決定に使用されるデータをサポートベクトルと呼ぶ。

 

【ハンズオン】

アヤメの分類(2クラス分類)を行う。

######################
# SVM
######################
# モジュールをインポート
from sklearn import datasets, svm
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

# データセットの読み込みhttps://scikit-learn.org/stable/datasets/toy_dataset.html#iris-dataset
iris = datasets.load_iris()

# 説明変数は最初の2つのみを取得(がく片の長さ、がく片の幅)
# ハンズオンのために結果を2次元の図で出力するため。
x = iris.data[:, :2]
# 目的変数の取得
y = iris.target

# 2:iris virginica」以外のインデックスを取得(データセット3クラス。実施する分類は2クラス分類のため)
idx = (iris.target != 2)
# 2:iris virginica」以外のデータのみに絞り込み
x = x[idx]
y = y[idx]

# SVMインスタンス生成
clf = svm.SVC(C=1.0, kernel='linear')
# データに最適化フィット
clf.fit(x, y)

# 背景色を利用して、分類と境界を描画する
# グラフの表示エリアの取得(説明変数の最大+1 と 最小-1の範囲とする)
x1_min = min(x[:, 0]) - 1
x1_max = max(x[:, 0]) + 1
x2_min = min(x[:, 1]) - 1
x2_max = max(x[:, 1]) + 1

# グリッド情報の作成。
# mgrid:格子状の配列を作成。500jなので、500×500の要素数となる、
xx, yy = np.mgrid[x1_min:x1_max:500j, x2_min:x2_max:500j]

# グリッド情報を並べなおす(np.c_:配列を結合する。ravel():配列を1次元に変換する)
xg = np.c_[xx.ravel(), yy.ravel()]

# 各グリッドの点の分類結果の予測をZに格納
z = clf.predict(xg)

# グリッド情報を並べなおす
z = z.reshape(xx.shape)

# 分類ごと塗りつぶしに使用する色の設定
cmap = ListedColormap([(0.5, 1, 1, 1), (1, 0.93, 0.5, 1)])

# 背景の色を表示
plt.pcolormesh(xx, yy, z == 0, cmap=cmap)

# 軸ラベルを設定
plt.xlabel('sepal length')
plt.ylabel('sepal width')

Xc0 = x[y == 0] # 目的変数;0のデータ
Xc1 = x[y == 1] # 目的変数;1のデータ

# 目的変数;0のデータを描画
plt.scatter(Xc0[:, 0], Xc0[:, 1], c='#E69F00', linewidths=0.5, edgecolors='black')
# 目的変数;1のデータを描画
plt.scatter(Xc1[:, 0], Xc1[:, 1], c='#56B4E9', linewidths=0.5, edgecolors='black')

# サポートベクトルを取得
SV = clf.support_vectors_

# サポートベクトルの点を赤枠で囲む(可視化のため)
plt.scatter(SV[:, 0], SV[:, 1], c='black', linewidths=1.0, edgecolors='red')

# 描画したグラフを表示
plt.savefig("ii.png")

f:id:you_it_blog:20211010102259p:plain

作成された境界と、境界の決定に使用されているサポートベクトルを確認できる。

 

 

 

E資格の勉強①応用数学レポート

目次

1 本投稿の目的

応用数学に関する学習のまとめ

2 線形代数(行列と固有値)

【行列】

行列の使い方として以下がある。(もちろん、その他の用途もある)

  • 大量の連立方程式をシンプルに表現する
    (行列の掛け算を理解すると、この意味が分かる。)

また、以下のような行列特有の専門用語があるので、覚える必要がある。

  • 単位行列(普通の数値における1。
    「X × 1 = X」と同様、掛け算しても結果を変えない行列で1と0で構成される。

さらに、行列の計算は手法を覚える必要がある。

  • 行列同士の足し算、引き算
    → 行列のサイズが同一であれば、単なる足し算、引き算で算出可能。
  • 行列同士の掛け算
    → 直行表のようなイメージで、全パターンの掛け算を加算していく。
     これは練習して確実に理解する必要がある。
  • 行列 → 通常の数値の変換
    → 左斜めに掛け算 - →右斜めに掛け算 がベースで、3×3ならたすき掛けが必要。

固有値

行列のn乗を簡単に求めるために必要となる。

※厳密には、固有値の一覧 = 対角行列と固有ベクトルを使用することで、

 行列の累乗を簡単に求める事ができるようになる。
 対角行列の累乗は各数値をn乗する、という簡単な方法で計算できるため。

 

行列に対して固有値分解(書籍により対角化とも記載されている)

を行うことで、累乗式に必要な以下を取得できる。

なお、正方行列でない場合は特異値分解、という手法で求める必要がある。


【補足:参考資料】

全体的に、以下の資料がとても参考になった。
★行列を知らない人のための線形代数学入門 - 広島大学

http://www.math.sci.hiroshima-u.ac.jp/m-mat/TEACH/senkei-daisuu.pdf

 

3 確率・統計

条件付確率が、特に注意が必要。

解説:

 ①PA(B) = P(B|A) = 事象Aが発生した世界で、事象Bが発生する確率※

 ②P(B∩A) = AとBが同時に発生する確率

 →①②は別の意味であるので注意。

※各順番が逆じゃない?と思うが、英語ベースで考えるとこの順番になる。
 (日本語と異なり、主語がとにかく先頭にくる形式)

その他、以下の用語がある。

  • 期待値(期待される値の平均)
  • 分散(実際の値と期待値の差を2乗したもの、2乗するのは±の考慮を無くすため)
  • 標準偏差(分散を√したもの。2乗 = 単位自体が変わるため、それを解消する)


【補足:参考資料】
条件付確率の参考

https://ousar.lib.okayama-u.ac.jp/files/public/6/60999/20201203115534771574/bgeou_175_027_037.pdf

 

ベイズ統計の考え方については、以下の本が参考になった。
※数時間読めば、図ベースで、条件付確率が理解できるようになる。

www.diamond.co.jp

 

4 情報理論

【自己情報量】

「-log(p(x))」という公式を始めてみたが、実際に問題を考えてみると意味が良く分かった。確率は0~1の範囲になるので、p(x)の値はほぼ分数になる。分数は累乗に直すと-n乗になるので答えが正数になる。かつ、値が小さければ小さいほど(-n乗のnが大きいほど)最終的な値(その情報の価値)が大きくなる。

【シャノンエントロピー

自己情報量の期待値。誤差関数の中身として使う、という事もできそう。

【カルバック・ライブラー・ダイバージェンス

想定していた確率分布と、実際の確率分布の違いを表すことができる。

ダイバージェンス <> 距離。

ダイバージェンスは距離と呼ぶには一部の定義を満たせていない。

ここでもΣは使用するので、Σは非常に重要。

【公差エントロピー

KLダイバージェンスの一部分。Qに対する情報をP(現実)の分布で平均する。

 

全て、公式を覚えておく(意味も理解する)はもちろん、自己情報量以外も実際に計算してみて、解いてみる必要があると思われる。


以上

E資格の勉強を始めてみる

目次

1 本投稿の目的

E資格の勉強を始めてみる。その経緯を記載する。

2 自分について
  • 資格は色々持っている(高度試験3つ、情報処理安全確保支援士試験合格)
  • 数学は高卒レベル。プログラム(Python)は1年ほど個人で経験あり。
3 学習を始めようとした理由

昨年、奇跡的にITストラテジストプロマネに合格できたので、次を考えていた。
そこで、自社の雰囲気を見てみると、AIの知識を求めいている雰囲気があった。
→AIについて何か資格を取っておけば、今後何か評価が上がるのでは?、と感じた。

4 学習方法(予定) 

以下オンリーで対策してみる。

ai999.careers


E資格の受験対象となる講座を色々確認してみたが、
最安でも5万円近くかかる。(165,000円 × 専門実践教育訓練にで70%戻る)

しかし、これなら、上手くいけば35,000円くらいで済む。[登録20,000円 + 月額3,000円×5カ月]

値段が安い分、自分で色々調べる必要があるみたいだが・・頑張ってみよう。

 

5 計画と目標

2021年9月1日:学習開始

~12月末:修了認定テストを通過。

2022年2月:試験を受験。できれば一度で合格したい・・。

 

6 その他

数学の知識が無いので、調べながら進める。

その過程で、役立つサイトなどがあれば忘備のため追記していく。

 

 

7 数学の資料

行列

www.mext.go.jp

 

条件付確率

https://ousar.lib.okayama-u.ac.jp/files/public/6/60999/20201203115534771574/bgeou_175_027_037.pdf

記号の解説:

 ①PA(B) = P(B|A) = 事象Aが発生した世界で、事象Bが発生する確率

 ②P(B∩A) = AとBが同時に発生する確率

 →①②は別の意味であるので注意。

覚えておくべき英単語を文章付きでまとめる。

udemyで英語の講座を受けた時に気付いた、
「意味を覚えておくべき単語」をまとめておく。

【英文】
Starting in DTR 2.6, you should perform a backup before switching storage drivers. This ensures that your images will be preserved if you decide to switch back to your current storage driver.


Docker Performance Improvement
stackify.com

ensure docker is not running or delete
www.edureka.co


【英単語】
impose
 意味:何かを課す。
 由来:上に(in-)置く(pono)。
 覚え方:人の机に書類を置いて、「これやっとけよ」と強いる。
gogen-ejd.info

expose
 意味:公開する。
 由来:外に(ex-)置く(pono)。
 覚え方:由来そのまま。
gogen-ejd.info

区間和(更新無し)の最大値(abc183_d)

概要

区間和(更新無し)の最大値を求める方法を、図で解説する。
※加算、減算を同時に行える。

解説図

以下の様な区間の最大値を求める。

f:id:you_it_blog:20201121101623p:plain

1.全探索(ダメなパターン)

処理量がO(nw)
→(問題の制約的に)最大で20万×20万・・・とても間に合わない。

2.累積和を使う

「要素が変わるタイミング」は以下の通り。
f:id:you_it_blog:20201121102023p:plain
これを1つの配列(変動表)にまとめて・・
f:id:you_it_blog:20201121102559p:plain
累積和を求める。
f:id:you_it_blog:20201121102633p:plain
→最大値は「7」と分かる。
この方法なら処理量はO(n+w)。最大で20万+20万なので、問題なく回答できる。

包除原理(abc178_c)

概要

知識不足で包除原理の解説が難しかったので、図で解説する。

問題

atcoder.jp

解説図

答えの式

f:id:you_it_blog:20201101101608p:plain

1.初期イメージ

f:id:you_it_blog:20201101103803p:plain
ベースはこれ。

2.加算:全パターン(10^n)。

f:id:you_it_blog:20201101103817p:plain
全パターンを+1。

3.減算:0を含まないパターン(9^n)f:id:you_it_blog:20201101103834p:plain

「0を含む」以外のパターンを-1。

4.減算:1を含まないパターン(9^n)

f:id:you_it_blog:20201101103857p:plain
「1を含む」以外のパターンを-1。

5.加算:0と1を含まないパターン(8^n)

f:id:you_it_blog:20201101103909p:plain
「0を含む」「1を含む」以外のパターンを+1。

6.結果

f:id:you_it_blog:20201101103921p:plain
「0を含む」かつ「1を含む」パターンだけ算出できた。
(そのほかの部分は0なので除外できている)

未経験で合格:ITストラテジスト(2019年秋期)

結論

  • 未経験でも合格可能。(1回落ちた)
  • 勉強時間は約300時間。
  • 午後2は運も影響する。何回か受けて当たりを待つべきかも。

目次

1.自分について

1.1 本投稿の目的

ITストラテジストに合格したので、勉強方法などの備忘録。

1.2 自分について
1.3 受験理由

自己研鑽+合格して会社でどや顔したかったため。 

2.勉強

2.1 午前1

応用情報技術者試験の過去問(午前1)を実施。

3年分実施して平均70%を取れるようにする。

※おそらくこれだけでOK。

2.2 午前2

ITストラテジストの過去問(午前2)を実施。

過去6~7年分実施して、回答内の全用語を把握する。

※毎年いくつか新出問題があるが、おそらく6割は過去問を流用(?)

 しているので、これでOK。専門書等は読まなくて良い。

2.3 午後1(大変)

ITストラテジストの過去問(午後2)を実施。

過去5年分を実施して、「なぜ、この設問に対する回答がこれになる」かを、

設問->問題文(システム改善後の運用)->問題文(システム改善前の課題)の順にトレース。

※正攻法(先頭~末尾まで読む、回答を1つずつ解く)では時間が足りない。

 パズルゲー感覚で問題文から回答を逆引きする必要がある。

 回答は問題文中にある場合が大半なので、専門書等は読まなくて良い。

2.4 午後2(超大変)

これが問題。調査が必要。以下、私が調査した情報。

  • 論述対象にする業界の特徴、規模(私の場合はアパレル業界)
  • システム開発の大まかな予算、期間、効果。
    ※各ベンダーの導入事例や日経クロステックで調べた。

以上を調べた後、過去問を何点か実施。以下3種類の論文を準備した。

  • 全体システム化計画
  • 個別システム化計画
  • 経営戦略の立案

これで本番を望むだけだが・・、午後2は運要素が強い気がする。

  • 突如、不意打ちのような問題が出題されることがある。
     平成24年度:事業継続計画の制定
     平成26年度:クラウドコンピューティング導入方針
     平成30年度:新技術と業務システムによる新サービス
     →全過去問の論文を準備しても(おそらく不可能だが)対応できない。
      ※その代わり、該当の実務経験がある人には、非常に有利。

  • 前提が合わず、準備した論文が流用できないことがある。
     平成27年度:グローバルな事業
     →「グローバル」システムの論文のみ流用できる。
      「国内向け」システムの論文は流用できない。

問題に対応した実務経験or事前対策が必須だが、

なにせ範囲が広い。自分にとっての当たりが出るまで受験が必要かもしれない。

 

3.受験

3.1 結果確認

点数は以下の通り。

f:id:you_it_blog:20191220230938p:plain


→午後2、準備した「個別システム化計画」の論文が当たった。

 ※準備したのは「AI活用事例」を元にした論文。これ以外なら落ちたはず。
 また、数十文字足りなかったかも・・!!と思っていたが合格した。

 最後まであがいたのが功を奏したかもしれない。

4.最後に

午後2の準備に注力しすて、足元を掬われないよう注意が必要。

合格した結果だけ書いているが、実は2018年度は午前2で落ちている。

→午後2は採点すらされなかった。100時間以上を無駄にした。

 

以上。

未経験で合格:kintone認定 アソシエイト

結論

  • 未経験でも合格可能。
  • 勉強時間は13時間。→適切かも。
  • 通常は15,000円かかるが、無料受験バウチャーで0円。

目次

1.自分について

1.1 本投稿の目的

kintone認定 アソシエイトに合格したので、勉強方法などの備忘録。

1.2 受験前の知識
  • ワークフローソフトの利用経験あり
  • kintoneに関する実務経験=0
1.3 受験理由

Cybozu Days 2019 -モンスターへの挑戦状-に参加後、以下キャンペーンに気付く。

→「試験無料バウチャー」をプレゼント。これを見て受験を決定。

 

2.勉強

2.1 試験対策テキスト(約10時間)

目的:基礎知識の取得。回答の練習。

以下の本を購入し、2周読み込む。 

読むときの準備

  1. kintone(キントーン)- 30日間無料お試しを登録。
    分かりづらいところは実際に叩いてみるのが一番。
  2.  Associate(アソシエイト) | kintone 認定資格の種類についてを読む。
    「出題範囲」は必ず読む。
    「XX年XX月時点のバージョンに対応しています。」という記載を確認する。
  3. kintone(キントーン)- 主なアップデートを読む。
    いわゆるリリースノート。
    ※以下の差異を把握するために必要※
     ・実試験:「出題範囲」に記載されたバージョン
     ・試験対策テキスト:出版時点(?)のバージョン 
     ・30日間お試し環境:おそらく最新のバージョン 

    上記を把握しないと、「試験対策テキスト」や「30日間お試し環境」の知識で
    回答して間違えるリスクがある。

2.2 kintoneヘルプ(約3時間)

目的:基礎知識の取得。

以下を読み込む。

 

「細かな制限」や「試験対策テキストに記載されていないが重要な点」を読む。
受験後の感想だが、以下だけで合格できたかも、と感じた。

  • ヘルプを全部読む
  • 試験対策テキストのサンプル問題を解く(サンプル問題以外は飛ばす)

3.受験

3.1 受験
  • 当日申込できる試験会場もある。
  • 受験後、すぐ結果が分かる。

→40分で全問回答。合格。

3.2 結果確認

点数は以下の通り。

f:id:you_it_blog:20191219233235p:plain
→合格ラインは不明だが、ちょうど良い点数かもしれない。
 過学習を回避できた気がする。

4.最後に

kintoneの感想として「とにかく操作が簡単」と感じた。

競合他社に務めるエンジニアが調査を兼ねて学習しても良いかもしれない。

 

以上。

英文の勉強方法(備忘録)

本ページは、英語の勉強法の備忘録。

思いついたことをひたすら追記していく。

 

 

1.「読み」「聞き」の練習+文法を覚える

1.英語の教科書(小学生低学年向け)

以下を読む+ヒアリングを行う。

 

2.「読み」の練習+語彙を増やす

以下サイトの好きな文章を読み込む。

1.システム系の英文

AWSの新機能説明(AQUA)

  • if you系(If you look This means that even if you removed・・)

2.英文全般

海外のこども向けニュース(テクノロジ関連)

 

3.注意点

1.勉強していて眠たくなる時

教科書を見る+聞くだけでは眠たくなる。

小さくでも良いので、声に出して読み進めると眠くならない。

 

2.分からない単語を調べる方法

思考に日本語を入れない(英語とイメージだけで考える)ことが重要?と思っている。
そのため、単語は以下で調べて、英語で考える。

→どうしても分からないなら、最終手段 = 英和辞典サイトで調べる。

 

英語の勉強を始める。

結論

  • 目標:英語のドキュメントやフォーラムを読めること
  • アメリカの小学生向けの本で学習する。
  • 2020年3月末に成果を発表する。

目次

1.なぜ英語を勉強するか

理由:日本語ベースの情報収集に限界を感じた。
前回のブログで「Solutions Architect – Professional」に合格した事を書いたが・・

日本語が無い公式ドキュメントが非常に多い。
以下に何度苦しめられたか・・f:id:you_it_blog:20191128151648p:plain

また、試験本番は日本語で受験できるが、若干日本語が怪しい。

※ググってもらえれば色々事例が出てくると思う。

AWSに限らず、ドキュメントは日本語、フォーラムは英語主体のサービスも多い。

例:Aspose

→という事で、英語は重要と考えた。

2.現在の英語力

ほぼ0に近い。
TOEICを受けたことないが、きっと100点とかのレベル。

3.どう勉強するか

以下を参考に、「英語圏の小学生が使う教科書」を使う事にした。

 

以下の最新版を購入。eBook付で、音声も聞けるらしい。

Basic Grammar in Use Student's Book with Answers and Interactive eBook: Self-study Reference and Practice for Students of American English

Basic Grammar in Use Student's Book with Answers and Interactive eBook: Self-study Reference and Practice for Students of American English

 

→これを読み込む。 とりあえず3周。

 

2020/3/8のTOEICに申し込みしたので、3月末に受験結果を記載する。

 

以上。

未経験で合格:AWS認定 ソリューションアーキテクトプロフェッショナル

結論

  • 未経験でも合格可能。
  • 勉強時間は150時間。→過剰だったかも。
  • 受験費が高い(最低30,000円。バウチャー利用で15,000円)。

目次

1.自分について

1.1 本投稿の目的

SAP(ソリューションアーキテクト – プロフェッショナル)に合格したので、

3年後の再認定に備えた備忘録。

1.2 受験前の知識
1.3 受験理由

AWSからオンラインカンファレンスのメールを受け取る。

→「模擬試験無料バウチャー※」をプレゼント。

 これを見て受験を決定。

 ※ソリューションアーキテクト – プロフェッショナル限定

2.勉強

2.1 Jayendra's Blog(約30-40時間)

目的:基礎知識の取得。

以下の全リンクを読む。

読み方は・・

  • 関連リンクをひたすら追っていく。
  • 英語なのでGoogle翻訳
    ⇒翻訳不備は公式ドキュメントを読んで対応。
  • 適時日本語を修正して進めるので、なかなか辛い。
  • 日本語化した資料をまとめる。私はOneNoteを使用した。
2.2 サンプル問題(約100-120時間)

目的:実際の問題を読んで回答できるか確認。

実際の問題文と回答は非常に長い。3~5行とか。

数を積んで、速く正確に答えるテクニックを身に着ける必要がある。

→問題集で対策することにした。以下、見つけた問題集。
 ※全て有償。宣伝目的でないので価格は未記載。

  1. SAP-C01 Practice Exams※Jayendra's Blogが推奨

  2. Udemyの問題集

  3. AWS WEB問題集で学習しよう

→「1」だけ購入した。(半額セールで2,500円だったため)

 

以下の通り勉強を進めた。

  • 70問を実施(2.5時間)。
  • 復習。全ての正解、不正解を理解する。(10-15時間)
    AWSドキュメントで確認して、未記載ならAWSで検索

→上記を6セット。これが一番大変だった。

2.3 模擬試験の実施(約1.0時間)

目的:合格する可能性の確認。

以下ページの「試験のスケジュールを立てる」から、模擬試験を受験。

  • 後で復習するため、全問題キャプチャする。
  • 2回受験したが、半分ほど同じ問題。1回だけで十分と思われる。
  • 受験後、点数が通知される。
    ※相変わらず個別の正否を教えてくれない。つらい。

70~80点だったが、模擬試験は実際と採点方法が違うとのこと。   

 Q:模擬試験と実際の認定試験は同じ方法で採点されますか?
 A:模擬試験は正解率に基づいて採点されます。
   例えば、20 問中 16 問が正解だった場合、スコアは 16/20 または 80% です。
   実際の認定試験のスコアは、100~1000 点のスコアで示されます。

3.受験

3.1 受験
  • 当日申込できる試験会場もある。
  • 受験後、すぐ結果が分かる。

→2時間で全問回答。疲れたので見返さずにテスト終了して・・合格。。
 合否がその場で分かるのはありがたい。

3.2 結果確認

数日後、点数を確認したところ・・

f:id:you_it_blog:20191127123340p:plain

→880点。高得点だが、過学習だった。問題集をざっと読むだけで十分かも。

4.最後に

試験の費用は非常に問題。

  • 模擬試験・・ 4000円 + 税
    →バウチャー利用で無料
  • 試験  ・・ 30000円 + 税
    →バウチャー利用で半額

→模擬試験で点数が低い場合、再勉強した方が良いかも。
 

誰かの参考になれば、うれしいです。 

以上。