tensorflow1.15, tensorflow2での勾配や重みの取得

この記事はFUN part2 Advent Calendar 2021 - Adventarの23日目の記事です。遅くてすみません。
adventar.org
22日目はあわくんの2021年買ったものをまとめてみる - あわあわくんですです。彼の資金源はどこから来ているのか興味を惹かれますが、ロードスターがかっこいいのでこれにて終了。

はじめに

深層モデルの重みや勾配を取得するのは特に最近のモデルにおいて重要なものとなっています。tensorflow2では資料が多く落ちていますが、tensorflow1ではほぼ資料がありません。なのでtensorflow1での重み取得や勾配取得について試してみたブログになります。この記事は未完成なので気をつけてご覧ください。

OSと利用バージョン

  • tensorflow 1.15.3 | 2.0.0(多分2系でバグ踏まなきゃ共通)
  • windows 10
  • python 3.7

tensorflow2

重み取得

kerasの場合

レイヤーについて - Keras Documentationにあるようにkerasの全てのレイヤーはget_weightsの関数を持っているので、layer.get_weights()で重みを取得する事ができます。また複数レイヤを束ねた(Sequential)モデルも同様にしてmodel.get_weights()ですべてのレイヤーの値が取得できます。

独自モデルの場合

独自モデルでtf.keras.Modelを利用してモデルを定義した場合も上記と同様にmodel.get_weights()で重みを取得する事ができます。

またおおよそこれらのモデルに対してset_weightsも利用する事ができますが、挿入しようとする行列のshapeに注意してください。

勾配取得

勾配を取得するために必要なものは2つあって。1つ目が損失(loss)で2つ目が勾配を求めたい行列(重み等)です。公式ではGradientTapeを利用するチュートリアルが提供されています。

GradientTape

GradientTapeは公式チュートリアルの様に利用すれば

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(10, activation='softmax')
])
label = np.array([0,0,0,1,0,0,0,0,0,0])
input_test = np.random.random(size=(1,28,28))
with tf.GradientTape() as tape:
  logit = model(input_test)
  loss = tf.nn.softmax_cross_entropy_with_logits(label,logit)
grad = tape.gradient(loss, model.trainable_variables)

で取得できます。また特定のレイヤーについて勾配を求めることも可能です。

grad = tape.gradient(loss, model.layers[1].trainable_variables)

ちなみに途中でnumpyの計算を挟んだりすると勾配がNoneになる可能性があります。気をつけてください。

tf.gradient

公式チュートリアルではGradientTapeが利用されていますが、tensorflow1と同様にtf.gradientも利用可能です。tensorflow2では基本的にeagerモードで実行されるためgraphモードに変更してのみtf.gradientを利用することができます。eager・graphモードの切り替えは、Tensorflow のgraph modeをeager modeに変える | マサムネの部屋こちらのブログ等がありますので検索をお願いします。
またgraphモードでの勾配計算はtensorflow1と似たようなものだと思っているのでここでは割愛して次で話します。

tensorflow1

巨人の肩に乗りたいなど何らかの理由があってtensorflow1系でこれらを実行したい場合があるのでここに記載します。

重み取得

tf.trainable_variables()で獲得した後session内で.eval()で求めるかtf.get_default_graph().get_tensor_by_name()で名前を指定して一時保存されたグラフファイルから(?)取得する事ができます。tensorflow1のkerasは知りません弄ってません過去の遺産は大体独自モデルだと信じています貴方も信じますか?

勾配取得

tf.gradients

ここではこの単純な3層NNとクロスエントロピー誤差を用います。

def NN(input_tensor):
  flat_input = tf.layers.Flatten()(input_tensor)
  L1 = tf.layers.dense(
            flat_input,
            128,
            kernel_initializer=tf.truncated_normal_initializer(stddev=0.02))
  out = tf.layers.dense(
            L1,
            10,
            kernel_initializer=tf.truncated_normal_initializer(stddev=0.02))
  return out

def loss_fn(logits, positions):
  one_hot_positions = tf.one_hot(
    positions, depth=10, dtype=tf.float64)
  log_probs = tf.nn.log_softmax(logits, axis=-1)
  loss = -tf.reduce_mean(
    tf.reduce_sum(one_hot_positions * log_probs, axis=-1))
  return loss

このとき以下のコードで勾配を取得することができます。

input_test = np.random.random(size=(1,28,28))
label = 3

out = NN(input_test)
loss = loss_fn(out,label)

tvar = tf.trainable_variables()
grads = tf.gradients(loss, tvar)

init_op = tf.initialize_all_variables()
with tf.Session() as sess:
  sess.run(init_op)
  sess.run(grads)
  grad_split = grads[0].eval()

流れとしてはデータの流れを定義したあと、tfがキャッチしている学習可能パラメータの取得とそれについての勾配(ここでは計算していない)を定義する。その後session内で初期化・計算・算出を行っています(多分)。

GradientDescentOptimizer

bert実装ではtf.gradientsを利用していたので節穴でしたが、実はGradientDescentOptimizerでも勾配計算することが可能です。上記のモデル・損失関数に対して以下の様なコードを利用します。このコードはTensorflowでGradientの値を計算グラフ外から読み込み - Qiitaを参考にしました。

input_test = np.random.random(size=(1,28,28))
label = 3

out = NN(input_test)
loss = loss_fn(out,label)

opt = tf.train.GradientDescentOptimizer(0.001)
grads_and_vars = opt.compute_gradients(loss)

init_op = tf.initialize_all_variables()
with tf.Session() as sess:
  sess.run(init_op)
  sess.run(grads_and_vars)
  grads = [gv[0] for gv in grads_and_vars]

これですべての学習可能パラメータについて勝手に算出してくれます。grads_and_varsは勾配と対応するパラメータの組でできています。これについて実数を算出したい場合はsession内でgrads[i=任意の数字].eval()を行ってください。

まとめ

tensorflow2になって抽象系APIがちゃんと動いてくれてかつめちゃくちゃ楽だったのでバージョンの向上を感じました。結果として本記事が未完になってしまったのが心苦しいですが、いつか追記をするかもしれませんすみません。また追加でコードも上げるかもしれませんが、それらの時はtwitterやらなんやらで告知したいと思います。

お読みいただきありがとうございました。

ソフトウェアエンジニアの為の道具としての深層学習紹介

本記事の目的

 本記事は FUN Advent Calendar 2020 - Adventar の18日目の記事です。
昨日の記事はみょいさんの「ニューロンの振る舞いを理解する - HackMD」でした。
シナプス電位やニューロンのモデルのコードと結果が私的に見どころでした、お疲れ様です。彼が私から遠い場所に行ってしまう感覚に戦々恐々としましたが、世の中そんなものだと思うので私の記事を書いていこうと思います。

 本記事はソフトウェアエンジニアの為の道具としての深層学習紹介という事で詳しいことは他に丸投げしつつ紹介だけしていきたいと思います。

自己紹介

 私は自然言語処理の深層学習モデルを主に追っている学部4年生です。なので本記事は正確なものでない可能性が大いにありますので、お気を付けてお読みください。

ソフトウェアエンジニアはいつAIの利用を検討するのか

 基本的に複雑なデータを入力として分類や予測などのタスクの中で複雑なものを自動で行ってくれるシステムを開発したい時に検討します。ここでの複雑なデータとは変動するデータ(画像や言語や音など)の事を指しており、複雑なタスクとはそれらの変動を加味した上での出力の決定を主に指します。具体的な例として、チャットボットや顔認識、監視カメラの人モノ検出等です。

深層学習とは

 機械学習Wikipediaによると経験からの学習により自動で改善するコンピュータアルゴリズムの事を指します。これらは入力とされるデータの背景を分析し出力を作成します。基本的には入力のデータと共に出力のデータ例も学習には必要です。
 深層学習はその機械学習の中に位置付けられていて、多数のニューラルネットワークを用いた手法を主に指します。詳しい説明はディープラーニング(深層学習)とは|基本知識・仕組み・活用事例・機械学習との違い | Ledge.ai等を参照してください。

深層学習の使いどころ

 深層学習はパラメータが多い等の性質上複雑な背景を持つデータの分析が得意です。よって明示的に記述するのが難しい状況下で用いられます。有名なのは画像分類で、比較的簡単にデータの下で良い結果を出す事ができます。

データの重要性

 これまでで言った通りデータが無いと深層学習は活用できません。また画像の様なデータ単体でも難しく、ラベルというものも用意しなければいけません。その為企業はデータに対してラベル付けをする仕事を他所に委託している場合があります。また学習に使うデータを作成する専門の企業も出ています。それほどまでにデータは深層学習の生死を分けます。

深層学習の種類

 深層学習にはさまざまな種類のタスクとモデルがあります。多くの際ビジネスで持ち上がるタスクとしては画像や言語です。また実際に深層学習が可能なタスクについてはBrowse the State-of-the-Art in Machine Learning | Papers With Codeを参考にして下さい。
 画像系のタスクを行う場合用いやすいモデルとしてはVGGと呼ばれるCNN系列のモデルです。また言語系のタスクを行う場合用いやすいモデルはAttention系列のTransformerまたはRNN系列のSeq2Seqです。詳しいモデル説明は割愛します。

深層学習のツール

資金があまりない場合

 自身でコードを書く必要性が出てきます。その場合深層学習ライブラリとしてtensorflowかpytorchの2点が挙げられます(機械学習ならsklearn)。個人的なおすすめはtensorflowの中にあるkerasというライブラリーでとても簡単にモデルを作成する事ができます。またtensorflowは多くの言語に対応しており、pythonで学習させたモデルを他の言語のサーバーサイドの関数として搭載する事も可能です。(Home - Keras Documentation)を行うと良いと思います。
 また運用に関してはMLOpsの様な機械学習の運用を調べたら良いと思います。

資金が潤沢にある場合

 AutoML等の簡単にモデルを運用できるサービスを利用するまたは外注するのが最善だと思われます。なぜなら深層学習の運用は昨今の研究やフレームワークの開発で多少マシにはなってきているものの今だ泥沼の様な戦いが予想されます。特に似たような前例が無い事をする場合は注意した方が良いと思います。

おわりに

 駆け足で本記事を記述しましたのでエビデンスの少ない記事になってしまいました。申し訳ありません。今回深層学習のご紹介をさせていただきましたが、身も蓋もない事を言うと特別な理由(助成金の為・深層学習でしかできないタスクをする為)等が無い場合実サービスに深層学習を選択するのは止めた方が良いと個人的には思います。統計手法や機械学習、ルールベースにしましょう。最後まで読んでいただきありがとうございました。

公立はこだて未来大学のコース選択について

はじめまして。公立はこだて未来大学の海老原です。今回はFUN Advent Calendar 2019 - Adventarの10日目の記事として書かせていただきます。本来ならば2本立てで本記事とAttention Network(ディープラーニング関係)の事を書こうと思っていたのですが、間に合いそうにないのでAttentionは後日寄稿させていただきます。

本記事の内容
本記事はタイトル通り公立はこだて未来大学のコース選択について書きます。なぜ書くかと言うと、今年は1年生が有望でかつコース選択について自分のコースのみの宣伝しかしない人がいるらしいので需要があるかなと思ったからです。ちなみに私自身は複雑コースです。

想定読者
公立はこだて未来大学に入学した学部1年生

注意
本記事は完全に個人の主観によるものなので、他の情報を加味した上でコースの選択をして下さい。どんな人生になっても作者は責任を負いませんが質問には答えます。公式なコース説明は次を参照:学科・コース | 公立はこだて未来大学

情報デザインコース
名前の通りデザインに興味のある人向けのコースです。デザインは物やUI等だけでなく、ヒトがどう感じるかを学ぶ事もできるらしいです。授業に全部出席して、課題をこなせる方なら卒業しやすいと思います。

知能システムコース
人工知能興味あるけど積極性はあまりないという人向けのコースです。昔の人工知能研究の考え方や、それを実世界応用する上で必要となる基礎技術を学ぶコースです。情報システムコースと複雑コースの複合型な感じがします。真面目な人なら卒業できる気がします。

複雑系コース
複雑系に含まれる領域に興味があり、特に積極的に動ける人向けのコースで、未来大学の旧目玉コースです。複雑系科学を学ぶ上で必要となる最低限の知識を学ぶコースです。複雑系科学については個人的に調べて下さい。含まれる領域としては、経済学や力学、確率統計等です。人工知能も入ります。数学できる人なら卒業できます。

情報システムコース
未来大生に一番推奨するコースで、未来大学の現目玉コースです。一般的な情報系大学の講義とエンジニア系の基礎力を広く浅く養う事ができるコースです。何らかの専門家(ここではデータサイエンティストや学者の事を指します)になる予定が無いのならば最適なコースだと思います。なぜなら情報システムコースの授業を受けていれば色々な所に応用が利くからです。パソコンを触るのが苦でないなら卒業できると思います。

高度ICTコース
システムエンジニアやマネージャーになる為の基礎力を培うコースで、修士確定していて就職や入試にかけるコストなどを考えるとコスパの良いコースです。6年制の教育が受けられるのでかなり濃密です。情報システムコース卒業+α位の真面目さとシステム系で好きな所があれば卒業できると思います。

まとめ
上記でコースの紹介をしましたが、結局は自分の好きな事や進みたい道、目標を授業の内容やそのコースの先輩方と比較して決定するのが良いと思います。

おまけ
本記事を書く上で複数のアイデアといくつかの記事をボツにしました。本記事自体は1時間で書きました。本記事がコース選択の参考になると幸いです。

エイチームの4日間インターン行ってきた

こんにちは。はこだて未来大学学部3年の海老原です。

かれこれブログ投稿するのは半年ぶりです。今回はエイチームインターンに行ってきたので考えの整理的にまとめようと思いました。また本記事には何を実装したかの記載は無く、重要だと思った事や感想等のみ記載しております。ご容赦下さい。

実は短期間インターンというものに参加するのは初めてで、今まではハッカソンと同じようなものだから身になるような事は無いかな~とかふざけた事を考えていました。長期間アルバイトインターンを以前やらせていただいた時は、基本一人プロジェクトで会社のバックアップのあるチーム開発は今回が初めてだったりします。その為似たような年代の似たようなレベル帯の人に本当に初めて会いました。とても勉強になりました。話が長くなりましたのでインターンのお話をしたいと思います。

エイチームインターン
4日間のスケジュール
1日目:目標設定→講義→企画
2日目:企画(続き)→開発→振り返り
3日目:リリース→レビュー→修正開発
4日目:プレゼン準備&開発→リリース→プレゼン→フィードバック

やったこと
webサイトの機能の追加提案、開発、プレゼンを行いました。

1日目
あらかじめ組まれたチームでの目標設定やエイチームの方々の講義、今回開発する機能の企画を行いました。

合計8チームでメンターさんはなんと1チーム2人いました!(僕のチームはメンターさん1人...)

f:id:takanori_AB:20190827131429j:plain
初日お昼ご飯IN社内食堂

社内見学を行いました。エイチームといえばやはり滑り台!もちろん滑ってきました!
講義はdockerのお勉強だったり、エイチームの根幹(?)的な話をしていただきました。
チーム内連携的なものがお粗末で、企画に時間をとても吸われてしまいました。。。

f:id:takanori_AB:20190827131840j:plain
脳みそ限界アイデア出し
f:id:takanori_AB:20190827132059j:plain
晩御飯IN社内食堂
チーム内連携を少しでも良くする為に散歩と少しだけの飲み会を行いました。
↑これは大学の集中講義(短期間でチームでのアイデア出しを行いました)で必要性を実感しました。

~睡眠時間5時間~

2日目
企画の続きとそれのフィードバック、開発の着手を行いました。

前日の交流も相まってか、チーム内連携が取れていました。それによって良い感じにアイデア出しを行う事が出来ました。アイデア出しの時他のメンバーは他のメンターさんにインタビューに行ってくれたのですが、タイミングを見失い僕自身は行くことがありませんでした。。。(ここからご飯写真は自重します)
昼食を終えついに開発が始まるというときにうちのチームのみ環境のエラーが頻発し、着手できませんでした。。。
翌日にversion1のリリースでかつ僕らの中でRuby on Railsに熟達した人が居なかったので、夜中の開発を行いました。

~睡眠時間2時間~

3日目
リリースとレビュー、それに基づいた開発を行いました。

私達が想定していた機能とは少し離れた機能が実装されたversion1をリリースしました。評価は上々、特にアイデア出しを頑張っただけありました。
レビューを様々な方から頂いたので、レビュー点の改善とアルゴリズムの修正を行いました。
1日中眠くてかなり脳みそ動いてませんでした、、、やはり睡眠時間は大事ですね。
ですが、version2のリリースは翌日なので今日もやはり深夜開発です!

~睡眠時間3時間~

4日目
リリースとプレゼンを行いました。

体力の限界を迎え、死屍累々としながら開発をしました。それによって私達が想定していた機能の実装とレビュー点の改善を行う事ができました。
残るはプレゼン、私ともう一名がスライドを作成し私が発表しました。これが敗因だったかもしれません。
プレゼン後順位と1ヶ月インターン参加者が発表されましたが、私達のグループは入賞しませんでしたし私自身選ばれる事はありませんでした。
プレゼンレビューとして、"完成度"が最下位でした。私達の想定した機能は実装できたのですが、プレゼンがうまくいってなかった様です。申し訳ございません。

まとめ
したこと

  • イデア出し
  • 少しの設計
  • デプロイ
  • プレゼン

得られたもの

  • 論理的思考能力
  • Railsでの開発経験
  • 同レベル帯との開発経験
  • 名古屋飯

振り返り

いままでハッカソンタイプのインターンは遠慮していましたが、ハッカソンタイプのインターンの良さを知ってしまったのでこれからは積極参加していこうと思いました。ではまた、、、

カロリーメイト中心の食生活によるメリットデメリット

はじめに

この記事はFUN Advent Calendar 12/10の記事です。(遅れてすみません)
私は2か月にわたってカロリーメイト(チーズ味・チョコレート味)*2箱を購入しました。その時感じたカロリーメイトを箱で買う際に感じたメリットデメリットを書き留めておこうと思います。あくまで個人の見解なのですべての人に適応されるとは思わないでください。

カロリーメイトとは

  • 身体に必要な11種類のビタミン・6種のミネラル・たんぱく質・脂質・糖質がバランスよく含まれている
  • 1本100kcal

ヒトが必要なカロリーや栄養素

カロリー

ヒトが1日に必要なカロリーは基礎代謝量と身体活動レベルを掛け合わせたものです。
基礎代謝量(kcal) = 基礎代謝基準量(kcal/kg)*体重(kg)
身体活動レベル = 表より索引
例として、私の必要なカロリーは1980(kcal)です。

栄養素

一日に必要な栄養素は沢山ありますが、1箱(4本入り)を食べるだけで1日に必要な半分の栄養素が得られます。(例外があります)

カロリーメイトのメリット

  • 時間が短縮できる
    • もちろん作る必要も無いし食べるのも作業しながら、洗い物も発生しません
  • 栄養が偏らない
    • 上記で説明した通り、栄養素はきちんと取れるのでカップ麺等より良いです
  • 買い物に行く必要がない
    • 通販で箱買いするので買い物に行く必要はありません!

カロリーメイトのデメリット

  • 精神的な幸せ度が低い
    • 私は何も感じないのですが、まだ見ぬディストピアのような食事風景です。
  • 脂質が多めだし、たんぱく質やカロリーが足りない
    • 脂質は1箱で1日の必要な脂質が取れます。また、たんぱく質は私の場合5箱は食べないと足りません。
  • 高い
    • もちろんですが、自炊よりは高いです。箱買いで4本入り1箱が164円です。

カロリーメイトを中心とした食生活で感じた事

最初にお話しした通り私は2ヶ月カロリーメイト中心の生活をしてきました。私は朝は何も食べず、昼は学校で買い、夜は家でカロリーメイトという生活をしていましたが、特に体に異常はありません。またたんぱく質不足等を昼飯でカバーし、カロリーもインスタント麺と併用すれば十分です。
無駄な外食も減り、作業の効率化も実現できました。
カロリーメイト自体が苦手な人には無理かもしれませんが、カロリーメイト中心の生活は有意義だと私は思います。
Let's カロリーメイト生活 !

www.amazon.co.jp

動的計画法の基本実装してみたった

とりあえず最初ということで簡単なところからいきます。本日生命情報学という授業でちろっと出てきてまだちゃんと実装したことなかったのでpython動的計画法をやってみようと思いました。

動的計画法とは?

処理が大きい問題を分解してそこだけ解いて速く解こう!っていうアルゴリズムらしいです。今回はフィボナッチ数列を使って[1]のサイトに書かれているトップダウンボトムアップの求め方をやってみて、最後に計算時間を計ろうと思います。

参考にしたサイトはここ

  1. http://tango-ruby.hatenablog.com/entry/2016/10/20/172918
  2. https://mieruca-ai.com/ai/introduction-dynamic-programming/

まずは普通のフィボナッチ数列
def nomal_fib(n: int):
    #初項 = 第0項目とする
    if n < 2:
        return 1
    else:
        return nomal_fib(n-1)+nomal_fib(n-2)

これは実装簡単ですね。漸化式になっていて、F(x)=F(x-1)+F(x-2)となっていてF(1)=F(2)=1です。ちなみに計算回数は2^nとなっていて、膨大です。

ではトップダウンをやっていきましょう。
class topDown_fib:
    def __init__(self):
        self.node = [1, 1]
    def __call__(self, n: int):
        if n < len(self.node):
            return self.node[n]
        else:
            A = self.__call__(n-1) + self.__call__(n-2)
            self.node.append(A)
            return self.node[-1]

これも基本的な計算は同じですが、self.nodeに計算した値を入れ同じ数字はわざわざ計算をしなくても良いようになっています。(これをメモ化と言うらしいです)

次にボトムアップを試してみようと思います。
def bottomUp_fib(n: int):
    if n==0:
        return 1
    else:
        a = b = A = 1
        for i in range(n-1):
            A = a+b
            a = b
            b = A
        return A

こちらは比較的元ブログのようなプログラムになってしましました...ゴールとスタートが見えてるなら最初っから最後まで計算しちゃえば良いじゃない!って感じです。(分割統治法と言うらしいですね...)

では最後にお待ちかねの計測ったーいむ!

f:id:takanori_AB:20181115205453p:plain

第20項まで求めてtime.perf_counter()で計りました。これは予想していない程に格段に違いましたね。これがアルゴリズムの力なのでしょうかね。

今回の感想

今回トップダウン型が2番手に来ましたが、なんとなくまだ伸びしろがありそうですね。。。次回こそは本業(趣味)である深層学習について書きたいです(^^♪ではまた次回~

私のブログを読むにあたって

初めまして。ご観覧いただきありがとうございます。

本ブログは情報系学部大学生がつらつらとなるべく有益になるような情報を発信する予定でございます。

---------***注意事項***-----------

・なるべく正確な情報をアップする予定ですが、至らない所やバイアスがかかっている可能性があります。ご注意ください。

・筆者はガラスのハートなのでアドバイスは人格否定等避けるようよろしくお願いします。

---------------------------------------