【AI×ねこ】雑種猫の品種割合を当ててみる
実家で雑種の兄弟猫たちを飼っています。 その2匹が全然似ていないので、「ねこ品種判定AI」LINEbotをつくって品種割合を推定してみることにしました。
ねこ画像をLINE画面で送ると、構成される品種の割合が返される仕様です。
第二の目的として、Tensolflowの転移学習モデルInception-v3を試してみたかったというのもあります。
では早速実装の手順を解説していきます。 結果だけ知りたい人は、スクロールして最後の章へ...
システム構成
システム構成は簡単に書くとこんな感じ。 学習モデルをherokuサーバに置いて、WebhookでLINEbotから呼び出します。
使用したデータセット
画像を集める手段はいくつかありますが、スクレイピングは枚数の制限等が面倒で、オックスフォード大が公開しているデータセットを使いました。 (http://www.robots.ox.ac.uk/~vgg/data/pets/)
ねこちゃんいっぱい...
少し枚数は少ないですが、品種ごとにラベリングされた犬猫画像がまとめられています。今回はこのデータセットのうち猫の画像セットを使用します。 犬の画像を使えば犬種判定AIがつくれます。
枚数
枚数は一品種あたり約200枚。12品種なので全部で2400枚です。 DeepLearningの世界ではちょっと少な目な枚数。
含まれる品種
・アビシニアン ・ベンガル ・バーマン ・ボンベイ ・ブリティシュショートヘア ・エジプティアンマウ ・メインクーン ・ペルシャ ・ラグドール ・ロシアンブルー ・シャム ・スフィンクス 何やら聞きなれない品種もありますが、ひとまずこれで学習します。
ちなみに、最近Googleがデータセットを検索出来るサービスGoogle Dataset Searchをリリースしたようなので、今度はそれを使ってみたいです。(https://toolbox.google.com/datasetsearch)
学習器をつくる(転移学習)
学習器はTnsolflowの転移学習モデルInception-v3を使いました。
転移学習とは、学習済みのモデルに、タスク固有のデータを追加で学習させることです。一般に、少ないデータ数でそれなりに高い精度のモデルが得られると言われています。
今回でいうと、様々なカテゴリの画像を学習済みのInception-v3モデルに、猫画像を追加で学習させて、ねこ品種判別に特化したモデルになるようパラメータを調整します。
まずはデータの前準備から。
x_size = 224 y_size = 224 kind_label = [] cat_img = [] #識別する品種のリスト cat_list = ['Abyssinian','Bengal','Birman','Bombay','British_Shorthair','Egyptian_Mau','Maine_Coon','Persian' ,'Ragdoll','Russian_Blue','Siamese','Sphynx'] #データセットのロード for cat_kind in cat_list: print(cat_kind) file_list = glob.glob('/path/to/cat/image/*.jpg') for file in file_list: img_path = file img = image.load_img(img_path, target_size=(x_size, y_size)) x = image.img_to_array(img) x = preprocess_input(x) cat_img.append(x) kind_label.append(cat_kind) #品種ラベルをダミー化 Y_dummy = pd.get_dummies(kind_label) X_train, X_test, y_train, y_test = train_test_split( cat_img, Y_dummy, test_size=0.2, random_state=42)
モデルを作っていきます。今回は最終段のみ再学習します。 以下のコードを変えることで再学習する範囲を調整することも可能です。需要があれば追記しようと思います。
model = InceptionV3(weights='imagenet') # 中間層を出力するモデル intermediate_layer_model = Model(inputs=model.input, outputs=model.layers[311].output) feature = intermediate_layer_model.predict(x) pd.DataFrame(feature.reshape(-1,1)).plot(figsize=(12, 3)) # Denseレイヤーを接続 x = intermediate_layer_model.output x = Dense(1024, activation='relu')(x) predictions = Dense(len(cat_list), activation='softmax')(x) # 転移学習モデル transfer_model = Model(inputs=intermediate_layer_model.input, outputs=predictions) # 一旦全レイヤーをフリーズ for layer in transfer_model.layers: layer.trainable = False # 最終段のDenseだけ再学習する transfer_model.layers[312].trainable = True transfer_model.layers[313].trainable = True transfer_model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) #転移学習 transfer_model.fit(np.array(X_train), np.array(y_train), epochs=10, validation_data=(np.array(X_test), np.array(y_test))) #精度確認用に出力(必要に応じて) loss, acc = transfer_model.evaluate(np.array(X_test), np.array(y_test)) print('Loss {}, Accuracy {}'.format(loss, acc))
最後にモデルをh5ファイルとして出力します。
transfer_model.save("./model.h5")
LINEアカウントをつくる
以下のURLからLINE@アカウントを作ります。 https://at.line.me/jp/
「LINE@アカウントを作成する」>「一般アカウントを作成する」からLINEアカウントにログインし、必須項目を入力してアカウントを作成する。
アカウントを作成した後のbot設定は以下の通り。 ・LINE@MANAGER画面> Messaging API設定 >API申し込み ・LINE Developersで設定するボタンをクリック ・”Channel Secret”、”アクセストークン”をメモしておく ・利用可能なAPIにREPLY_MESSAGEがあることを確認 ・Webhook送信を「利用する」に
herokuでサーバーを立てる
まずはherokuのアカウント登録から。 https://www.heroku.com/
無料で使えるサーバーを立てていきます。
heroku環境導入
ローカルにherokuインストール
$ brew install heroku
ログインする
$ heroku login
アプリを作成
$ heroku create アプリ名
Herokuの環境変数にトークン追加
ここで上でメモしたLINEbotの情報が登場。”Channel Secret”、”アクセストークン”を使います。
$ heroku config:set LineMessageAPIChannelAccessToken={アクセストークン} --app アプリ名
$ heroku config:set LineMessageAPIChannelSecret={Channel Secret} --app アプリ名
準備するファイルはこちらの記事を参考にしました。(https://qiita.com/suigin/items/0deb9451f45e351acf92)
上記事中のapp.pyのみ画像を受け取って結果を返す仕様に変更しました。 (こちらもが需要があれば公開予定です。) 先ほど作った学習モデルはここで呼び出します。学習モデルのファイルはこのコードと一緒にherokuにデプロイしましょう。
一通りherokuへのデプロイが済んだところで、
$ heroku open
で出力されたWebhook URLをLINE Developersの設定画面に戻って設定すれば完了!
長かった...
完成!
やっと完成したので、ひとまずラグドールの画像で試してみたら良い感じ! そしてかわいい...
うちの猫たちで試してみる
うちの雑種ちゃん2匹で試してみます。 長毛くんの方は...
53.8%がラグドール、34%でバーマンとのこと。ちゃんと長毛認識してそう。しかもどことなく面影が...?
まっくろちゃんの方は...
98%の確率でブリティッシュショートヘアー。確かにちょっとふてぶてしい表情とか似てる。 画像引用:https://madoguchi.iyell.jp/british_short_hair_cat/
結論
転移学習を使えば、大量の画像を用意しなくても、なんとなく当たってそうな識別器が出来た。 テストデータで正解率を見たら8割弱くらい。まだ改善の余地はあるが、少しのデータでここまでのモデルが出来るの結構すごい。
Unityでの強化学習が結構たのしい【その1】
はじめに
「ねこ品種判定AI」( https://qiita.com/Gri_Gra/items/e5a507ebae5c4be2be6f )では、転移学習について書きましたが、 今度はUnityで強化学習が出来るようになったと知り、早速試して見ました。
Unity ML-Agents自体まだβ版ということもあり、手探り状態でしたが、先人達の知恵を借りながら、なんとか動かすところまではいけたので備忘録も兼ねて。
今回はボールを落とさないように板を動かすというタスクを学習させていきます。学習前はこんな感じ。落ちて来たボールをそのまま受け流してる。
学習後どうなったかは記事の最後でご紹介。
最初はQiita等のページを参考にさせていただいたのですが、どうもうまくいかず。どうやらバージョンアップに伴った仕様変更が原因のようでした。(さすがβ版...) やはり公式ドキュメントはきちんと読まないとですね...。(英語だからついつい避けてしまう)
環境
環境は以下の通りです。 OS: macOS Sierra(10.12.6) Unity: 17.02.0f3 Unity ML-Agents: v0.5
枠組み
概念の理解は、以下のページが大変参考になりました。 https://qiita.com/dora-gt/items/bacce436de2a3cdb1ef4
今回はgit管理等はとりあえず置いておいて、とりあえず一旦動かすことを目標に実際の作業ベースでメモしていきます。
インストール
インストールの必要があるのは以下
・Unity(2017以降): https://store.unity.com/ja Unityについては多分解説いらないですかね。ページの指示に従ってインストールします。個人利用なら無料で使えます。
・Unity ML-Agents(強化学習用アセット): https://github.com/Unity-Technologies/ml-agents Unity ML-Agentsについてはクローンする方法とzipをダウンロードする方法があるようです。私は後者でやりましたが、どちらでも問題ないと思います。 zipをダウンロードする場合は右上にある'Clone or Download'の緑のボタンを押して'Download ZIP'を選択してください。
・TensorFlowSharpプラグイン: https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Basic-Guide.md Basic Guide > Setting up the ML-Agents Toolkit within Unity > 文中の Download をクリックしてダウンロード。
・Python3(なければ) 以下のコマンドで使っているpythonのバージョンを確認。
$ python --version
ver=3.X.XX でなければpython3をインストール。
$ brew install python3
パスを通すのも忘れずに。
ここまででひとまず必要な環境のインストールは完了。
Unityでシーンを作成
まずはUnityを開いて、新規3Dプロジェクトを作成。
作成したプロジェクトのAssets下にダウンロードした’Unity ML-Agents’のうち、ml-agents-master>UnitySDK>Assets>ML-Agentsの中身をまるごとコピー。
Unityのメニューから Assets > Import Package > Custom Package... でTensorFlowSharpプラグインを選択しインポート。
同様にUnityのメニューから、Edit > Project Settings > Playerで PlayerSettingタブを開く。そこで以下の設定。
- Resolution and Presentation
ーRunin Backgroundをチェック
ーDisplay Resolution DialogをDisabled
- Other Settings
ーScripting Runtime VersionをExperimental(.NET 4.6 Equivalent) ⇒Unity再起動
ーScripting Defined Symbolsに'ENABLE_TENSORFLOW' と記載
先ほどUnityプロジェクトにコピーしてきたフォルダの中からサンプルシーンを開く。(今回は3DBall) 場所は Assets > ML-Agents > Examples > Scenes > 3DBall です。
こんな感じの画面が開けていればOK!
ヒエラルキー(この画面でいうと左上)のBall3DAcademy/Ball3DBrainを選択して右側にインスペクターを表示させる。 Brain.csのところのBrainTypeをExternalに変更。
最後にビルドしてappファイルを作成。具体的にはUnityメニューの File > Build Settingsから 'Add Open Scene'をクリックして先ほど編集した3DBallのシーンを追加。PCを選択し'Build'をクリック。
python側の学習の準備
コマンドライン上でml-agents-master>ml-agentsに移動して以下を打ち込む。必要なパッケージのインストールを行うコマンド。
$ pip install .
学習の実行
参考にしていたページのコマンドでは上手くいかず、公式ドキュメントを見てみたらコマンドが変わっていた。 コマンドライン上でml-agents-master>ml-agentsに移動したまま以下を打ち込む。
$ mlagents-learn /path/to/config/trainer_config.yaml --env=/path/to/app/[appファイル名].app
別画面が立ち上がり、コマンドラインに以下のようなメッセージが表示されて学習の過程が見える。
2018-09-XX XX:XX:XX: INFO:mlagents.envs:Hyperparameters for the PPO Trainer of brain Ball3DBrain: batch_size: 64 beta: 0.001 buffer_size: 12000 ・・・ curiosity_enc_size: 128 INFO:mlagents.trainers: cob_1-0: Ball3DBrain: Step: 1000. Mean Reward: 1.236. Std of Reward: 0.689. Training. INFO:mlagents.trainers: cob_1-0: Ball3DBrain: Step: 2000. Mean Reward: 1.330. Std of Reward: 0.745. Training. ・・・
学習結果
【学習初期】
【35000step後】
待ちきれなくて35000stepで切り上げので、若干たどたどしさはありますが、ボールがほとんど落ちなくなっています。やったぜ。
学習条件を変更したい場合は、trainer_config.yamlファイルの中身を変更すれば良いのだと思います。
次回以降は自分でシーンを作成して学習させていく予定です。
電子工作初心者が シリアル通信方式を分かりやすくまとめてみた
自分の勉強がてら、シリアル通信方式を分かりやすくまとめました。 絶賛勉強中なので、ツッコミどころがあればご指摘いただけると嬉しいです。
全部読むのが面倒な人の為に、最後にシリアル通信方式比較表でまとめています。
そもそもシリアル通信とは何か?
シリアル通信
データ伝送の間、デジタルデータを1ビットずつ順次伝送する接続方式のこと 特徴 :slight_smile: 回線数が少なく低コスト :frowning2: 伝搬速度が遅い ⇒パラレル通信と比較し、長距離間のデータ伝送等に有利
パラレル通信
複数の信号線を利用して複数ビットのデータを同時に伝送する方式 特徴 :slight_smile: 伝送効率が速い :frowning2: 回線数が多く高コスト ⇒同一室内の近距離端末間等で利用される
シリアル通信かパラレル通信か?
ここまで、シリアル通信とパラレル通信、それぞれメリットとデメリットを見てきたが、最近では、通信速度の高度化により、シリアル通信が主流になりつつあるようである。 (詳しい人いたらコメントください)
シリアル通信の同期方式
クロック同期 データ通信用の信号線とは別にクロック信号線を持ち、その信号を用いて送信側と受信側の同期を行う。 以下のような特徴がある。 ・ データ通信用の信号線の他にクロック信号線を必要とするため、信号線の本数が増える ・ データ通信用に信号線が確保出来るため、伝送効率が良い ex.) I2C通信、SPI通信
調歩同期/非同期方式 送受信するデータの前後に"start bit"と"stop bit"を伝送することで、送信側と受信側の同期をする方式。 調歩同期方式とか非同期方式とか呼ばれているよう。名前がややこしい。 以下のような特徴がある。 ・ 同期のためのクロック線を必要としないため、信号線が少なくてすむ ・ データ線とスタートクロック同期に比べ伝送効率は悪い ex.) UART通信
各シリアル通信の特徴をみていく
I2C通信
フィリップス社が提唱した周辺デバイスとのシリアル通信の方式。 一本の信号線がいくつかの役割を担っているイメージ。
特徴 ・マスタ側とスレーブ側を分け、マスタ側が全ての制御を行う ・ データ通信信号線の方向は双方向 ・1バイト転送毎に受信側からACK信号を返送し、互いに確認を取りながら データ転送を行う ・個々のスレーブがアドレスを持ち、データの中にアドレスが含まれる
:slight_smile: 信号線が少なくて済む (2本の信号線から構成される) :frowning2: 伝送速度は遅め (100kbps~1Mbps) 用途 ・同じ基板内など、近距離で直結したデバイスでシリアル通信を行うために使われるのが主。(離れた装置間の通信には不向き)
SPI通信
モトローラ社が提唱した周辺デバイスとのシリアル通信の方式。 それぞれの信号線が各々の役割に集中しているイメージ。
特徴 ・ I2C通信同様、マスタ側とスレーブ側を分け、マスタ側が全ての制御を行う ・ データ通信は、 MOSI / MISO信号各々が、”マスタ→スレーブ”、”スレーブ→マスタ”片方向ずつを担う ・ SS(スレーブセレクト)信号でデータ通信先を指定
:slight_smile: 伝送速度がはやめ (数Mbps) :frowning2: 信号線が3~4本必要 用途 ・同じ基板内など、近距離で直結したデバイスでシリアル通信を行うために使われるのが主(離れた装置間の通信には不向き)
UART通信
調歩同期式によるシリアル通信の方式。 同期のためのクロック線を持たない。
特徴 ・データ通信のための1〜2本の信号線で構成される ー半二重通信(1本):送信と受信を切り替えながら,交互に通信を行う。 ー全二重通信(2本):送信と受信を同時に行うことが可能。ほとんどの UART が対応。 ・ 1バイトの開始と終了を start bit と stop bitで認識
:slight_smile: 信号線が少なくて済む (1~2本) :frowning2: クロック同期式と比較し伝送速度は低速 (0.1~115kbps) 用途(追記予定) ・マイコン間通信? ・マイコンと動作モニタ用の端末を通信や、無線LAN用のモジュールとの通信等
シリアル通信方式まとめ
信号線 | 同期方式 | 通信速度 | 接続形態 | 実際の用途 | |
---|---|---|---|---|---|
I2C通信 | 2本 | クロック(同期式) | 0.1 ~ 1 Mbps | 1対多 | デバイスーマイコン間 |
SPI通信 | 3~4本 | クロック(同期式) | 1 ~ 数 Mbps | 1対多 | デバイスーマイコン間 |
UART通信 | 1~2本 | タイミング信号(調歩同期/非同期式) | 0.1 ~ 115kbps | 1対1(一部1対多) | マイコンーマイコン間 |
参考サイト
参考にさせていただいたページは以下の通りです。
SPI通信の使い方: http://www.picfun.com/f1/f05.html I2C通信の使い方: http://www.picfun.com/c15.html →詳細に、かつ分かりやすくまとめてくださっています。もっと知りたい!という方は目を通してみると良いかも。
調歩同期について: https://synapse.kyoto/glossary/glossary.php?word=%E8%AA%BF%E6%AD%A9%E5%90%8C%E6%9C%9F
【GoogleCloudPlatform】使っているインスタンスにGPUを追加する
東京リージョンでもGPUが使えるようになったけど、新しくインスタンスを立てなおして諸々の設定を最初からやるのは面倒!となったので、既存のインスタンスでGPUを使えるようにどうにか設定しました。 パッケージのバージョンを変更したりなんだかんだあるので、バックアップ推奨です。
環境
CentOS 7.6 python 3.5
インスタンスのマシン構成を変更する
インスタンスを起動している場合は停止させて、インスタンスの編集画面へ。 編集画面のマシンタイプのところのカスタマイズを選択すると"GPUの数"が選べるようになる。
ここで好きなGPU数とタイプを選択し画面一番下の"保存"を選択。 今回はTesla-T4を選択した場合の環境設定手順について書きます。GPUタイプが異なる場合は適宜読み替えてください。 *現在GPUに対応しているリージョンは限られているので注意。もし対応していないリージョンでインスタンスを立てていたら(GPUの選択項目が出てこなければ非対応の可能性高)一旦ディスクイメージを取ってインスタンスを立て直すのが早いかと思います。
ここまで設定したら、もう一度 "開始">"起動" でインスタンスを起動。
ドライバダウンロード
まずはOSのバージョンを確認。
$cat /etc/redhat-release
念のためcuda-9-0が未インストールなことも確認しておきます。
$rpm -q cuda-9-0
NVIDIAのページからCUDAtoolkitをダウンロードしてきます。
$curl -O http://developer.download.nvidia.com/compute/cuda/repos/rhel7/x86_64/cuda-repo-rhel7-9.0.176-1.x86_64.rpm
システムにリポジトリを追加
$sudo rpm -i --force ./cuda-repo-rhel7-9.0.176-1.x86_64.rpm
epel-releaseリポジトリをインストール
$sudo yum install epel-release
Yumキャッシュ削除
$sudo yum clean all
CUDA9.0のインストール
$sudo yum install cuda-9-0
CUDA9.0にドライバが含まれるとの記載もあったが、自身の環境ではうまく動かなかったので手動でNVIDIAドライバをダウンロード。(もしかしたら冗長なのかも。)
$sudo sh NVIDIA-Linux-x86_64-410.79.run
永続モードを有効にする
$nvidia-smi -pm 1
*ここで以下のようなエラーが出た場合はインスタンスの再起動を試してみる
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running
ここまででインスタンスでGPUを使うための準備完了。 ここからはtensorflow/kerasでGPUを使うための準備をする。
cuDNNのダウンロード
以下のサイトでcuDNNをダウンロードする。 今回はlinuxの9.0バージョンを選びました。 https://developer.nvidia.com/rdp/cudnn-download
インスタンス上にダウンロードしたフォルダを配置したらまずは解凍。
そんでもってPATHを追加しておきます。
$export CUDA_ROOT="/usr/local/cuda"
$export LIBRARY_PATH=$CUDA_ROOT/lib:$CUDA_ROOT/lib64:$LIBRARY_PATH
$export LD_LIBRARY_PATH=$CUDA_ROOT/lib64/
source ~/.bash_profile
tensorflow-gpuの導入
地味にこれが面倒だった。パッケージのバージョンはかなり注意しないとという教訓。 このあたりは各自の環境によってもかなり変わるかと思うので、自身の環境を確認しつつ実行してください。
anacondaを使用の場合は以下のコマンドで今の仮想環境のパッケージを確認出来ます。
$ conda list
ここでtensorflowと表示される場合は注意。tensorflow-gpuとは共存出来ないようなので一旦アンインストールする必要がある。(pip経由でインストールした場合はpipコマンドで削除)
$conda uninstall tensorflow
そしてtensorflow-gpuをインストール。最新版のtensorflow-gpuだとエラーになったので、バージョン1.8.0のものを取ってきます。
確認
ここまでで準備は全て出来ました。 動作確認したい場合は以下のコードを実行してみてください。keras使ってる人は念のためそちらも確認しておいた方が良さそうです。
import tensorflow as tf # Creates a graph. with tf.device('/device:GPU:0'): a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3], name='a') b = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[3, 2], name='b') c = tf.matmul(a, b) # Creates a session with allow_soft_placement and log_device_placement set # to True. sess = tf.Session(config=tf.ConfigProto( allow_soft_placement=True, log_device_placement=True)) # Runs the op. print(sess.run(c))
【GoogleCloudPlatform】pythonでGCSバケットのデータを読み出す/書き出す
なんだかんだと時間がかかったので、自分用のメモも兼ねて。
GCP上のインスタンスで、GCS (Google Cloud Storage)のバケット内データを読み書きするpythonコードです。
pythonコードは Anacondaの jupyter notebookで実行しています。
前準備:インストール
まず google cloud をインストール
$ pip install google-cloud
$ pip install google-cloud-storage (2019/01/30修正)
データの読み出し
from google.cloud import storage as gcs bucket_name = バケット名 fname = ファイル名 project_name = プロジェクト名 #プロジェクト名を指定してcliaentを作成 client = gcs.Client(project_name) #バケット名を指定してbucketを取得 bucket = client.get_bucket(bucket_name) #Blobを作成 blob = gcs.Blob(fname, bucket) content = blob.download_as_string()
データの書き出し
from google.cloud import storage as gcs bucket_name = バケット名 fname = ファイル名 project_name = プロジェクト名 #プロジェクト名を指定してcliaentを作成 client = gcs.Client(project_name) #バケット名を指定してbucketを取得 bucket = client.get_bucket(bucket_name) #Blobを作成 #2019/01/30修正 blob = gcs.Blob(fname, bucket) blob.upload_from_string('test')
403エラーが出る場合
VMインスタンスを動かしているPJとは別のPJのGCSにアクセスしようとすると、以下のようなエラーが出た。
- エラーメッセージ
Forbidden: 403 GET https://www.googleapis.com/download/storage/hogehoge: google_service_account_name@developer.gserviceaccount.com does not have storage.objects.get access to bucket_name/file_name.
【Jupyter Notebook】セルの実行が重い
最近はPythonをJupyter Notebook で使う機会が多いのですが、環境を整備していくうちに 「私のJupyter、遅すぎ...?」状態になっていました。
最初は気のせいかとも思ったのですが、同様の症状がある人が他にもいたので、原因を調べてみました。
具体的な症状
・セルを実行していくと、だんだん実行に時間がかかるようになる ⇒[*]表示になってから実行開始までの謎のタイムラグ ・カーネルリスタートすると始めは快適だが、実行していくうち同様の症状が出てくる ・処理の重さは関係なさそう
原因
日本語で調べてみるもなかなかヒットせず...英語のページをあさってみて、やっと見付けた!
どうやら既出の問題だったようです。 https://github.com/ipython-contrib/jupyter_contrib_nbextensions/issues/1275
JupyterNotebookまわりの環境を整える際、nb_extensionsという拡張機能を入れていたのですが、その中の変数インスペクタ機能(Variable Inspector)が悪さをしていたよう。 Spyderぽく使えるし、めっちゃいいやん!と思っていた拡張機能、こいつが原因だったとは...
対処法
対処法はかんたん! nb_extensionsの変数インスペクタ機能(Variable Inspector)をOFFにしたら上述の症状が出なくなりました。
個人的にはすごく便利な機能だったので、使えなくなるのは中々に惜しいですが...仕方ないですかね...