#Level8.深層学習 DAY4
##8-1.Section1) TensorFlowの実装演習
●TensorFlowについて
•実務ではTensorFlowを活用することが多く、スクラッチで実装することは少ない。
•TensorFlow、Keras、Pytorchの順。
•TensorFlowはgoogleが作ったディープラーニングのフレームワークで、
調べる際もTensorFlowが多い。
●実装「constant」
•TensorFlow ではテンソルというものを利用する。
•Session.run() で起動しないと中身も確認できない。
●実装「placeholder」
・placeholderは、箱のようなものを用意している。
・placeholderは後から値を自在に変更できる。
・feed_dictで配列のx番目の要素を渡す。
⇒xをバッチに渡して実行するときなどに使用する。
●実装「variables」
・a = tf.constant(10)と定義するとaに10を設定する。
・x = tf.Variable(1)後々に値を変えて更新できる。
⇒「calc_op = x * a」「update_x = tf.assign(x, calc_op)」
で値を更新している。
・init = tf.global_variables_initializer()は、
変数を初期化する。
###8-1-2 線形回帰の実装演習
●matplotlibのjitterの仕様(1度目にプロットできない)
matplotlibの下にinlineを書いてあげる。
●コード
・iters_num ・・・何回学習するか。
・plot_interval ・・・10回ごとに結果を表示する。
・n = 100
x = np.random.rand(n)
d = 3 * x + 2 ・・・100個のランダムなxを用意し、3*x+2の値を作る。
・xは直線の値のため、noiseを加える。
⇒上下にまばらな値ができる。
・train = optimizer.minimize(loss) ・・・誤差を最小化する学習。
・loss = tf.reduce_mean(tf.square(y - dt)) ・・・回帰二乗誤差
・sess.run(train, feed_dict={xt:x_train,dt:d_train})
・・・trainを読み出し、feed_dictでx_train、d_trainを渡していく。
・W_val:[3.0194452]、b_val:[1.9318823]となっており、
d = 3 * x + 2のW:3とb:2に近い予測値になっている。
●Tryの確認
・noiseの値を変更しよう
・dの数値を変更しよう
noiseに0.55、bに9を設定する。
⇒W:[3.0428321]、b:[8.961408]と予測された。
その他変更して試したが、noiseが大きいと上手く回帰できない。
☆考察☆
•noiseによるデータの作成で、直線上からどの程度ノイズを発生させるのか、
実際のデータがない時に一般データとの差を考えるのも難しいと感じた。
•Wとdがきちんと予測されると面白い。
###8-1-3 非線形回帰の実装演習
●非線形な一直線でない式を予測する。
●コード
・「d = -0.4 * x ** 3 + 1.6 * x ** 2 - 2.8 * x + 1」
非線形な解を作成している。
・Wが-0.4、1.6、-2.8、1と4つあるため、
WのVariableのoshapeを[4,1]と定義。
・optimizer = tf.train.AdamOptimizer(0.001)に変更している。
・[[-0.3990355]
[ 1.6032437]
[-2.8051274]
[ 1.0001277]] ・・・4つのWがきちんと予測できている。
●Tryの確認
・noiseの値を変更しよう
・dの数値を変更しよう
noiseを0.35にしてみた。
⇒[[-0.36423665]
[ 1.6244664 ]
[-2.8141403 ]
[ 0.96930456]] ・・・4つのWはほぼ予測ができている。
dを変更してみる。
「d = 0.4 * x ** 3 + 2.8 * x ** 2 - 2.8 * x + 10」
⇒[[ 0.31515315]
[ 3.8476086 ]
[-2.596497 ]
[ 7.5793443 ]] ・・・ちょっと厳しかったようだ。
☆考察☆
•noiseを大きくしても線形回帰と比べてあまり分散しなくなるようだ。
•dは線形回帰と比べても極端に予測がズレない。4つのWで複雑な非線形になると、
平均二乗誤差の収束は難しくなるが、線形回帰より大きく外れないと思った。
●Tryの確認
次の式をモデルとして回帰を行おう
$𝑦=30𝑥^2+0.5𝑥+0.2$
誤差が収束するようiters_numやlearning_rateを調整しよう
☆考察☆
・iters_numを30000~35000回くらいに設定しないと収束しなかった。
データ作成数を増やすなど、様々な試行錯誤は必要だと感じた。
「optimizer = tf.train.AdamOptimizer(0.01)」を0.001⇒0.01にする差が大きい。
⇒iters_numは25000回くらいで十分だった。
###8-1-4 分類1層(mnist)
●MNISTの分類
手書き文字のデータセットで、28×28×白黒データで1チャンネル。
0~9のどの数字かを予測する。
●Tryの確認
次の式をモデルとして回帰を行おう
・x:入力値, d:教師データ, W:重み, b:バイアス をそれぞれ定義しよう
・内容を確認する。
①x_batch[0]
②d_batch[0]
③x_batch[0].shape
④plt.imshow(x_batch[0].reshape(28,28))
☆考察☆
詳細はもう少し復習して深堀してみるが、
1層で出力のsoftmax関数が出力する0~9の分類が87%の精度はすごいなと感じた。
###8-1-5 分類3層(mnist)
●MNIST1層より精度を上げる。
・hidden_layerを2つ用意する。
・784(入力)⇒600、600⇒300⇒10(個の出力)のニューラルネットワーク
・隠れ層があるのでWやbを3つずつ用意。
・TensorFlowでは毎回Variableを定義する必要がある。
・Wが3つある場合:W1,W2,W3と、b1,b2,b3と定義する。
・出力の前にドロップアウトしており、汎化性能を上げるため、
あるニューロンを消している。
「drop = tf.nn.dropout(z2, keep_prob)」
●Tryの確認
隠れ層のサイズを変更してみよう(600、300)
optimizerを変更しよう
☆考察☆
修正前の状態で90%となった。dropout_rate=0としたら91%となったが、
過学習になってしまってのかもしれない。
隠れ層のサイズを半分にしたところ、87%と精度が落ちた。
逆に800、500と増やすと91%と少し向上する。増やせばいいものだろうか。
⇒増やすと学習に時間がかかるようになった。
optimizerは、AdaGradを試してみた。
最終的な精度は90%だが、途中からの伸びが良かった。
講義と同じように全種類試した。
###8-1-6 分類CNN(mnist)
●Conb×pool×Conb×poolで、
affin×dropout×affinという構造。
・1層目でreshapeにより28×28×1チャンネルの画像として処理。
・W_conb1は5×5×1×32というウェイト
5×5:CNNのフィルターサイズ
1×32:1チャンネルのものを32チャンネルに拡張する
・padding='SAME':shapeが変わらないようなpaddingを用意する。
☆考察☆
ドロップアウト率が0.5の時は、93%の精度だった。
ドロップアウト率を0にしたら、精度が91%と落ちた。
ただ、90~96%をふらふらしており、学習モデルとしては安定していない印象。
x_batchでトレーニングデータを渡したもので、汎化性能は不明。
テストデータの場合、ドロップアウトさせた方が精度があがる。
###8-1-7 論文から実装する
●画像認識の最新モデルを実装するには?
・VGG
・AlexNet
・GoogLeNet
・Resnet
・Yolo
⇒・VGG16でarxivと検索するとarxivのサイトにて論文を参照でき、
サイトから無料で手に入る。
・ABSTRACTを読む→ARCHITECTUREを見る。
RESULTで精度がどうなったか確認する。
・表とかテキストで実装した組み合わせなどがまとめられている。
・VGGはブログの記事になっているものもある。
・コードがGitHubに載っているので参考にする。
・AlexNet等でもアーカイブがあり、構成図を参照したりする。
「pytorch AlexNet」のように検索する。
・ResnetはDeep Residual Learning for Image Recognitionで、
他と同じようにアーカイブがある。
・最新のものでなければ、既にあるものから実装する。
・物体認識(Yolo)もPDFで提供されているが、
再現実装するのは大変だったりする。
●例題3つ目
正解は(a)
●例題4つ目
正解はあ:(a)、い:(a)、う:(a)
☆確認テスト☆
・8-1-8-1 VGG・GoogLeNet・ResNetの特徴をそれぞれ簡潔に述べよ。
【自分の回答】
VGG:16層と19層の構造のバージョンがある。勾配消失問題がある。
GoogLeNet:22層の構造。Inceptionモジュールが特徴。
ResNet:152層の構造。VGGの勾配消失問題を解決。
【解答】
VGG:最も古くて2014年のモデル。Convolution、Convolution、max_poolという
単純なネットワークの積み重ねで出来ている。パラメータ数が多い。
GoogLeNet:Inception moduleを使ているのが特徴。1×1の畳み込みの次元削減。
ResNet:スキップコネクションアイデンティモジュールを使うことで残差接続を行い、
深い学習ができるという特徴。
###8-1-9 Keras1
●Kerasについて
•TensorFlowのラッパーである。
•初心者でも簡単に記述できる。
•複雑なことを行う場合、TensorFlowを書かなければいけない。
●Tryの確認
np.random.seed(0)をnp.random.seed(1)に変更
エポック数を100に変更
AND回路, XOR回路に変更
OR回路にしてバッチサイズを10に変更
エポック数を300に変更しよう
☆考察☆
単純なOR回路でもバッチサイズやエポック数によっては、
正解率が100%にならないことがある。XOR回路は、
ハイパーパラメータを変更してもロスが減らず不正解がある。
OR回路は非線形のため、1層ではうまくいかない。
●実装実習「分類(iris)」
●Tryの確認
中間層の活性関数をsigmoidに変更しよう
SGDをimportしoptimizerをSGD(lr=0.1)に変更しよう
ソースの修正が必要だった。
# from sklearn.cross_validation import train_test_split
⇒from sklearn.model_selection import train_test_split
# plt.plot(history.history['acc'])
# plt.plot(history.history['val_acc'])
⇒plt.plot(history.history['accuracy'])
⇒plt.plot(history.history['val_accuracy'])
☆考察☆
sigmoid関数だと勾配消失を起こすので、
ReLU関数の汎化性の良さはわかるが、irisデータだと分かりづらい。
複雑なデータを扱った際に、それぞれ検証してみようと思う。
###8-1-10 Keras1
●実装実習「分類(mnist)」
●Tryの確認
load_mnistのone_hot_labelをFalseに変更しよう (error)
誤差関数をsparse_categorical_crossentropyに変更しよう
Adamの引数の値を変更しよう
☆考察☆
model.compileの指定方を修正しないと、上手く動作しなかった。
コーディングのいけないところは、じっくり再確認する予定。
one_hot_labelの設定と、誤差関数をsparse_categorical_crossentropy、
categorical_crossentropyの指定方については間違えないようにする。
●実装実習「CNN分類(mnist)」
☆考察☆
確かに処理に時間かかることが確認できた。
padding=SAMEした時の動作比較検証は地道だが面白そう。
多層のconvolutionについてもサイズを変更して確認してみる。
●実装実習「cifar10」
☆考察☆
50000枚のトレーニングデータ、10000枚のテストデータで、
カラーの画像をRGBのため255で正規化している。
割愛であるが、処理時間とコードの内容確認のため実施してみた。
動画のように枚数を絞って実行すればよかった・・・。
●実装実習「RNN」
2進数足し算の予測
Keras RNNのドキュメント https://keras.io/ja/layers/recurrent/#simplernn
●Tryの確認
RNNの出力ノード数を128に変更
RNNの出力活性化関数を sigmoid に変更
RNNの出力活性化関数を tanh に変更
最適化方法をadamに変更
RNNの入力 Dropout を0.5に設定
RNNの再帰 Dropout を0.3に設定
RNNのunrollをTrueに設定
☆考察☆
※BGMがうるさ過ぎて解説の声がすごく聞きづらい。。。
KerasでRNNの実装はすごく楽である。
sigmoidは精度が出ない。状況に応じて使い分けるのは計算させてみてだろうか。
RNNの出力活性化関数をtanhにしたところ、直ぐに収束し精度が良い。
KerasならsimpleRNNから様々なRNNのネットワークに切替えが可能。
Kerasは容易に扱える印象であるが、やはりTensorflowで組めるようにしておきたい。
##8-2.Section1) 強化学習
###8-2-1 強化学習とは
●強化学習とは
長期的に報酬を最大化できるように環境の中で行動を選択
できるエージェントを作ることを目標とする機械学習の一分野。
⇒行動の結果として与えられる利益(報酬)により、
行動を決定する原理を改善していく仕組み。
教師あり学習や教師なし学習とは違った分野。
・マーケティングの応用例
プロフィールと購入履歴からキャンペーンメールを顧客に送付するソフト。
行動:顧客ごとに送信、非送信の行動を選択。
報酬:キャンペーンのコスト(負の報酬)、
生み出されると推測される売り上げ(正の報酬)を受ける。
☆確認テスト☆
・8-2-1-1 強化学習に応用できそうな事例を考え、
環境・エージェント・行動・報酬を具体的に挙げよ。
【自分の回答】
環境:コンビニ等の共通したポイントカード導入箇所
エージェント:ポイントの蓄積・ポイント利用の履歴により、
利用者還元セールやポイント10倍Dayなどを開催する。
行動:顧客のポイントカード利用履歴から、ポイントを還元する、
通常よりポイントを上乗せしてもよいか選択する。
報酬:ポイント還元・上乗せによる負の報酬と、
還元セールや上乗せにより購入が増えると推測される正の報酬。
【解答(例)】
ゲームやボードゲーム
プレイヤーが指す手についての強化学習
###8-2-2 探索と利用のトレードオフ
●探索と利用のトレードオフ
環境について事前に完璧な知識があれば、
最適な行動を予測し、決定することは可能である。
⇒どの顧客にキャンペーンメールを送付すると、どの行動するか既知である。
(そんなことはそうそうない。)
⇒強化学習の場合、そのような仮定は成り立たないとする。
不完全な知識を元に行動しながらデータ収集し、最適な行動を探索する。
●問題になるのは・・・
探索と利用のトレードオフである。
「過去のデータで、ベストとされる行動のみを常に取り続ければ、
他にもっとベストな行動を見つけることができない。」
(探索が足りない状態)
↑
トレードオフの関係性
↓
「既知の行動のみ常に続ければ、過去の経験が活かせない」
(利用が足りない状態)
どちらの状態も良くなく、トレードオフを上手く調整することが必要。
###8-2-3 強化学習のイメージ
●強化学習のイメージ
エージェントがある方策を実施して行動した状態sとなる。
⇒それを観測し、状態sの報酬価値を受け取る。
という流れ。
●関数
方策:方策関数 Π(s,a)で表される。
行動や価値V:行動価値関数 Q(s,a)で表される。
###8-2-4 強化学習の差分
●強化学習と、通常の教師あり/教師なし学習との違い
【結論】目標が違う
・教師あり/なし学習では、データに含まれるパターンを見つけ出す、
及び、そのデータから予測することが目標
・強化学習では、優れた方策を見つけることが目標
###8-2-5 強化学習の歴史
●強化学習について
冬の時代があったが、計算速度の進展により大規模な状態を持つ場合でも、
強化学習を可能としつつある。⇒ AlphaGo など
●Q学習
行動価値関数を、行動するごとに更新することで学習を進める方法
●関数近似法
価値関数や方策関数を関数近似する手法のこと
###8-2-6 行動価値関数
●行動価値関数とは
価値を表す関数としては、状態価値関数と行動価値関数の2種類がある。
⇒ある状態の価値に注目:状態価値関数
状態と価値を組み合わせた価値に注目:行動価値関数
●Q学習
行動価値関数を行動のたびに更新することで学習している。
###8-2-7 方策関数
●方策関数とは
方策ベースの強化学習手法において、
ある状態でどのような行動を採るのかの価値を与える関数のこと。
⇒この状態であれば、この行動をとる確率が◎◎%といったもの。
###8-2-8 方策勾配法
●方策反復法
方策をモデル化して、最適化する手法
$θ^{(t+1)}=θ^{(t)}+ε∇J(θ)$
●Jとは
方策の良さである。
⇒定義しなければならない。
●定義方法
・平均報酬:行動をとった時に生まれる価値全部の平均
・割引報酬和:カッコになればなるほど報酬の加算する割合を減らす(減衰)
⇒定義に対応して、行動価値関数 Q(s,a)の定義を行い、
方策勾配定理が成り立つ。
$∇_θJ(θ)=\mathbb{E}_{π_θ}[(∇_θlogπ_θ(a|s)Q^π(s,a))]$
⇒Q関数を使って上記のように定義している。
●例題解説
正解は(a)
方策をアップデートするのが方策勾配に基づくアルゴリズムである。
方策勾配定理は基本的には下記の2式から導出される。
・状態価値関数 v(s) = sum_a (π(a|s)Q(s,a))
・ベルマン方程式 Q(s,a) = sum_s’(P(s’|s,a)[r(s,a,s’) + γV(s’)]
###8-2-9 論文解説DCGAN
●DCGAN
・Deep Convolutional Generative Adversarial Networksという名前。
・CNNのディープなネットワークを使って敵対的学習により画像を生成する。
・例として、実際に存在しないベッドルームの画像をきれいに出力している。
・潜在空間でベクトルとして表現したものからGenerator部分の画像を生成するため、
「笑顔の女性の顔」から「普通の女性の顔」を引いて、「男性の顔」を足し合わせる。
⇒「笑顔の男性の顔」を数式的に扱うことができる。
・Generatorの生成部分はランダムな100個の正規分布の値を使って画像生成している。
⇒生成画像と実際の画像を比較し、Discriminatorというモデルが、
その画像が作られたものかを判定する。
###8-2-10 Kaggleについて
●Kaggle
・データ分析のコンペティション
・データ分析・AIにおいての世界大会のようなものである。
・Googleが運営している。
・企業等が賞金を出している。
・日本人でも上位に入るチームがある。
・Kaggleへの登録方法。サイトに行けば登録できる。
・コンテスト参加迄の一連の流れ
・Researchが研究目的。
・Featuredが賞金があるコンテスト。
・titanicやmnistなどの初心者向けのコンペがある。
(データセットが有名なため、不正が発生?順位があてにならない)
・Kernelsで世界のデータサイエンティストの実装を参照できる。
・参加した後の流れ
よさそうなスコアのものや説明を読んだり、コピーして動かしてみたり、
データの水増しのやり方を覚えたりすると良い。
・コンペではDiscussionもあるので、知見としてアイディアが共有される。
有意義な議論があり、とても参考になる。
KernelやDiscussionを見てみると良い。
・失敗談
どのコンテストに出るかが難しい。
⇒データセットとタスクの見極め等
データセットの容量が少ないものに出てみるとか、
mnistなどGPUを必要としないものに出てみる等。
Gitを使えれば良いが、スクリプトの管理が難しい。
管理がごちゃごちゃになる。
⇒適当に管理しているといけないのでフォルダで管理する。
・自分一人で頑張ろうとして順位が上がらず、モチベーション低下する。
Kernelを使いこなして参加することで維持できる。
・上位入賞するには、特徴量のパターンが出てきた時に、
1000個と5000個では5000個の方が良い精度が出るので、
時間があれば実践を増やすといい。
シングルモデルは難しく、多数のモデルでアンサンブルが良い。
色々な特徴量を用意して、精度を上げていく。
⇒最後にアンサンブルで多様性を出す。
###8-2-11 実践につながるインプット
●学習のやり方
プログラミングの習得⇒機械学習
スクリプトベースの学習
Kaggleでの実践⇒実務に活かす。
論文の読み込み。
データ分析やAIはKaggleが良い。