#daiizメモ

Scrapboxに夢中

tfPhotoClassifierをTensorFlow 0.10に対応させた

TensorFlowで画像分類実験をするときに使っている自作ツール「tfPhotoClassifier

を,最新版のTensorFlow(バージョン 0.10rc0)で動くようにした.開発当初からずっとバージョン0.6.0のTensorFlowでしか動かないコードだった.

バージョン0.6.0 → 0.10 では一部のTensorFlowのAPIの呼び出し方が変わっていたり,推奨される振る舞いが変更になっていたりする.ひとまずは動かしながらエラーで躓いたところを探しながらプログラムの修正をした.その時の様子はこちら

コメントをいじったり引数を2行に跨いで関数呼び出しとかをしているので,あまり参考にならないけど,f:id:daiiz:20160807020158p:plain くらいの作業量だった.これから新しく始めるプロジェクトでは最新版のTensorFlowを使いたい.

僕の既存の食神プロジェクトのように色々訳ありでtfPhotoClassifier登場当初のTensorFlow 0.6.0のまま使い続けたいときのために,これまでの版をGitHubリポジトリのリリースに入れておいた.

txtファイルをウェブページに変身させる実験

単なるテキスト(.txt)ファイルをきれいなウェブページに変身させるChrome拡張機能「SimpleWebPage」をつくりました.

デモ

Chromeにあらかじめ拡張機能をインストールしたうえで,サーバから配信される以下のようなテキスト(.txt)ファイル*1を開くと,続くスクリーンショットのように,タイトル文字が大きくなったりリンクが挿入されたり画像が展開されたりします.この拡張機能は.txt?swpで終わるURLに反応します.

Hello, Simple Web!

軽量なウェブページの実現と、読者がページデザインを自由に選択できるウェブページを目指すプロジェクトです。

これは、ただのテキストファイルですがウェブページです。
あらかじめ"専用のChrome拡張機能(*1)"をインストールしておくと、自動的にページがレイアウトされます。
将来的にはいくつかのテンプレートのなかからお好みのウェブページデザインを選択できます。

写真も展開されます。
"肉だけど寿司[*2]"

作者

- "@daizplus(*3)"
- "ブログ(*4)"

おまけ

- "自動レイアウト有効バージョン(*5)"
- "自動レイアウト無効バージョン(*6)"


*1: https://github.com/daiz713/SimpleWebPage
*2: http://images.miil.me/i/08bdc09a-4fee-11e5-a24a-22000aba161e.jpg 300 300
*3: https://twitter.com/daizplus
*4: http://daiiz.hatenablog.com/
*5: https://daiiz-apps.appspot.com/1/hello.txt?swp
*6: https://daiiz-apps.appspot.com/1/hello.txt


スポンサーリンク

うれしいこと

  • ただのテキストなので特段拡張機能を使わなくても読める
    • Markdown記法で配信してもよいけれど,#!などのコンテンツ以外の記号はなるべく使用されないほうが読みやすいと思ったので今回は純粋なテキスト形式
  • HTMLの文法を知らなくて良い
    • このプロジェクトにもいくつか覚える記法はあるけれど,シンプルなルール(を目指している)
    • メモなどを書き換えること無くそのまま公開できる
  • <style>宣言部や,外部CSSの読み込みがないため,データ通信量が減るはず
    • ウェブページに変身するためのCSSは拡張機能がローカルで持っているので通信はない
    • テザリング時も安心

今後

  • テキストの構造的な部分を意識しながらHTMLに変換
  • 拡張機能にページレイアウト(デザイン)テーマを複数種類用意する
    • ベースカラー,カラム数,文字の大きさなどを指定できると良い
  • .txt以外のテキストファイルに挑戦..texでやってみたい
  • WebExtension化
    • Chromeだけでなく,他のブラウザでも使えるようにする
  • スマホアプリ化
    • 本当に必要なテキストコンテンツだけを配信して,ページデザインはアプリ側でやるというニュースアプリを作りたい

関連アイデア

*1:スマホで見ると文字化けする場合がある

GCEでVMインスタンスをつくった

TensorFlowを使った新しい実験プロジェクトを始めたくて,丁度いいLinuxマシンが欲しかった.いまのMacBook Airでやっても良いけれど,計算量が多いので一気にPC本体が熱くてうるさくなるので嫌だった.

そんなに大掛かりなことをやる訳ではないけれど,TensorFlowでの学習中はマシンを他のことに使えなくなってしまうくらいMacBookの動作がもっさりしてしまう.

そのうちGoogle Cloud MLが一般公開されるだろうから,それまでのつなぎとしてGoogle Compute Engine を使うことにした.

  • Machine Type: n1-standard-1
  • Virtual CPUs: 1
  • Memory: 3.75GB
  • 永続化ディスク: 10GB
  • OS: Debian

という構成で借りた.GCEのインスタンスは,使用した時間分(VMインスタンスを起動していた時間分)だけ課金される.停止させている間はディスクのぶんだけで済む. 今回の構成は,万一1ヶ月起動しっぱなしだったとしても29ドルくらい*1.これくらいの額だと失敗したときも安心.

さっきSSHして

をインストールしてきたので開発準備は整った.

IDE PyCharmでPythonを書いてVMで動かしたい場合は,手元のMacBookで書いたものを更新の度にSFTP転送するか,git push / pull するしかないのだろうか. それとも,VM上のPythonファイルを直接編集しているような気分になれる凄い機能とかあるのだろうか

*1:GCPのウェブUIでVMインスタンスを作成するときに予算が提示される

Google App Engine/Python, Google Cloud Storage で特定のユーザーのみに画像を返す

Google App Engine / Python と Google Cloud Storage を使って,HTTP/GETでリクエストをもらったときに,特定のユーザーだけにコンテンツを返却する仕掛けを作る.

  • 「特定のユーザー」であるかどうかはGoogleアカウントでログイン中のユーザーのGmailアドレスで判断する.
  • 「コンテンツ」はどのようなファイルでもOK.今回は画像を用いる.

ざっくりとした手順とプログラムを紹介する.

GCS にファイルを置いておく

プログラムで画像を生成させてGCSに保存したり,コマンドラインからアップロードしたりできるけれど,今回はウェブUIで操作してファイルを保存する. f:id:daiiz:20160727013102p:plain:w450

GAE のプログラムを書く

メインの部分だけ載せます.

from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers

# コンテンツにアクセスできるユーザーのGmailアドレス
MASTER_USERS = []

def is_master_user(user):
    if user is None:
        return False
    return user.email() in MASTER_USERS

# 予め登録されたユーザーのみにコンテンツを返却する
class GCSServingHandlerPrivate (blobstore_handlers.BlobstoreDownloadHandler):
    # /gs-p/<BUCKET_NAME>/<DIR_NAME>/<FILE_NAME>
    def get (self, bucket_name, dir_name, file_name):
        user = users.get_current_user()  # ログイン中のユーザー情報がわかる
        if is_master_user(user):
            blob_key = blobstore.create_gs_key('/gs/%s/%s/%s' % (bucket_name, dir_name, file_name))
            self.send_blob(blob_key)
        else:
            # 登録されていない場合は代わりの画像を返す
            blank_key = blobstore.create_gs_key('/gs/daiiz-bucket-1/public/illust.png')
            self.send_blob(blank_key)

あとはwebapp2.WSGIApplicationのルーティングの設定を追加する.

app = webapp2.WSGIApplication([
    ...
    ('/gs-p/(.+)/(.+)/(.+)', GCSServingHandlerPrivate),
    ...
])

アクセスしてみる

以下に,実際に https://daiiz-apps.appspot.com/gs-p/daiiz-appspot/test/sushi.jpg<img>で読み込んでみる.

僕は「予め登録されたユーザー」に含まれているので,京都の寿司の写真が見られるけれど,僕以外の人がアクセスした場合はキャラクターのイラストが写っていれば大成功.

感想

GAEとGCSは触っていて楽しい

今週のリリース(7月 第1週)

今週のリリースです.

SVG Screenshot

ついに,アプリのアイコンが決定しました! 高校の頃からの友人で,美術センス抜群のまれ (@maremarecosmo)さんに描いて頂きました.
ちなみに,僕のプロフィールアイコンid:daiizもまれさんが描いてくれたものです.

これを機にChrome拡張機能v0.1.3をリリースしました.
SVG Screenshot - Chrome Web Store

アイコンの変更に加えて,

  • 選択した文字列をスクリーンショットに保持する
  • 保持された文字列をビューワページで表示する

のような新機能が搭載されています.

以下のアニメーションのように使います.とても便利です.

1.スクショを撮りたいページで右クリックして「SVGスクリーンショットを撮る」メニューをクリック

https://i.gyazo.com/2426c4dece26afb1d1ca92e8b4994964.gif

2.スクリーンショットに含めたい文字列を選択

https://i.gyazo.com/3e03e92dc24487d101b34d2ba9719e5b.gif

3.撮りたい領域を決定して,切り取りボックスをダブルクリック

https://i.gyazo.com/66ac017e4bc6638e6daf6ce1d9d5bb7f.gif

4.スクリーンショットファイルをアップロード

https://i.gyazo.com/708eb8383cde451f2d1efb5cf148d064.gif

5. マイ・スクリーンショット一覧ページから先程のスクリーンショットを選んで開く.ページ右上のテキストを表示するボタンをクリックして,保持された文字列を表示

https://i.gyazo.com/dc5dc15935433c8cad6a6c6b712079e8.gif

少しずつではありますが今後も改良を続けてゆきます.

【日記】KotlinをGAEで動かす準備をした

今日の朝〜昼までかけて,大学の研究用のデモで使う開発環境を整えた.

IntelliJ ✕ Google App Engine ✕(Java + Kotlin)

というような,ずっと試したかった組み合わせ.初めて使うものも多いけど頑張ろう. デプロイはしないプロジェクトになりそうだが,いいものを作りたい.

「Python ✕ GAE」は試したことがあるので,これと同じ要領でRESTful APIを返す環境を簡単に作れると思ったが,少し難しかった. Google Cloud Endpoint というのを使うと良いらしいが,そこまで大げさにしなくて良いので,Restlet を採用した.Restletは使いやすいけれど,選択として正解かどうかは自信がないのでもっと良いものがあったら教えてください!

いまマックのポテトLを食べて体力復活させてきた.

ヤパチー行きたかったな.

今週のリリース(6月 第4週)

小さなリリースをまとめて書くコーナーです.

SVG Screenshot for Web

自分が撮影したスクリーンショットの一覧画面で絞り込み検索が可能になりました. SVG Screenshot ウェブアプリについてはこちらの記事をご覧ください.

https://i.gyazo.com/4c9a12c1ebc99531eba59d944cdc0b1e.gif

SVG Screenshot (beta)

f:id:daiiz:20160229233044p:plain:h56

Chrome Apps Launcher (Chrome拡張機能)

f:id:daiiz:20160703032313p:plain:h350
▲ アプリを一覧表示した様子

f:id:daiiz:20160703032406p:plain:h350
▲ 接頭辞:を用いてパッケージ化されていないアプリのみを検索した様子

公式のChrome アプリランチャーが廃止されてしまったので代替品を作った.Chromeの拡張機能としてインストールできて,ほぼ同様な機能が使える.

プラスアルファ機能として

  • 「chrome://apps/」でもインストールされたアプリを確認できるが,なぜか検索ボックスが用意されていなくて不便だったので検索窓を付けた.
  • 開発者としていくつかパッケージ化されていないアプリもインストールしているので,これらのみを対象にして検索する機能も付けた.

のようなことができる.

GitHubで公開していますので,よろしければご利用ください.Chromeウェブストアに出品する予定はありません.

github.com

f:id:daiiz:20160309005235p:plain:h56

以上です.来週も頑張りましょう!

legacy packaged apps ってなんだ

Chrome アプリ開発メモ

拡張機能のページでプロジェクトを読み込んだときにこんなメッセージが出た.

'hoge' is only allowed for extensions and legacy packaged apps, but this is a packaged app.

'hoge'というのは使おうとしていたChrome Apps APIのことで,色々ある.

このメッセージが言いたいことは,

  • API 'hoge' は拡張機能(extensions)または旧版のパッケージアプリ(legacy packaged apps)でのみ使える.
  • しかしこのプロジェクトは,現行のパッケージアプリ(packaged app)である.(→ つまりAPI 'hoge' は使えない)
f:id:daiiz:20160309005235p:plain:h56

こんな状況下で,API 'hoge' を使いたい場合は

  • legacy packaged apps 化する
  • appsではなくてextensions化する

のどちらかの方法が考えられる.しかし, legacy packaged appsはlegacyであり,既に廃止が決定されている.したがってextensionsにするしか道はない.

ちなみに,manifest.json のappフィールドが

"app": {
    "background": {
      "scripts": [
        "background.js"
      ]
    }
}

のような形をしていれば legacy ではなくて,

"app": {
    "launch": {
      "local_path": "index.html",
      "container": "panel"
    }
}

であれば legacy な packaged apps である.

確かに後者はむかし(Chrome アプリが登場したての頃)よく書いていた気がする.

写真を与えると食神定食番号が判定されるウェブアプリをつくりました

食神590円定食シリーズの写真が何番定食であるかを識別する実験サイト「Shokujin Classifier」をつくりました.この前行った最新の学習成果に基いて判定されます.現時点では,1,3,4,5番定食に対応しています。

https://shokujin-classifier.herokuapp.com/

f:id:daiiz:20160628122239p:plain

Herokuの無料プランで動かしているため,読み込みに時間がかかることがあります.本当はGoogle App Engineで動かしたかったのだけど,GAEの環境にTensorFlowを入れる方法が分からなかったのでHerokuになりました.

サイト内にサンプル画像も用意してありますので,是非お試しください.

SVG Screenshot のウェブアプリを公開しました

SVG形式でウェブページのスクリーンショットを撮るChrome拡張機能「SVG Screenshot」をより便利に使うためのウェブアプリを Google App Engine で公開しました.SVG Screenshotのコンセプトについては以下の記事をご覧ください.

この記事では

  • ウェブアプリでできること
  • Chrome拡張機能とウェブアプリの融合(撮影したファイルをウェブアプリにアップロードして保存する機能)

について,順に紹介します.

ウェブアプリでできること

スクリーンショットファイルを表示する

https://svgscreenshot.appspot.com/viewer にアクセスすると,これまで拡張機能に付属していたものと同様なビューワページが開きます.拡張機能で生成されたスクリーンショットSVGファイルを,中央の白い領域にドラッグ・アンド・ドロップすると内容を表示できます.

https://i.gyazo.com/c3a53f77ea0f4ba8f392034137513259.gif


このページを使えば,拡張機能をインストールすることなく,友人から受け取ったSVGスクリーンショットファイルを閲覧することができます.

スクリーンショットファイルをクラウドに保存する

この機能を使ってアップロードしたファイルは,アップロードした本人だけが閲覧/削除できます. この機能はGoogleアカウントでログインした状態でご利用ください.ページ右上の「Googleアカウントでログインする」リンクからログインできます.

ログインが完了していると,さきほどのビューワページの右上にのアイコンボタンが現れます.このボタンをクリックすると,表示中のSVGスクリーンショットファイルがウェブ上に保存されます.

f:id:daiiz:20160620040103p:plain:w450


アップロードが完了すると,画面下部に完了のメッセージが表示されます.

アップロードしたファイルを閲覧/削除する

ビューワページの左上「ホーム」リンク,または,https://svgscreenshot.appspot.com/ にアクセスすると,保存されたファイルが一覧表示されます.

f:id:daiiz:20160620035259p:plain:w450

スクリーンショットカードをクリックすると,ビューワページにファイルが表示されて閲覧できます.カードの右上に表示されるボタンを押すとファイルが削除されます.

f:id:daiiz:20160320041319p:plain:h65

Chrome拡張機能とウェブアプリの融合

本日リリースされた最新版の拡張機能では,上記で紹介したウェブアプリの機能を直接的に使用することができます.手順をご紹介します.

Chrome拡張機能「SVG Screenshot」をインストール

Chrome ウェブストアでの配布ページ にアクセスして,最新版の拡張機能をインストールします.

スクリーンショットを撮影する

ウェブページ上で右クリックして表示される「SVGスクリーンショットを撮る」を押すと,撮影範囲を選択する灰色のボックスが現れます.

f:id:daiiz:20160620035103p:plain:w450



これを好きな場所に移動してダブルクリックすると撮影されます.

f:id:daiiz:20160620034931p:plain:w450
スクリーンショットをアップロードする

撮影が完了すると,プレビューページが開きます.このページでは従来の「Download SVG」機能に加えて,「Upload SVG」機能が利用できます.ページ右上でログイン状態であることを確認して,「Upload SVG(ログイン時のみ)」をクリックすると,スクリーンショットがウェブアプリに保存されます.

f:id:daiiz:20160620035018p:plain:w450

繰り返しになりますが,保存されたファイルのリストは https://svgscreenshot.appspot.com にて,どの端末からでも確認できます.

f:id:daiiz:20160320041319p:plain:h65

最後に

お知らせ
  • ウェブアプリ「SVG Screenshot for Web」は現在ベータ版です.
  • Google Chrome でのご利用を推奨しています.
  • 現時点で,ユーザーお1人当たりがアップロードできるファイルの上限は4個です.ウェブアプリが軌道に乗り次第,上限値を増やしていく予定です.(上限の変更が生じた場合は,このブログでお知らせします.)
お願い
  • パスワードが写ったスクリーンショットなど,アップロードすることが不適切と思われるファイルのアップロードはおやめください.
  • スクリーンショットファイルのバックアップは必ずご用意ください.

リンク

どうぞご利用ください!

クラスタリングの様子を眺めた

最近はクラスタリングの実験をしている.様々なクラスタリングアルゴリズムをJavaで実装しながら精度を観察している.

クラスタリング結果として,各クラスタの中心ベクトルと何番目の訓練データ点がどのクラスタに入ったかをテキストログとして眺めていた.しかしこれだと,上手くいったり失敗したりしたときに原因を探しにくい.そこで,「Cluster Visualizer」というものを即席で作って可視化に挑戦した.

Cluster Visualizerは,あくまで補助的なツールなので,既に作ってあるJavaプログラムを大きく変更するようなことはしない.毎回のクラスタリング試行ごとに,以下のような一行ログを追加出力するだけで良い.

[Cluster Visualizer]  {"0": [1, 3, 5, 7], "1": [0, 2, 4, 6]}

これは「0番目のクラスタに1, 3, 5, 7番目の訓練データ点が,1番目のクラスタに0, 2, 4, 6番目の訓練データ点が属している」ことを表している.

このような結果ログと,N次元の訓練データセットを3次元に次元削減したものをテキストファイルで用意する.次元削減は「TensorFlowで画像分類した定食たちの銀河をつくった - ShikousakuGo」と同様に行った.クラスタを描画するのはThree.jsで頑張った.

こんな感じで,画面下部のスライダー操作ボタンでクラスタリングの様子をアニメーションできる.

https://i.gyazo.com/a31c9c1d04e7d28fe68e2894c7c6c7e6.gif

様子が目で見えると安心感がある.

自分でデータセットを作るときにも重宝した.どうもクラスタリングの挙動がよろしくなかったので,訓練データセットを教師ラベル別に色分けしたものを表示してみると,うまく2クラス分類できそうな形をしていなかった.

https://i.gyazo.com/d0468709e8ee291ef1febb4651a48304.gif

ほぼ一日でここまで作れたのは良かったと思う.もう少し作り込んだら実験ツールとして公開したい.