見出し画像

パラメータの最適化とExcelへの出力方法

はじめまして、大学院1年生です。
専攻は土木ですが、凝り固まった土木業界に機械学習の導入を目指しています。

はじめに


私は地盤工学の解析手法の一つとして機械学習を導入しています。専門は土木で(専門というもののたかが大学院生)、機械学習はあくまで一手法なので非常に未熟です。温かい目で見ていただければ幸いです。

また、不備等ありましたらコメントお願いします。


概要

言語:Python
ライブラリ:TensorFlow
解析手法:回帰分析(入力12変数、出力1変数)

目標

1.説明変数を減らす感度分析を行いたい。でもいちいちハイパーパラメータを最適化するのがめんどくさいため、半自動的にできるようにしたい。

2.各条件の比較は結果の平均絶対誤差と決定係数で行う。なので、解析ごとに使用したパラメータ値と結果をExcelに出力させたい。

最適化するもの

・層数 (1~8層を検討)
・バッチサイズ (16~128を検討)
・ノード数 (50~250を検討)
・初期学習率 (0.005~0.05を検討)

最適化手法

「ハイパーパラメータ最適化の手法はなく、試行錯誤的な決定が望ましい」

と先輩にうかがったため、複数組み合わせてパラメータを決定します。

for hidden_nodes in range(50,300,50): #ノード数を50,100,150,200,250
   for batch_size in [16,32,64,128]: #バッチサイズを16,32,64,128
       for first_lr in [0.005, 0.01, 0.05]: #初期学習率を0.005, 0.01, 0.05

こんな感じでパワーでfor文に当てはめました。最終のインデントの中に基幹となる計算を埋め込めば動きます。

これだと、5*4*3の60通りを回すのでモノによってはだいぶ時間がかかります。

また、層数は入っていません。なぜなら現状の層形式が

layer_1_drop=tf.nn.dropout(layer_1,rate=layer_1_rate)#第1層に対するDropoutを設定
weight_2 = __init__weight(shape=[hidden_nodes, hidden_nodes], st_dev=(2/hidden_nodes)**0.5)#標準偏差は√(2/hidden_nodes)(=前層のノード数)とした
bias_2 = __init__bias(shape=[hidden_nodes], st_dev=(2/hidden_nodes)**0.5)
layer_2 = fully_connected(layer_1_drop, weight_2, bias_2) #Dropoutを考慮

このように汎用性を利かせられない形式になっているからです。今は層数のみ逐次手打ちで変更しています。いつか簡略化したいです。def関数でできるんですかね?

加えて、ドロップアウトの考慮もしないといけないので、ある説明変数に対しては層数*2(DropOut ありなし)の数だけ解析を回す必要があります。
僕の例では層数は(1,2,4,6,8)において結果を観たいので10回の解析が必要です。

これも捉え方次第ですが、for文を使ってなかったら600回手を動かす必要があったのでだいぶましです。

出力

解析は回せましたが、いかにExcelに出力させるか。

出力させたいもの

・最終の教師損失関数
  →未学習でないか、学習は終えているかの確認
・最終のテスト損失関数
  →発散していないかの確認
・MAE(平均絶対誤差)
  →精度比較に利用。基本的にこれが小さいやつを最適としたい。
・R2(決定係数)
  →サブの精度比較に利用。

1試行ごとに4つの数値を得たいわけです。

イメージとしては、見てわかるように用いたハイパーパラメータの値とこれら4つを1行にどんどん追加させていきたい。

出力方法

(一部)
#一行目の列名指定
active_sheet['A1']='hidden-nodes'
active_sheet['B1']='batch-size'
active_sheet['E1']='平均絶対誤差(MAE)'
active_sheet['F1']='決定係数(R^2)'

#2行目に順次追加していく
active_sheet.cell(row=2, column=1).value = hidden_nodes
active_sheet.cell(row=2, column=2).value = batch_size
active_sheet.cell(row=2, column=5).value = MAE
active_sheet.cell(row=2, column=6).value = decr2

#2行目に1行空の行を挿入
active_sheet.insert_rows(2, amount=1)

#ここで、MAEとdecr2は前もって定義してます。

アクティブシートを使用しているのはこれまでの解析でテストデータの値と予測値をExcelに出力させていたからです。名残です。わからないですが、普通のシートで動くと思います。

結果論ですが、結構簡単でした。でも考え付くのに1時間ほどかかって、コードが完成するまで2時間ほどかかりました。

一番のみそは空行の挿入ですね。末行に追加していくのではなくて、上から降ろしていくイメージです。

まとめ​

ある程度の作業効率化は図れました。簡単なことに置き換えて、できそうなパターンで試行を繰り返すことが大事だと思いました。

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