Hatena::ブログ(Diary)

Over&Out その後 このページをアンテナに追加 RSSフィード Twitter

2016-09-14

iOS 10の新機能のサンプルコード集「iOS-10-Sampler」を公開しました

iOS 10でも大量のAPIが追加されました。が、新しいAPIはどう使うのか、実際に何がどこまでできるのか、といった具体的なところが、英語のドキュメントやWWDCのセッション動画をながめているだけだと正直あまりピンときません。やはり実際にコードを書いて動かしてみるのが一番わかりやすい・・・ということで今年もつくりました!


iOS-10-Sampler


f:id:shu223:20160914063446j:image:w600


恒例の新機能のサンプルコード寄せ集めアプリです。ソースコードは GitHub に置いてあるので、ご自由にご活用いただけると幸いです。


使い方は Xcode 8 でビルドするだけ なので、デザイナーさんやディレクターさんもぜひお近くのエンジニアにビルドしてもらってください。


f:id:shu223:20160914072119j:image:w600


iOSももうかなり成熟してしまい、話題になる革新的な新機能とか、どの開発者にとっても嬉しい新機能というのはなかなかないわけですが、実装してみると思ったより簡単なので自分のアプリにも取り入れたくなったとか、他の誰も話題にしてないけど自分的には熱いみたいな機能もあったので、ぜひ一度お試しいただけると嬉しいです。


また、Samplerシリーズでは「余計な実装を混ぜずに、新機能のメリットをできるだけシンプルな実装で伝える」というところに気をつけています *1。コピペもしやすいと思うので、自分のアプリに取り入れて動かしてみるとより楽しいかもしれません。


今のところ17個のサンプルが入っています。随時追加していきます。機能追加プルリク大歓迎です!


以下各サンプルの紹介です。


Speech Recognition

新たに追加された Speech Framework を利用した音声認識のサンプルです。


f:id:shu223:20160914070235j:image:w405


Appleのサンプルをベースに、全58種類の対応言語を選択する機能を追加しています。


Looper

AVFoundationに新規追加されたクラス AVPlayerLooper を用いた動画のループ再生のサンプルです。


f:id:shu223:20160914070311g:image:left f:id:shu223:20160914070308g:image



このクラス自体はプレイヤー機能は持っておらず、AVQueuePlayer と AVPlayerItem のインスタンス、そしてループする範囲を示す CMTimeRange オブジェクトを渡して使用します。

public init(player: AVQueuePlayer, templateItem itemToLoop: AVPlayerItem, timeRange loopRange: CMTimeRange)

Live Photo Capturing

写真撮影用に追加された新クラス AVCapturePhotoOutput を使用したライブフォト撮影サンプルです。*2


f:id:shu223:20160914070434j:image:w200


Live Photo のビューワーは iOS 9.1 から使えましたが、今回から撮影もできるようになりました。


Audio Fade-in/out

すごーく地味だし、このAPIがなくてもできたといえばできたことなんですが、実際に使う人は多いかもしれません。AVAudioPlayerにフォードイン/アウトするためのメソッドが追加されました。

// Fade In
player.setVolume(1, fadeDuration: 3)

// Fade Out
player.setVolume(0, fadeDuration: 3)

これタイマーとかでやってた人は嬉しいんじゃないでしょうか。


Metal CNN Basic: Digit Detection

Metal Performance Shaders フレームワークに追加されたCNN (Convolutional Neural Network / 畳み込みニューラルネットワーク)を用いた手書き数字認識のサンプルです。*3


f:id:shu223:20160914070517g:image


この「Metal AcceleratedなCNN計算処理」は個人的には今回一番熱い新機能です。



Metal CNN Advanced: Image Recognition

上のサンプルに引き続き、Metal Performance ShadersのCNNを利用したリアルタイム一般物体認識のサンプルです。*4


f:id:shu223:20160914070509g:image


速くて見づらいかもしれませんが、ノートパソコン(notebook)→ リモコン(remote control) → iPhone(iPod)と認識しています。


Metal ShaderというぐらいなのでGPUで処理されます。6s利用ですが、処理速度も申し分なしでした。(ちなみにMetalはAppleのハードウェアに最適化されたグラフィックスAPIで、「OpenGLより最大10倍速い」と言われています)


ちなみにミスリードもあるかもしれないので念のためですが、「一般物体認識」という新機能があるわけではないです。本サンプルで使用しているモデルはImageNetデータセットを用いてInception v3ネットワークをTensorFlowで学習させたもので、新機能はあくまで「Metal(GPU)でCNN処理」という部分になります。


PropertyAnimator: Position

アニメーション用の新クラス、UIViewPropertyAnimatorを用いて UIView オブジェクトの位置と、背景色をアニメーションさせるサンプルです。


f:id:shu223:20160914070727g:image


画面上をタッチしたままグリグリと動かしてみてください。touchMovedが呼ばれるたびにアニメーションが追加するという単純な処理をやっているのですが、いい感じに追随してくれるのが今回のクラスがアニメーションの追加をいい感じにやってくれてる *5 おかげなのかなと。


PropertyAnimator: Blur

UIViewPropertyAnimator の `fractionComplete` を用いて UIVisualEffectView / UIBlurEffect のブラーをアニメーションさせるサンプルです。


f:id:shu223:20160914070720g:image


やってることは超シンプルで、`effect` プロパティから UIBlurEffect を削除する処理を UIViewPropertyAnimator に登録しておいて、

animator = UIViewPropertyAnimator(duration: 0, curve: .linear) {
    self.effectView.effect = nil
}

スライダーの値に応じて `fractionComplete` を変化させています。*6

@IBAction func sliderChanged(sender: UISlider) {
    animator.fractionComplete = CGFloat(sender.value)
}

Preview Interaction

新クラス、UIPreviewInteraction で、3D Touchでピーク&ポップするサンプルです。


f:id:shu223:20160914070939g:image


Notification with Image

新しい通知のフレームワーク、UserNotifications framework を用いて、画像付きローカル通知を発行するサンプルです。


f:id:shu223:20160914033106j:image:w200:left f:id:shu223:20160914033113j:image:w200



Sticker Pack

iMessage のステッカーパックのサンプルです。


f:id:shu223:20160914032800j:image:w200


Messagesってメッセンジャーアプリとしてどれだけのシェアがあるの?という声も効きますが、ステッカーパックは画像をアセットカタログに入れていくだけの超超簡単実装なので、いい感じの画像を持っているアプリはやっといて損はないのかなと。


Core Data Stack

NSPersistentContainer を使うと Core Data の実装がシンプルになるよ、というサンプルです。


f:id:shu223:20160914034038j:image:w200


noliliさんよりpull requestいただきました!


TabBar Customization

UITabBarのバッジをカスタマイズするためのAPIが追加されました。*7


f:id:shu223:20160914034330j:image:w200


センスがなく、全然いい感じにカスタマイズできてないのが心残りですが。。


New filters

CIFilterで追加されたフィルタのサンプル。


f:id:shu223:20160914034350j:image:w200:left f:id:shu223:20160914034353j:image:w200



前回は豊作だったのですが、今回はちょっとしかありませんでした。。


New Fonts

新規追加されたフォントのサンプル。こちらも今回は少なく、4種だけ。*8


f:id:shu223:20160914034359j:image:w200


Proactive: Location Suggestions

NSUserActivityに新たに追加された `mapItem` プロパティを用いた "Location Suggestions" のサンプル。


f:id:shu223:20160914054654j:image:w200:left f:id:shu223:20160914071309j:image:w200



いわゆる「Proactive」というやつで、Appleから出てるサンプルがあるのですが、どの実装が何に効いているのか、というかこのサンプルをどう試すのか、というのがちょっとわからず(WWDCセッションをちゃんと見ればいいのかもしれませんが)、下記記事に助けられました。


Attributed Speech

AVSpeechUtterance に、NSAttributedStringを渡せるイニシャライザが新たに追加されたので、これを試すデモです。


NSAttributedString は文字列に色んな属性を指定できるわけですが、


これを音声合成の「Utterance」に渡せるということは、例えば、NSFontAttributeNameを用いてある範囲のフォントをboldにすると、その部分だけ強調されて発声されるとか、何か別の属性を使ってアクセントを制御できるとか、そういうことを期待したわけです。


が、結果は・・・何も起こりませんでした



同ツイートのメンションで岸川さんから `kCTLanguageAttributeName` で言語を切り替える、`kCTRubyAnnotationAttributeName` でルビをふる、といった文字列だけではなくて音声にも有用そうな属性を示唆いただきましたが、これらを試してみてもやはりあり/なしで違いは発声しませんでした。


何か私の実装が間違っているのかもしれませんし、プルリクをいただけるかもしれないので、サンプルとしては残してあります。


所感

箇条書きで。。

  • Notificationのカスタマイズ、ロック画面でプレビューは嬉しい
  • 標準で、ローカルで音声認識ができるようになったのも嬉しい
  • MPSCNNは熱いのでここはもっと勉強したい
  • iMessage app / Sticker Pack は当初まったく期待してなかったけど自分でやってみるとその簡単さとやっておいて損はない(親アプリがiOS 9でもok)という点で意外と熱い
  • UIViewPropertyAnimator、あまりワクワクするような新しさのあるものではなかったが、従来のものよりは便利なのでiOS 10以上のアプリでは普段使いすると思う
  • 3D TouchでPeek&Popは3D Touchデバイスが普及するまでは静観
  • Proactiveは今は静観
  • SiriKitは良いサンプルが思いつかず今回は入れなかった

デュアルカメラとか、Taptic Engine APIとか新デバイス系はまた後ほど。


おわりに

最初は個人的な勉強として始めたものがすっかり恒例になって、もうかれこれ4年もこれをやっています。


f:id:shu223:20160914061757j:image:w320


これがまぁなかなか大変で、それなりに時間がかかるので、周りの人には毎年「今年はやらないかも」とか毎年言ってて、なんだかんだやっぱり今年もつくってしまったという。







まぁ自分はやっぱり「新しいAPIが追加されると開発者としてできることが増える」のが好きなのと、(冒頭に毎年書いていることですが)自分で手を動かさないと全然理解できないというのがあるので、これはやっぱり続けた方がいいなと。


そんなわけで Apple Watch Series 2 が届いたら「watchOS-3-Sampler」もつくりたいと思います!


*1:Appleによる公式サンプルではアプリとしての体裁を整えるために新機能とは直接は関係ない実装がたくさん入っていたりしてややこしくなっているケースが多々ある

*2:Appleの「AVCam」サンプルをベースに、Live Photo撮影の実装だけを抜き出し、シンプルにしたもの

*3:本サンプルは、Appleの「MPSCNNHelloWorld」サンプルをベースに、不要な実装を除去しシンプルにしたもの

*4:本サンプルのモデルデータと、ネットワークの実装は、Appleの「MetalImageRecognition」サンプルをベースにしています

*5:WWDC16のセッション216でそんな感じのことを言ってました

*6:この手法は、こちらのコードで知りました: https://github.com/manuelCarlos/IOS10-Animate

*7:これらの追加APIについては、こちらの記事で知りました: [iOS 10] UITabBarのバッジを少しカスタマイズできるようになった - Qiita

*8:しかもFutura、AmericanTypewriterは従来からあるfamilyの太さ違い

2016-09-02

iOSDCのリジェクトコンで『iOSとディープラーニング』について話しました #iOSDCRC

一昨日メルカリさんのオフィスで開催された iOSDC Reject Conference days2 で、「iOSとディープラーニング」というタイトルで登壇させていただきました。



大層なタイトルですが、僕はディープラーニングや機械学習について詳しいわけではなく、「これから勉強したい」だけの素人です。iOSDCのCFPではLT枠の場合はトーク概要を書く必要がなかったので、タイトルは大きめにしておいて、内容は勉強の進捗に応じて、という算段でした。


で、先週あたりから夜な夜なこのへんの勉強をしていて、

この次に「自分でモデルをつくる」というステップに進みたかったのですが、次から次へとわからないことがでてきて、結局「誰かがつくったサンプルを動かす」「拾ってきたモデルを使う」止まりの発表になってしまいました。


そこは引き続き精進してまいります、ということで、以下補足を。


iPhoneでInception-v3モデルによるリアルタイム物体認識を動かす

TensorFlowのInception-v3を使った一般物体認識のデモをiPhoneで動かしたときの動画がこちらです。


f:id:shu223:20160902082200g:image


最初 [Notebook] [Laptop] を認識していて、カメラが下の方にいくと [Computer Keyboard] の順位が上がり、リモコンを映すと [Remote Control]、メガネを映すと [Sunglasses] が候補の上に上がってきます。*1


パフォーマンスもなかなかではないでしょうか。(用いたデバイスがiPhone 6sなので、ちょっとずるいですが。。)


サンプルを試す手順の詳細は下記記事にあります。


iOS 10で追加されたニューラルネットワーク機能群

LT5分だったのでここまで話せなかったのですが、iOS 10では2つのフレームワークにニューラルネットワークを高速計算するための機能群が追加されました。


ひとつは BNNS (Basic Neural Network Subroutines) と呼ばれていて、Accelerate Framework に新規追加されました。Accelerate は CPUで高速計算を行うためのフレームワークです。


そしてもうひとつは CNN(Convolutional neural network) で、MetalPerformanceShaders Frameworkに新規追加されました。Metal Performance Shaders はGPUで高速計算を行うためのフレームワークです。


で、どちらも同じような用途の機能が用意されていて、素人からするとGPUで処理するほうが良さそう、と思うのですが、わざわざ2種類出してきたからにはきっと一長一短あるのでしょう。もっと詳しい方が書いた記事があり、その記事ではこれらの比較についてこう述べられています。

AccelerateとMetalは、非常によく似たニューラルネットワーク関数群を提供しているので、どちらを選択するかは、各アプリケーションに依存します。GPUは、通常、機械学習に必要な種類の計算には望ましい反面、データの局所性によって、Metal CNNのパフォーマンスが、Accelerate BNNSバージョンより劣る場合があります。GPUにロードされた画像上でニューラルネットワークを動かす場合、例えば、MPSImageと新しいMPSTemporaryImageを使うと、Metalの方が明らかにパフォーマンスが上です。


MPSCNNのサンプル

BNNSの方も公式サンプルはあるのですが、今のところMac OS X用のものしかありません。MPSCNNの方はメリットやパフォーマンスを把握するのに最適なiOS向け公式サンプルが2つ出ています。

  • MPSCNNHelloWorld・・・MPSCNNで手書き数字認識
  • MetalImageRecognition・・・MPSCNN+Inceptionモデルで物体認識

ちなみに"MPS"は MetalPerformanceShaders のプレフィックスで、CNN関連の機能にはMPSCNNというプレフィックスが付いています。


で、上の手書き文字認識の方(MPSCNNHelloWorld)がシンプルで非常に理解しやすく、最初の一歩にすごく良いです。ベータ期間中につきサンプルのスクショは控えます。


f:id:shu223:20160902080706j:image:w500


上の画像(発表資料p35)はWWDC16のセッションスライド内にあった多層ネットワークの概念図に、該当するMPSCNNのクラス名を書いたものですが、わりとそのまんまで、CNNの概念を理解していれば非常に使いやすそうです。

  • Convolution Layer(特徴量の畳み込みを行う層): MPSCNNConvolution
  • Pooling Layer(レイヤの縮小を行い、扱いやすくするための層): MPSCNNPooling
  • Fully Connected Layer(特徴量から、最終的な判定を行う層): MPSCNNFullyConnected

(参考:Convolutional Neural Networkとは何なのか - Qiita


iOS 9以下でも使えるオープンソースのDL/NNライブラリ

iOS 10の話ばかりしても現実感がないかもしれませんが、"ios deep learning" とか "ios neural" とか "swift neural" とかでGitHub検索するとOSSがざくざく出てきます。


そのうち、100スター以上ついているものをピックアップしてみました。


f:id:shu223:20160902080845p:image:w500


TensorFlowがサンプル含めObjC、C++であるのに対して、Swiftで書かれているものも多いですし、Metal or Acceleratedフレームワークで高速化してあるものも多く、充実している印象です。


が、いざ試してみようとすると、サンプルもなかったり、最近はメンテされてなさそうだったりで、実際に使えるのは実はあまり多くないのかも、とも思いました。


もっともスターが多くついている「Swift-AI」については下記記事で紹介しています。


ディープラーニングの基本概念を学ぶのに良かった本

発表内では触れてないのですが、ディープラーニングというか人工知能というかそういう系の話はWebに解説記事も多く、逆にどこから手を付けていいかわからない、という状態に長らく陥っていました。で、とある機会に会ったこの分野でゴリゴリやってる人に教えてもらったのが下の書籍です。


脳・心・人工知能 数理で脳を解き明かす (ブルーバックス)
講談社 (2016-05-27)
売り上げランキング: 6,089


人間の脳のしくみから読みやすい文章で紹介してあって、いきなり数式ベースの解説があると「また今度にしよう」となってしまう自分には入り口として最適でした。


今後の展望

TensorFlowにしろiOSのBNNS/CNNにしろ、学習済みモデルの中身というかフォーマットがよくわかってないので、次はそのあたりを調べたいと思ってます。


*1:このとき食べていたアイスクリームも見事に認識してくれたのですが、食べかけだったのでカットしました

2016-08-22

iOSDCで発表しました『海外のiOSカンファレンスに登壇する - 完全版』 #iOSDC

先週の金・土に練馬で開催された600人規模のiOSカンファレンス「iOSDC 2016」にて、『海外のiOSカンファレンスに登壇する - 完全版』というタイトルで発表させていただきました。


f:id:shu223:20160820103328j:image:w600


応募時に書いたトーク概要はこちら

ベルリンの「UIKonf」、ロンドンの「iOSCon」、サンフランシスコの「AltConf」と、今年は3つの海外のiOSカンファレンスに登壇する機会に恵まれました。


とはいえ招待されたわけではなく、CFPに自ら応募して投票・審査の上で採択された結果です。


本発表では、海外カンファレンスに参加するメリット、CFPの探し方、発表の準備、実際の登壇でうまくいったことや失敗したこと等について話します。


海外のiOSカンファレンスに登壇するためのノウハウ集、というよりは、英語がそんなに得意でもない自分が、どう四苦八苦しつつも海外登壇までこぎつけたのか、その結果どうだったのかという失敗談多めの内容となっております。


動画がこちら。このトークでは埋め込みの音声や動画が重要な役割を担っているので、スライドよりも動画のほうが伝わるかなと思います。


発表スライドはこちら。


以下、裏話や当日の様子について書きたいと思います。


裏話その1: 実行委員長 長谷川さんの神対応

開催前にこういうツイートをしました。


そう、僕の出番はゲストスピーカーである岸川さんの裏にどーんとぶつかっていたわけです。


実は、スタッフの方のひとりと飲む機会があり、事前にこのタイムテーブルについて知ることができたのです*1が、「そんなの誰も来てくれるわけがない・・・」とFacebookで長谷川さんに突然の友達申請をし、長いDMを送り、何とかなりませんかと泣きつきました。


そんな突然かつ面倒なメッセージに対して、長谷川さんは「なぜこういうタイムテーブルになったか」という意図について大変詳細かつ丁寧なご説明を返信で書いてくれて、僕は深く納得し、誰も来ないかもしれないけど(草の根集客活動含め)がんばろう、と思うに至った、ということがありました。(さすがにDMをここに載せることはできないのですが、それにしても朝イチのお客さんの流れとか色々考えられていて感動を覚えるほどでした)*2


結果的には、想像以上に多くの方に来ていただけたし、あと個人的にも出番を朝イチで終えてカンファレンスを存分に楽しめたしで、これで本当に良かったなと。めちゃくちゃお忙しい中、めんどくさい登壇者の個別問い合わせに懇切丁寧に対応してくださった長谷川さん、ありがとうございました🙇🏻🙇🏻🙇🏻


裏話その2: 発表時間

前日夜の時点で15分の発表時間に対して30分以上もかかる、ということに気付きまして、


とりあえず寝て、朝起きたら何となく整理がつくだろうと思ったのですが、



全然整理がつかなかったのです。。


で、とりあえずスライドを削るのはあきらめて、「全部は説明せずに流れが分かる程度にだけ説明する」というページに印をつけておいて*3、その辺を飛ばしながら話すことで、Q&A用の時間もフルに使った19分30秒でなんとか話し切ることができたのでした。(ギリギリですいませんでした🙇🏻🙇🏻🙇🏻)


当日の様子

手元に写真がない *4 ので、会場に来られていた方々のツイートをお借りしつつ会場の様子をお伝えしたいと思います。












関連記事:


おわりに

iOSDC、登壇者としてもいち参加者としてもめちゃめちゃ楽しかったです。トークは勉強になるし面白かったし、アイコン入りの大きめサイズのネームプレートとか、懇親会のビールとか、いろんなところに愛とこだわりを感じるカンファレンスでした。あと参加した人達みんなが口を揃えて言っていたことですが、初回にしてこんなに滞りなくいい感じに進むのってすごいことだと思います。


こんな素晴らしいカンファレンスを主催された長谷川さん、超ハードに動かれていたスタッフのみなさまには本当に感謝です。



そしてチケット代がたったの4000円。僕はトークが採択される前にスポンサーチケット(8000円)を購入していたのですが、この内容でこの値段、お得すぎます。スポンサー企業のみなさまには足を向けて寝られません。チラシにしっかり目を通してサービスを積極的に利用させていただきます。


来年もあればぜひまた参加させていただきたいと思います。ありがとうございました!


関連記事


お知らせ

iOSDC Reject Conferenceにもday1、day2両方とも出させていただきます。


day1はこちらのテーマ。


day2の方は5分のLT枠で応募していて、落ちたのですが、15分枠が定員割れで空いていたので、そちらで出させていただくことになりました。


どちらもまだまだ勉強が必要な分野ですががんばって準備します。よろしくお願いします。

*1:発表前だったものの絶対に秘密というものではなかったそうです

*2:やるしかない、となった理由の決定打は、「そもそもA会場に全員が入れるわけじゃない」(→ 誰かが裏でやるしかない → 僕がそこを降りても別の誰かがそこに入ることになる → それはスタッフの誰かのトークになる)というところでした。

*3:アップした資料からはその印を削除してあります

*4:公式の写真がいずれシェアされるっぽいです!

2016-08-16

イスラエルとパレスチナでiOSとBLEについて講演してきた話

7月24日〜30日、「中東のシリコンバレー」と呼ばれスタートアップがめちゃめちゃ盛り上がっているイスラエルのテルアビブ、IT産業が伸びているというパレスチナのラマッラ、そしてあの聖地エルサレムにて、iOS×BLEについて話してきました。


f:id:shu223:20160816085014j:image:w300

(在イスラエル日本大使館作成のチラシ)


なにそれどういうこと?と思われた方もいらっしゃるかもしれませんが、これ、外務省の「日本ブランド発信事業」という事業の一環なのです。


こういうこともなかなかないだろうという貴重な経験をさせていただいたので、ブログに書いておこうと思います。


経緯

正式に決まったのは出発のちょうど1ヶ月前ですが、きっかけは半年以上前、昨年12月に開催された DemoDay.Tokyo #0 にまでさかのぼります。そこで「勉強しつつソースコードをオープンにしてたら海外からも仕事が来るようになった」という話をしたのですが、そこに外務省の方が来られていて、「こういうのあるんだけど興味ある?」「あります!」的なやり取りをさせていただいたのでした。


「iOSという米国産プラットフォーム上で活動してるだけの自分が日本ブランド発信なんて場違いだろう」という気持ちもありつつダメ元で応募書類を提出したところ、WHILLとかMoffとかBONXとか、日本発の魅力的なプロダクトに横断的に関わっているというところを評価されて見事採択されたのでした。


スケジュール

こんな感じのスケジュールでした。

  • 7/24 東京発
  • 7/25 テルアビブ着、エルサレムへ移動しアズリエリ工科大学にて講演
  • 7/26 テルアビブのGoogle Campusにて講演
  • 7/27 テルアビブのSigma Labsにて講演
  • 7/28 パレスチナのビルゼイト大学にて講演
  • 7/29 テルアビブ発
  • 7/30 東京着

毎日講演が入っていて、移動もあり、会食もあり、それ以外の時間は現地のスタートアップと会ったり資料の手直しをしたりしてたので、自分でどこかに観光に行くような余裕はありませんでした(後述しますが道中で名所に寄ってくれたりはしました)


位置関係

テルアビブとかエルサレムとか言っても多くの日本人にとってはなかなか位置関係をイメージしづらいんじゃないかと思うので、地図を載せておきます。


f:id:shu223:20160816084908p:image:w280


テルアビブ〜エルサレムまで車で片道1時間〜1時間半(渋滞状況による)ぐらいです。


歴史的背景とかは素人が下手に説明できない複雑さがあるのでぜひググッてみてください。。


各講演の様子

それぞれの規模はそんなに大きくはなくて、20〜40名ぐらい。しっかり細かい質問や意見を拾うことができてちょうど良い人数だったと思います。4講演とも基本的には同じテーマで話をした *1 のですが、それなりに場所も離れているので、参加者のかぶりはなかったようです。


初日:アズリエリ工科大学 / エルサレム

f:id:shu223:20160816085715j:image:w600


f:id:shu223:20160816085714j:image:w600


2日目: Google Campus / テルアビブ

f:id:shu223:20160816085753j:image:w600


f:id:shu223:20160816085750j:image:w600


3日目: Sigma Labs / テルアビブ

f:id:shu223:20160816085826j:image:w600


4日目: ビルゼイト大学 / パレスチナ

f:id:shu223:20160816090120j:image:w600


f:id:shu223:20160816090218j:image:w600



各講演やその他の活動についての報告はレポートに書いて既に外務省に提出したので、いずれサイトにて公開されるかと思います。


道中の観光

初日のエルサレムの会場への移動中に、大使館の方のはからいで旧市街に寄っていただきました。

旧市街はユダヤ教・イスラム教・キリスト教の聖地であり、嘆きの壁や聖墳墓教会、岩のドームといった各宗教縁の施設を訪れる人々が絶えない。旧市街は城壁に囲まれ、東西南北に宗派ごとで四分割されている。北東はムスリム地区、北西はキリスト教徒地区、南西はアルメニア正教徒地区、南東はユダヤ人地区となっている。現在の城壁はオスマン・トルコのスレイマン1世によって建設されたものである。城壁には北側中央にあるダマスクス門から時計回りに、ヘロデ門、獅子門、黄金門、糞門、シオン門、ヤッフォ門、新門の八つの門があり、ここからしか出入りができない。19世紀に作られた新門以外はスレイマン時代より存在する門である。(エルサレム - Wikipedia

こういうすごいところなのです。


f:id:shu223:20160725162845j:image:w600


f:id:shu223:20160725163126j:image:w600

(石造りの街並)


f:id:shu223:20160725162641j:image:w400

(嘆きの壁で講演の成功を祈る。かぶっている帽子はキッパというそうです)


観光ではありませんが、パレスチナはこういう機会でもないとなかなか入っていけない(個人の旅行でも入れるみたいですが)ので、すべてが新鮮でした。


f:id:shu223:20160728143114j:image:w600

(パレスチナのとあるレストランから見た風景)


あと、パレスチナからの帰り、かの有名な死海にも寄っていただいたのですが、ビーチに出られるゲートが既に閉まっていて、遠くの方から眺めることしかできませんでした。


大使との会食

なんと、イスラエル大使公邸にてイスラエル大使とお食事をご一緒させていただく機会にも恵まれました。


f:id:shu223:20160726210756j:image:w500


安倍総理やオバマ大統領との写真が飾られている中、恐縮しすぎてちゃんと話せるのかと心配もありましたが、非常に気さくに話していただき、ご飯も和洋イスラエル料理の折衷で非常に美味しく、至福の時間を過ごさせていただきました。


f:id:shu223:20160816093042j:image:w600


途中ポケモンGOの話題になり、帰り際にズバット(コウモリみたいなやつ)を見つけて大使とのツーショットを撮影したところ非常に喜んでいただけました。(写真は 在イスラエル日本大使館のページに掲載されています。)


治安

よく聞かれるのですが、今回の滞在中、治安について不安に感じることは一切ありませんでした。そもそも「海外危険情報」を出しているのが外務省であり、移動も行き先もその外務省や現地大使館の方々が全面的にアレンジしてくださったので、大船に乗った気持ちだったというのもあります。


が、最近ではテルアビブの平均年収が東京のそれを超えたという話もあり、普通に生活水準も高く、警備もしっかりしていることもあって、基本的にかなり平和なようです。


f:id:shu223:20160727122358j:image:w600

(とあるオフィスから見たテルアビブ市街)


旅行なり仕事なりで、またぜひ行きたいと思っています。


おわりに

行く前はワクワク感よりも「自分でいいのだろうか」という不安の方が大きかったのですが、それなりに事業の趣旨に沿った貢献もできたと思うし、僕としては大変貴重な経験を多くさせていただけたので、とにかく行ってよかったです。


本事業の実現にご尽力いただいた外務省の皆様、各講演のアレンジから滞在中の移動や食事等全てにおいてお世話になった在イスラエル日本国大使館の皆様、パレスチナ講演にご協力いただいた対パレスチナ暫定自治政府日本国政府代表事務所の皆様、どうもありがとうございました!


お知らせ

iOSDC

いよいよ今週末に差し迫った iOSDC 2016 にて、『海外のiOSカンファレンスに登壇する - 完全版』というタイトルで発表させていただきます。


ベルリンの「UIKonf」、ロンドンの「iOSCon」、サンフランシスコの「AltConf」と、今年は3つの海外のiOSカンファレンスに登壇する機会に恵まれました。


とはいえ招待されたわけではなく、CFPに自ら応募して投票・審査の上で採択された結果です。


本発表では、海外カンファレンスに参加するメリット、CFPの探し方、発表の準備、実際の登壇でうまくいったことや失敗したこと等について話します。


出番は朝イチの10:20、しかもゲストスピーカーである岸川さんの裏ということで誰も来てくれないんじゃ・・・と恐々としております。来ていただけると嬉しいです。


iOSDC Reject Conference

iOSDC Reject Conferenceにもday1、day2両方とも出させていただきます。


day1はこちらのテーマ。


day2の方は5分のLT枠で応募していて、落ちたのですが、15分枠が定員割れで空いていたので、そちらで出させていただくことになりました。


どちらもまだまだ勉強が必要な分野ですががんばって準備します。よろしくお願いします。


*1:イベントの告知内容や現地主催者の要望に応じてソースコードレベルの話までするかどうかというようなちょっとした調整はした

2016-07-20

TensorFlowをiOSで動かしてみる

TensorFlow に iOS サポートが追加された というニュースを見かけたので、ビルドして、iOSで動作させてみました。


f:id:shu223:20160720074930j:image:w240

たまたま目の前にあった扇風機もバッチリ認識してくれました)


本記事では最終的にうまくいった手順を書いています。この手順をなぞってみるにあたってTensorFlowや機械学習・ディープラーニングについての専門知識は不要ですのでぜひお試しください!


ビルド手順

iOSサポートバージョンであるv0.9.0をチェックアウトして、以下の手順でビルドしていきます。手順はこの通りになぞるだけですし、ほぼスクリプトを実行するだけで非常に簡単です(が、実行時間がかなりかかります)。


  • スクリプトを実行して Eigen や Protobuf 等の依存ライブラリをダウンロード
cd tensorflow
tensorflow/contrib/makefile/download_dependencies.sh

  • protobuf をビルド&インストール
cd tensorflow/contrib/makefile/downloads/protobuf/
./autogen.sh
./configure
make
sudo make install

ここで、僕の環境では `./autogen.sh` 実行時に

Can't exec "aclocal": No such file or directory at /usr/local/Cellar/autoconf/2.69/share/autoconf/Autom4te/FileUtils.pm line 326.
autoreconf: failed to run aclocal: No such file or directory
shuichi-MacBook-Pro-Retina-15inch:protobuf shuichi$ ./configure
-bash: ./configure: No such file or directory

というエラーが出ました。”aclocal”というのは、”automake”パッケージに含まれているらしいので、automakeをインストール。

brew instal automake

で、改めて

./autogen.sh
./configure
make
sudo make install

  • iOS native版のprotobufをビルド
cd ../../../../..
tensorflow/contrib/makefile/compile_ios_protobuf.sh

  • iOSアーキテクチャ向けにTensorFlowをビルド
tensorflow/contrib/makefile/compile_ios_tensorflow.sh

(2016.8.22追記)v0.10.0 RC0 のビルド

現時点での最新Releaseである v0.10.0 RC0 は、上記手順でビルドしようとすると compile_ios_tensorflow.sh を実行するところでコケてしまったのですが、今は各ビルドの手順がまるっと入ったスクリプトが用意されているようです。

tensorflow/contrib/makefile/build_all_ios.sh

依存ライブラリのダウンロードからiOSアーキテクチャ向けビルドまで、これ一発でokでした。


サンプルをビルドする

`tensorflow/tensorflow/contrib/ios_example` に2種類のサンプルがあります。


simple と名付けられたサンプルアプリは、今回ビルドした static library をアプリ内に組み込む際の最小実装としての参考にはなりそうですが、デモとして見て楽しい機能があるわけではないので、本記事ではもう一方の camera の方を紹介します。


まず、このファイルをダウンロードして、解凍すると入っている、

  • imagenet_comp_graph_label_strings.txt
  • tensorflow_inception_graph.pb

の2つのファイルを、`tensorflow/contrib/ios_examples/camera/data` に置きます。*1


この Inception というのはGoogleが提供する画像認識用の学習済みモデルのようです。


cameraサンプル実行例

cameraサンプルを実行すると、すぐにカメラが起動します。身近のものを色々と映してみました。(リアルタイムカメラ入力に対する認識結果を表示してくれます)


MacBook

f:id:shu223:20160720080028j:image:w240


"Notebook" "Laptop" どっちでも正解!


扇風機

f:id:shu223:20160720074930j:image:w240


"Electric Fan" 正解!


椅子

f:id:shu223:20160720080106j:image:w240


"Folding Chair"(折りたたみ椅子) 惜しい。。ですが、そもそも `imagenet_comp_graph_label_strings.txt` には chair が3種類しかなくて、その中では一番近いと言ってもいいかもしれません。


iPhone

f:id:shu223:20160720080129j:image:w240


"iPod"・・・惜しい!iPhoneなのでほぼ正解と言ってもいいかもしれません。


パフォーマンス

今回cameraサンプルを試したデバイスはiPhone 6だったのですが、認識はまだまだリアルタイムとは言い難く、数秒単位の遅延がある感じでした。まだiOS向けにビルドできるようになったというだけでiOSにおける GPU Accelerated はされてないですし、パフォーマンスの最適化はまだまだこれからのようです。


ちなみに iOS 10 で Accelerate.framework に追加された BNNS (Basic neural network subroutines) を使用した最適化もissueに挙がっています。


ビルド手順の情報ソース

iOSサポートバージョンである0.9.0トップ階層にあるREADMEを見ても、iOSについては書かれていません


上述したビルド手順は`contrib/makefile` 配下のREADMEに書かれています。

関連情報を以下にまとめておきます。


サンプルのソースコードを読んでみる

サンプルは全編Objective-C++で書かれています。読んでもわからないだろうと思いつつ、せっかくなので読んでみます。


tensorflow_utils

モデルとラベルデータを読み込むメソッドと、認識結果を返すメソッドを持つユーティリティクラスのようです。

tensorflow::Status LoadModel(NSString* file_name, NSString* file_type,
                             std::unique_ptr<tensorflow::Session>* session);
tensorflow::Status LoadLabels(NSString* file_name, NSString* file_type,
                              std::vector<std::string>* label_strings);
void GetTopN(const Eigen::TensorMap<Eigen::Tensor<float, 1, Eigen::RowMajor>,
             Eigen::Aligned>& prediction, const int num_results,
             const float threshold,
             std::vector<std::pair<float, int> >* top_results);

汎用的に使えそう。


ios_image_load

画像ファイルを読み込むクラス。

std::vector<tensorflow::uint8> LoadImageFromFile(const char* file_name,
             int* out_width,
             int* out_height,
             int* out_channels);

プロジェクトには追加されているけど使われてないっぽい。


CameraExampleViewController

サンプル本体。肝っぽいところだけを拾っていくと、


`std::unique_ptr<tensorflow::Session>` なメンバ変数を定義して、

std::unique_ptr<tensorflow::Session> tf_session;

viewDidLoadのタイミングでモデルを〜.pbファイルからロード

tensorflow::Status load_status =
  LoadModel(@"tensorflow_inception_graph", @"pb", &tf_session);

で、カメラからのリアルタイム入力が得られるたびに呼ばれるデリゲートメソッドを見てみると、

- (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
       fromConnection:(AVCaptureConnection *)connection {
  CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
  [self runCNNOnFrame:pixelBuffer];
}

CMSampleBufferRef から CVPixelBufferRef を取得して `runCNNOnFrame:` を呼んでいるだけのようです。


`runCNNOnFrame:` はコードが若干長いですが、このへんと、

tensorflow::Tensor image_tensor(
    tensorflow::DT_FLOAT,
    tensorflow::TensorShape(
        {1, wanted_height, wanted_width, wanted_channels}));
auto image_tensor_mapped = image_tensor.tensor<float, 4>();
tensorflow::uint8 *in = sourceStartAddr;
float *out = image_tensor_mapped.data();

このへんが肝っぽいです。

if (tf_session.get()) {
  std::string input_layer = "input";
  std::string output_layer = "output";
  std::vector<tensorflow::Tensor> outputs;
  tensorflow::Status run_status = tf_session->Run(
      {{input_layer, image_tensor}}, {output_layer}, {}, &outputs);
  if (!run_status.ok()) {
    LOG(ERROR) << "Running model failed:" << run_status;
  } else {
    tensorflow::Tensor *output = &outputs[0];
    auto predictions = output->flat<float>();

    // ラベル取得
  }
}

が、すみません、それぞれ何をやっているのかを解説するにはTensorFlowの処理をちゃんと理解する必要がありそうです。。(勉強します)


自分のアプリに組み込む

試せていませんが、こちら に手順が示されていました。

  • ユニバーサルなstatic library(libtensorflow-core.a)をビルドしてプロジェクトに追加する
    • [Library Search Paths] にも追加。

The `compile_ios_tensorflow.sh' script builds a universal static library in tensorflow/contrib/makefile/gen/lib/libtensorflow-core.a. You'll need to add this to your linking build stage, and in Search Paths add tensorflow/contrib/makefile/gen/lib to the Library Search Paths setting.

  • libprotobuf.a と libprotobuf-lite.a をプロジェクトに追加する。
    • [Library Search Paths]にも追加

You'll also need to add libprotobuf.a and libprotobuf-lite.a from tensorflow/contrib/makefile/gen/protobuf_ios/lib to your Build Stages and Library Search Paths.

  • [Header Search paths] を追加

The Header Search paths needs to contain the root folder of tensorflow, tensorflow/contrib/makefile/downloads/protobuf/src, tensorflow/contrib/makefile/downloads, tensorflow/contrib/makefile/downloads/eigen-eigen-, and tensorflow/contrib/makefile/gen/proto.

  • [Other Linker Flags] に `-force_load` を追加

In the Linking section, you need to add -force_load followed by the path to the TensorFlow static library in the Other Linker Flags section. This ensures that the global C++ objects that are used to register important classes inside the library are not stripped out. To the linker, they can appear unused because no other code references the variables, but in fact their constructors have the important side effect of registering the class.

  • bitcodeを無効にする

The library doesn't currently support bitcode, so you'll need to disable that in your project settings.


まとめ

TensorFlowをiOS向けにビルドし、付属のサンプルを動かしてみました。パフォーマンスの最適化等、まだまだこれから感はありますが、扇風機や椅子、ノートパソコンやiPhone等、大きさも形も全然違うものを認識してくれて未来を感じます。


試してみるだけなら機械学習やTensorFlowについての専門知識を必要としませんし、ぜひお手元で動かしてみてください!


次のステップとしては、下記記事で紹介されているテンソルの計算部分に特化してSwiftで書かれたライブラリと比較したりしつつ、ちゃんとTensorFlowでやっていることを理解したいと思います。


また、本記事同様に「とりあえず動かしてみる」シリーズとして、こちらもよろしければどうぞ:


*1:ちなみにこのとき、 https://github.com/miyosuda/TensorFlowAndroidDemo/find/master にある同名ファイルを使っても、ちゃんと動きません。参考

2009 | 08 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 12 |
2016 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 |