いっしきまさひこBLOG

AI・機械学習関連、Web制作関連、プログラミング関連、旅行記録などなど。一色政彦。

Google Colaboratory(Colab)でRカーネルのノートブックを超簡単に作成するには?

結論から先に

上記のリンクをクリックするだけで、RカーネルのColabノートブックを新規作成できます(※ノートブックがGoogleドライブに保存されます。ちなみに「create=false」としても新規作成されてしまいます)。ブックマークするか、ショートカットリンクを保存しておくのがお勧めです。

f:id:misshiki:20200603000300p:plain
[ランタイムのタイプを変更]ダイアログ

関連として、下記のリンクをクリックすると、新規作成せずにPythonカーネルのColabノートブックを一時作成できます(※ノートブックは保存されません)。Rカーネルで一時作成する方法は分からないです。

また、次のリンクをクリックで、Colabのノートブック選択ダイアログが開きます。

解説

Google Colabは、グーグルが独自にカスタマイズして提供しているJupyter Notebook環境(Googleドライブのアドオン)です。基本的には、Jupyter Notebook(やJupyterLab)と機能が共通的です。

Colabは、通常、Pythonを実行できる開発環境/ノートブックとなっています。その実行エンジン(ランタイム)は、カーネル(kernel)と呼ばれ、実はPython言語(バージョン2とバージョン3)以外にもR言語/Swift言語が最初からサポートされています。

そのことは、Pythonカーネル上で!jupyter kernelspec listというコマンドをコード実行すると確認できます。

f:id:misshiki:20200603000424p:plain
ColabのJupyterカーネル一覧

このうち、ir /usr/local/share/jupyter/kernels/irと書かれている部分ですね。

使い勝手はPythonカーネルと同じです。MarkdownテキストもRコードも自由自在に書けます。

f:id:misshiki:20200603002156p:plain
Colab(Rカーネル)の使い勝手

Google Colaboratory(Colab)でSwiftカーネルのノートブックを超簡単に作成するには?

結論を先に

上記のリンクをクリックするだけで、SwiftカーネルのColabノートブックを新規作成できます(※ノートブックがGoogleドライブに保存されます。ちなみに「create=false」としても新規作成されてしまいます)。

f:id:misshiki:20200602235810p:plain
[ランタイムのタイプを変更]ダイアログ

関連として、下記のリンクをクリックすると、新規作成せずにPythonカーネルのColabノートブックを一時作成できます(※ノートブックは保存されません)。Swiftカーネルで一時作成する方法は分からないです。

また、次のリンクをクリックで、Colabのノートブック選択ダイアログが開きます。

解説

Google Colabは、グーグルが独自にカスタマイズして提供しているJupyter Notebook環境(Googleドライブのアドオン)です。基本的には、Jupyter Notebook(やJupyterLab)と機能が共通的です。

Colabは、通常、Pythonを実行できる開発環境/ノートブックとなっています。その実行エンジンは、カーネル(kernel)と呼ばれ、実はPython言語(バージョン2とバージョン3)以外にもR言語/Swift言語が最初からサポートされています。

これは、Pythonカーネル上で!jupyter kernelspec listというコマンドをコード実行すると確認できます。

f:id:misshiki:20200602235906p:plain
ColabのJupyterカーネル一覧

このうち、swift /usr/local/share/jupyter/kernels/swiftと書かれている部分ですね。

使い勝手はPythonカーネルと同じです。MarkdownテキストもSwiftコードも自由自在に書けます。

f:id:misshiki:20200602235945p:plain
Colab(Swiftカーネル)の使い勝手

サクッと試せるTensorFlow/Kerasニューラルネットワークの最小コード(Minimal Code)

「とにかくコピペだけでサクッと動かせるニューラルネットワークのコードが欲しい」というときがあるのだけど、検索してもなかなか出てきません。そこで、とにかくコピペだけ試せる最小コードを作りました。TensorFlow/Keras版です。

# ライブラリのインポート
import tensorflow as tf
import tensorflow.keras.backend as K

# 入力データ
NUMBER_OF_DATA  = 64
INPUT_FEATURES  = 1000
HIDDEN_FEATURES = 100
OUTPUT_FEATURES = 10
x = tf.random.normal([NUMBER_OF_DATA, INPUT_FEATURES])
y = tf.random.normal([NUMBER_OF_DATA, OUTPUT_FEATURES])
#x.shape # TensorShape([64, 1000])
#y.shape # TensorShape([64, 10])

# モデルの定義
model = tf.keras.models.Sequential([
  tf.keras.layers.Dense(input_shape=(INPUT_FEATURES,), units=HIDDEN_FEATURES),
  tf.keras.layers.ReLU(),
  tf.keras.layers.Dense(OUTPUT_FEATURES)
])
#model.summary()

# ★選択肢1★ トレーニング(簡易版)
LEARNING_RATE = 0.03   # 学習率: 0.03
EPOCHS = 100           # エポック数: 100
LOSS = 'mean_squared_error'

model.compile(
  optimizer=tf.keras.optimizers.SGD(learning_rate=LEARNING_RATE), 
  loss=LOSS,
  metrics=['accuracy'])
model.fit(x, y, epochs=EPOCHS)

print('Finished Training')
#print(model.get_weights())

# # ★選択肢2★ トレーニング(カスタマイズ版)
# LEARNING_RATE = 0.03   # 学習率: 0.03
# EPOCHS = 100           # エポック数: 100
#
# criterion = tf.keras.losses.MeanSquaredError()
#
# optimizer = tf.keras.optimizers.SGD(
#   learning_rate=LEARNING_RATE)
#
# def train_step(train_X, train_y):
#   training = True
#   K.set_learning_phase(training)  # tf.keras内部にも伝える
#   with tf.GradientTape() as tape:
#     pred_y = model(train_X, training=training)
#     loss = criterion(pred_y, train_y)
#   gradient = tape.gradient(loss, model.trainable_weights)
#   optimizer.apply_gradients(zip(gradient, model.trainable_weights))
#   return loss.numpy()
#
# for i in range(EPOCHS):
#     loss_result = train_step(x, y)
#     print(i, ':', loss_result)
#
# print('Finished Training')
# #print(model.get_weights())

ちなみに試すときは、Colabスクラッチパッドが便利ですよ。

サクッと試せるPyTorchニューラルネットワークの最小コード(Minimal Code)

「とにかくコピペだけでサクッと動かせるニューラルネットワークのコードが欲しい」というときがあるのだけど、検索してもなかなか出てきません。そこで、とにかくコピペだけ試せる最小コードを作りました。PyTorch版です。

# ライブラリのインポート
import torch
import torch.nn as  nn
import torch.optim as optim

# 入力データ
NUMBER_OF_DATA  = 64
INPUT_FEATURES  = 1000
HIDDEN_FEATURES = 100
OUTPUT_FEATURES = 10
x = torch.randn(NUMBER_OF_DATA, INPUT_FEATURES)
y = torch.randn(NUMBER_OF_DATA, OUTPUT_FEATURES)
#x.size() # torch.Size([64, 1000])
#y.size() # torch.Size([64, 10])

# モデルの定義
model = nn.Sequential(
            nn.Linear(INPUT_FEATURES, HIDDEN_FEATURES),
            nn.ReLU(),
            nn.Linear(HIDDEN_FEATURES, OUTPUT_FEATURES))

# トレーニング
LEARNING_RATE = 0.03   # 学習率: 0.03
EPOCHS = 100           # エポック数: 100

criterion = nn.MSELoss()

optimizer = optim.SGD(
    model.parameters(),
    lr=LEARNING_RATE)

def train_step(train_X, train_y):
    model.train()
    pred_y = model(train_X)
    optimizer.zero_grad()
    loss = criterion(pred_y, train_y)
    loss.backward()
    optimizer.step()
    return loss.item()

for i in range(EPOCHS):
    loss_result = train_step(x, y)
    print(i, ':', loss_result)

print('Finished Training')
#print(model.state_dict())

ちなみに試すときは、Colabスクラッチパッドが便利ですよ。

はてブのタグを一括編集、タグ名や日付で一括削除するためのツール「HatebuTagManager」

2020年12月16日追記:気付いたらいっぱいブックマークがついていてうれしかったです。ありがとうございます。はてなブックマーク本家で「タグの一括編集機能」が復活しました。これで本ツールは御役御免ですね。ご利用していただいた方、ありがとうございました。 - 「タグの一括編集機能」をPCのブラウザで再提供いたします - はてなブックマーク開発ブログ

はてなブックマークの「タグ一括 編集(タグの 置換変更)」「タグ名による 一括 削除」「日付による 一括 削除」の3機能を提供するWindowsアプリです。簡単な操作で使えます。※非公開ブックマークにも対応しています!

f:id:misshiki:20200408142131p:plain
はてブのタグを編集(変更/置換)したり、削除したりできる!

※注意事項: 本ツールの使用によって、何が起こっても無補償です。作者は一切の責任を負いません。自己責任でお願いします。ご了承のうえで本ツールをご使用ください。もちろんツール作者自身も本ツールを使っていますので、そんな大変なトラブルは起きないとは思いますが。

目的

かつて「はてなブックマーク」ではタグの一括置換機能が提供されていましたが、あまり使われなかったためか、機能が廃止されてしまいました。そこで「タグ一括置換」を行うための簡単操作ツール(Windowsアプリ)を作りました。

さらに、指定タグ名が含まれるブックマークを一括削除したり、指定日より前のブックマークを一括削除したりするための機能も、このツールに搭載しました。

(ちなみに最初に作り始めたのは2019年7月でしたが、2020年4月に行ったタグ整理をきっかけに、全機能を完成させました。)

ユースケース(用途)

  • 例えば、ツールや製品などの名前が変わったために、タグの名前も変えたい → [タグ一括置換]
  • 例えば、一度つけた名前がしっくりこなくて、後悔している → [タグ一括置換]
  • 例えば、技術が廃れたり製品がなくなったりしたため、タグごとブックマークもなくしたい → [タグ名による一括削除]
  • 例えば、ジョブチェンジや趣味の変化などの理由で、(タグ一覧で存在感が大きすぎる)以前のタグの存在感を弱くしたい → [タグ名による一括削除]
  • 例えば、5年以上前のブックマークは見返すことはないので、直近数年を残してブックマーク全体をリセットしたい → [日付による一括削除]
  • 例えば、ブックマークが大量すぎて、全体が把握しづらいので、とにかく数を減らしてスリム化したい → [日付による一括削除]

以上のような用途が考えられます。こういった用途に合致するのならば、以下の事前準備と使い方の方法でぜひツール「HatebuTagManager」を使ってみてください。

事前準備

  • このツールは「はてなブックマーク REST API」を使っています。その認証方法は、OAuthのみとなっており、Consumer keyとSecretが必要です。
  • Consumer keyとSecretは、公式ページ「OAuth ではてなのサービスにアクセスする - はてな」で取得してください。
  • [新しいアプリケーションの追加]ボタンを押すだけです。次に表示される登録ページ内の[キー]欄に、Consumer KeyとSecretは記載されています。
  • 登録ページ内の[承認を求める操作]欄で、下記の4つにチェックを付けて、一番下の[変更する]ボタンを押せば完了です。
    • read_public …… 公開情報の読み取り
    • write_public …… 公開情報の読み取りと書き込み、削除
    • read_private …… プライベート情報を含む情報の読み取り
    • write_private …… プライベート情報を含む情報の読み取りと書き込み

「HatebuTagManager」の使い方

  • ツール「HatebuTagManager」の最新バージョンは、[Releases]から「HatebuTagManager.~.zip 」ファイルをダウンロードしてください。その.zipファイルを展開して、フォルダー内のHatebuTagManager.exeファイルを実行してください(Windows 10専用です)。

GUIツール画面

  • 上から順番に、各入力欄に適切な内容を入力し、ボタンを押していってください。
  • ※[……(テスト用)]と書かれているボタンは、指定URLのブックマークを1つだけ処理する用です。一括処理時は、このボタンを押す必要はありません。
  • 【 ステップ 2 】では、
    • 「公開」ブックマークのみの場合: [すべての「公開」ブックマーク情報の取得]ボタンをクリックしてください(手軽)。
    • 「公開&非公開」全ブックマークを取得したい場合: はてなブックマーク公式のエキスパートページ から、ブックマーク形式のデータファイルをダウンロードして、ツール上にドラッグ&ドロップしてください(お勧め)。詳しくは後述します。
  • 【 ステップ 3 】に、上記の3機能に対応するボタンがあります。
  • 【 ステップ 3 】の処理中に実行をどうしても止めたくなった場合は、右上の[×]ボタンをクリックしてください。
    • ※ただし、これは強制終了でアプリを閉じることになり、アプリが閉じられる直前に強制的に「途中まで実施済みの結果ログの出力」が実行されます。
  • 【 ステップ 3 】の3機能を実行した後で、続けて【 ステップ 3 】の3機能をさらに実行したい場合は、【 ステップ 2 】の[すべてのブックマーク情報の取得]ボタンを押して、全ブックマーク情報をリセットしてから行ってください。
    • ※最新のブックマーク情報を取得し直す必要があります。

「公開&非公開」全ブックマークを取得する方法

非公開のブックマークを含めて全ブックマークを取得するためのAPIは提供されていません。そのため、ユーザーの方で全ブックマークをエクスポートとして、それを本ツール「HatebuTagManager」にインポートする必要があります。インポート方法は、ドラッグ&ドロップのみサポートしています。手順は以下のとおりです。

 上記の公式ページにアクセスしてください。

全ブックマーク情報のエクスポート

このようにして、 <ユーザーID>.bookmarks.html ファイルをダウンロードしたら、本ツールの【 ステップ 1 】を実行した後で【 ステップ 2 】として、そのファイルをツール上にドラッグ&ドロップしてください。

全ブックマーク情報のインポート

すぐに全ブックマーク情報が読み込まれます。次に【 ステップ 3 】の実行に進んでください。

【注意点】実行時間の表示について

置換/削除前に、ざっくりとした概算時間をメッセージボックスで表示しますが、あくまで予測であり、正確ではありません。特に「公開」ブックマークで「日付による一括削除」の場合、個々のブックマーク情報を取得しないと日付がチェックできないために、「最長時間」の予測表示になっています(※「公開&非公開」全ブックマークを取得した場合は、「日付による一括削除」でもブックマーク数で予測します)。

はてなブックマークAPIへの処理負荷を軽減するため、5~6秒に1処理ぐらいのペースで処理を行います(※サービス提供側への配慮です)。よって最低でも、100件で9分、1000件で1時間24分、10000件で14時間はかかる計算になります。使わないPCなどでずっと実行したままにするような形で使ってください。12時間以上かかりそうな場合は、(後述のTIPSを参考に)全削除して新たにブックマークを開始した方がよいかもしれません。

※本ツールは分散同時実行には対応していないため、ツールを複数箇所で同時に実行することもしないでください。

【注意点】一括削除時のエラーについて

はてなブックマークのリンク先がない場合など、「はてなブックマーク REST API」内部で何らかのエラーが起きやすいようです。本ツール側では対処のしようがありません。主に404エラーが出るページや、リダイレクト設定がされているページ、不要なクエリパラメーターが多数含まれているページで、このエラーが起きているようです。

エラーが起こったブックマークは、処理結果後のログファイルに記載されています。そのブックマークリンクを開いて、手動で置換/削除処理をしてください。基本的な手順を紹介しておきます。

手動削除手順(1)

(2)はてなブックマークのユーザー数(1 user)をクリックしてください。ゴミ箱ボタンをクリックしても、APIと同じで削除できない現象を確認しています。

これによってブックマークページが表示されるはずですが、次のように表示された場合はすでに削除済みです。

手動削除手順(2)

削除していない場合は次のように表示されるはずです。ここでゴミ箱ボタンをクリックします。

手動削除手順(3)

これによって削除され、[ブックマーク]ボタンが表示されるはずです。

手動削除手順(4)

日付順で最も古いものにアクセスするには、「https://b.hatena.ne.jp/(user-id)/bookmark?page=156」のようなURLでページ番号を指定して最後のページを探せばよいです。取りこぼし分は、ここから手動で削除していくこともできます。※作者確認では、どうしても削除できない項目がありました。はてなブックマーク運営会社に問い合わせてみましたが、やはり「調査の結果、ユーザー側ではできない」とのことで、運営会社側で削除してもらうことができました。

エラーの種類によっては、【 ステップ 2 】と【 ステップ 3 】の一連の処理を何度か繰り返すことで、何とかAPI内部で処理してくれる場合があることを確認しています。必要に応じて、お試しください。

【TIPS】はてなブックマークの全削除

はてなブックマークの全削除機能は、公式に提供されています(情報源「ブックマークの全削除機能の提供を再開しました - はてなブックマーク開発ブログ」)。

上記URLにアクセスし、[ブックマークの全削除]欄の[削除を進める]ボタンをクリックするだけです。

全削除

本ツールの開発について

このツールは無料ですし、あくまで個人の時間で簡易的に(1日ぐらいで)作成したものです。よってas-is(ありのままの状態)での提供とします。

Issues]に質問や不具合の報告をすることは可能です。ただし、上記の理由でこのツール開発に対する作者個人の優先度は低く、対応はあまり期待できないとお考えください。

Pull Requests]も受け付けます。時間があるときには対応します(数カ月~年単位の場合があります)。また、「積極的に開発したい」という方がいらっしゃれば、collaboratorとして招待しますので、何らかの手段でお知らせください。

ライセンス

  • MITライセンス

TensorFlow/Kerasの「kernel_initializer」などは、なぜ「weights(重み)」ではなく「kernel(カーネル)」なのか?

数年前、Kerasを初めて触ったとき、重みの初期化をしようと、APIドキュメントで「weight」を探しても見つからなくて、少し戸惑ったことがありました。その後、Kerasでは「重み」は「kernel」と表現されている箇所があることに気付いたわけですが、初心者には分かりにくいですよね。同じように混乱する人のために、このブログ記事を(手早く=手抜きで)書いて情報共有することにしました。

まずKeras(やTensorFlow 2.x)で重みの初期化を行うには、Denseレイヤーのコンストラクター(厳密には__init__()メソッド)の引数kernel_initializerを使います。他にも「kernel」と命名された引数には、正則化を行うための引数kernel_regularizerや、重み行列に制約を課すための引数kernel_constraintなどがあります。

なんで「weights」ではなく「kernel」? 実用上は問題ないので放置してそのまま使っていましたが、ずっとこの謎が気にかかっていました。最近、情報をあさっていて、Keras作者が直接言及しているGitHub Issues:

を発見したので、その内容を紹介します(※本文通りではない超訳です)。

  • 質問者: Denseレイヤーのパラメーターにkernel_initializerkernel_regularizerkernel_constraint、と「kernel(カーネル)」という名前が付けられていますが、「重み」ですよね。分かりにくいです。
  • 質問者: これってCNNの畳み込み(Conv)レイヤーとの整合性のために名付けられたのですか?( → 返答内容から見て基本的に「Yes」)
  • Keras作者: レイヤーの「重み」には、特徴(行列)とバイアス(ベクトル)の両方が含まれます。
  • Keras作者: カーネルとバイアスを区別する正確な方法が(レイヤー全種で共通化するために)必要でした。
  • Keras作者: そこで「カーネル/バイアス」という名称を採用しました。
  • Keras作者: Denseレイヤーは、「入力サイズ」のウィンドウを持つConvレイヤーの特殊なケースと見ることができます。つまりいずれも「カーネル」を参照するということです。
  • Keras作者: この表記法は、KerasとTensorFlow全体で使用されているため、ディープラーニングコミュニティの大多数が認識しています。つまり「カーネル/バイアス」はデファクトスタンダードなんですよ。
  • 質問者: なるほど~。でも研究論文では「カーネル」と書いているのは見たことないです。私の中では、重みの中にバイアスは含まれていないです。「カーネル」は言い過ぎなので、この命名には反対ですね。

個人的にはすっきりしました。「重み」の初期化って言いつつ「kernel」とコードに記述するのは一致しなくて違和感あるので、「weights」って単語も入れてほしかったですが。

重みの中にバイアスが含まれるのって、重み行列を書くときに、バイアスを$w_0$と書いてその重みテンソルの中に含めるからですよね(たぶん)。でも概念的には重みとバイアスって、(直線で言うと)傾きと切片なんだから別物な気がします。

個人的には質問者に賛成なんだけど、ライブラリ制作者サイドとしては、引数などの「共通化」や「整理された美しさ」などの考えが入って、こういう結果になっているんだろうなと、今のところ納得しています。

TensorFlowやPyTorchで自動微分して勾配を取得する方法

この記事では、TensorFlowとPyTorchの「自動微分」機能を使って勾配(=微分係数)を計算します。

PyTorchの自動微分については「第1回 難しくない! PyTorchでニューラルネットワークの基本:PyTorch入門 - @IT」を、
TensorFlowの自動微分については「第5回 お勧めの、TensorFlow 2.0最新の書き方入門(エキスパート向け) (2/2):TensorFlow 2+Keras(tf.keras)入門 - @IT」 を参考にしてください。

以下で説明する内容は、以下で実行/ソースコード参照できます。

■準備

●Pythonバージョン:3.x

import sys
print('Python', sys.version)
# Python 3.6.9 (default, Nov  7 2019, 10:44:02)  …… などと表示される

●TensorFlowバージョン

# Google Colabで最新の2.xを使う場合、2.xに切り替える(Colab専用)
# %tensorflow_version 2.x

import tensorflow as tf
print('TensorFlow', tf.__version__)
# TensorFlow 2.1.0 ……などと表示される

●PyTorchバージョン

import torch
print('PyTorch', torch.__version__)
# PyTorch 1.4.0 ……などと表示される

■実装方法

●例として使う計算式

$$ y=2x^3+4x^2+5x+6 $$

○これをPythonの式にすると...

def calc(x):
  return (2 * x ** 3) + (4 * x ** 2) + (5 * x) + 6

●微分する導関数の式は...

$$ \frac{dy}{dx}=6x^2+8x+5 $$

○これをPythonの式にすると...

def der_calc(x):
  return (6 * x ** 2) + (8 * x) + 5

●導関数に$x=0.5$を入力すると...

$$ \begin{align} \frac{dy}{dx}&=6\times(0.5)^2+8\times(0.5)+5 \\ &=(6\times0.25)+(8\times0.5)+5 \\ &=1.5+4+5 \\ &=10.5 \end{align} $$

○Pythonのコードで計算すると...

result = der_calc(0.5)
result # 10.5

$10.5$が出力される。これと同じことをPyTorchとTensorFlowの自動微分機能を使って行う方法を紹介する。

■PyTorch編

  • データをPyTorchテンソル化して、計算式を作る
  • backward()メソッドで逆伝播する(自動微分)
  • データ(テンソル)のgrad変数で微分係数(=勾配)を取得できる

という流れで書けばよいです。具体的には以下の通り。

import torch
import torch.nn as nn  # 「ニューラルネットワーク」モジュールの別名定義

x = torch.tensor(0.5, requires_grad=True)  # 変数に対して「勾配計算が必要」とマーク
y = calc(x)    # 既存の計算式から計算グラフを動的に構築
print(y)       # tensor(9.7500, grad_fn=<AddBackward0>) ……などと表示される

y.backward()   # 逆伝播の処理として、上記式から微分係数(=勾配)を計算(自動微分:Autograd)
g = x.grad     # 与えられた入力(x)によって計算された勾配の値(grad)を取得
print(g)       # tensor(10.5000)  ……などと表示される

y.backward(); g = x.gradg = torch.autograd.grad(y, x) と書いてもよいです。

●グラフを描画

先ほどは単一のスカラーだったので、今度は複数のスカラー値で計算してみます。

# PyTorchの微分グラフ
import numpy as np
import matplotlib.pyplot as plt

x = torch.arange(-4.0, 4.0, 0.001, requires_grad=True)
y = calc(x)
y.backward(gradient=torch.ones_like(y)) # スカラーテンソルの場合は勾配を格納する場所が必要なのでテンソルを仮生成【重要】
g = x.grad
x_numpy = x.detach().numpy()  # デタッチして(=追跡しないようにして)からndarray化する
g_numpy = g.detach().numpy()
plt.plot(x_numpy, g_numpy, label = "Derivative")
plt.xlim(-4, 4)
plt.ylim(-2.0, 30.0)
plt.grid()
plt.legend()
plt.show()

f:id:misshiki:20200319003754p:plain
出力された微分係数のグラフ(PyTorch編)

■TensorFlow編

  • データをTensorテンソル化して、勾配テープ(GradientTape)内で計算式を作る
  • 勾配テープ(tape)のgradientメソッドで逆伝播する(自動微分)
  • 逆伝播により計算された微分係数(=勾配)が取得される

という流れで書けばよいです。具体的には以下の通り。

import tensorflow as tf
import tensorflow.keras.layers as layers  # 「レイヤー」モジュールの別名定義

x = tf.Variable(0.5)
with tf.GradientTape() as tape:  # 計算式に対して「勾配計算が必要」とマーク
  y = calc(x)  # 既存の計算式から計算グラフを動的に構築
print(y)       # tf.Tensor(9.75, shape=(), dtype=float32) ……などと表示される

g = tape.gradient(y, x)   # 逆伝播の処理として、上記式から微分係数(=勾配)を計算(自動微分:Autograd)
print(g)       # tf.Tensor(10.5, shape=(), dtype=float32)  ……などと表示される

●グラフを描画

先ほどは単一のスカラーだったので、今度は複数のスカラー値で計算してみます。

# TensorFlowの微分グラフ
import numpy as np
import matplotlib.pyplot as plt

x = tf.Variable(tf.range(-4.0, 4.0, 0.001), trainable=True)
with tf.GradientTape() as tape:
  #tape.watch(x) # tf.constantなど「trainable=False」な状態であれば x を記録する(手動追跡)
  # ↑tf.Variableであれば既に訓練可能な状態(自動追跡)なので不要
  y = calc(x)
g = tape.gradient(y, x)
x_numpy = x.numpy()
g_numpy = g.numpy()
plt.plot(x_numpy, g_numpy, label = "Derivative")
plt.xlim(-4, 4)
plt.ylim(-2.0, 30.0)
plt.grid()
plt.legend()
plt.show()

f:id:misshiki:20200319003818p:plain
出力された微分係数のグラフ(TensorFlow編)

簡単ですね。以上で終わりです。