Hatena::ブログ(Diary)

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

2016-11-13

iOS/MetalのシェーダをWebGL/GLSLから移植する

Metalでグラフィック処理を行うにしろ並列演算を行うにしろ、GPUに処理をさせるためのシェーダを書かないといけないわけですが、これがまだ情報が少なくて、「こういうシェーダを書きたいんだけど、誰かもう書いてないかな・・・」というときに参考になる近いものとかはそうそう都合よく出てこないわけです。


ただ、WebGL/GLSLの情報はググると山ほどあって、GLSL Sandbox という、Web上で編集できてプレビューできてシェアできるサイトもあり、何がどうなってそうなるのか理解できない難しそうなものから、ただの円といったシンプルなものまで、既に偉大な先人たちのサンプルがたくさんアップされています


f:id:shu223:20161113192400j:image:w600



Metalのシェーダというのは正しくは Metal Shading Language といいまして、C++をベースとする独自言語なのですが、まー概ねGLSLと一緒です。


実際にやってみたところ、GLSL -> Metal Shader の移植はほとんど単純置き換えで済み、Swift 2をSwift 3に直すのよりも簡単という感覚でした。


f:id:shu223:20161113192821j:image


いずれも画像等のリソースは使用しておらず、iOSデバイス上で、GPUによってリアルタイム計算されたものです。


実際のところ自分はゲーム開発やVJをやったりしているわけではないので、こういう派手なエフェクトではなく、線とか円とかグラデーションとかのもっと単純なものをMetalで動的描画したいだけだったりするのですが *1、移植が簡単に行えることがわかっていれば、GLSLを参考にMetalシェーダを書けるというのはもちろんのこと、GLSL Sandboxで動作確認しつつシェーダを書いて、できたものをiOSに移植する、ということもできるので、個人的にはMetalシェーダを書く敷居がグッと下がりました。


というわけで、以下GLSLのコードをMetalに移植する際のメモです。


雛形となるプロジェクトを作成する

プロジェクトテンプレートに "OpenGL ES" はあっても "Metal" というのはないのですが、"Game" というのがあり、次の画面で [Game Technology] の欄で Metal を選択すると、シンプルなMetalのプロジェクトが生成されます。


f:id:shu223:20161113194605j:image:w500


これをベースに、GLSLのコードを移植して来やすいように次のように手を入れました。(現時点ではGLSL SandboxのコードをiOSで動かしてみるべく、フラグメントシェーダだけに手を入れています)


1.「画面の解像度」をフラグメントシェーダに渡す

多くのGLSLのサンプルでは、xy平面における座標を 0.0〜1.0 に正規化した状態で取り扱っています。ピクセルベースの座標値をシェーダ側で正規化できるよう、画面の解像度をシェーダに渡すよう修正します。


まずはシェーダ側。下記のように引数に float2型の "resolution" を追加します。

fragment float4 practiceFragment(VertexInOut     inFrag      [[stage_in]],
                                   constant float2 &resolution [[buffer(0)]])

次にSwift側。下記のようにバッファを用意して、

var resolutionBuffer: MTLBuffer! = nil
let screenSize = UIScreen.main.nativeBounds.size
let resolutionData = [Float(screenSize.width), Float(screenSize.height)]
let resolutionSize = resolutionData.count * MemoryLayout<Float>.size
resolutionBuffer = device.makeBuffer(bytes: resolutionData, length: resolutionSize, options: [])

フラグメントシェーダ関数の引数にバッファをセットします。

renderEncoder.setFragmentBuffer(resolutionBuffer, offset: 0, at: 0)

こんな感じで正規化した座標値を算出します。

float p_x = inFrag.position.x / resolution.x;
float p_y = inFrag.position.y / resolution.x;
float2 p = float2(p_x, p_y);

GLSL Sandboxはスクリーンが必ず正方形なのですが、iOSデバイスはそうではないので、比率が変わらないようどちらもx方向の解像度(つまり幅)で割っています。


2. 「経過時間」をフラグメントシェーダに渡す

ほとんど同様です。シェーダ側では、引数に float型の "time" を追加します。

fragment float4 practiceFragment(VertexInOut     inFrag      [[stage_in]],
                                   constant float2 &resolution [[buffer(0)]],
                                   constant float  &time       [[buffer(1)]])

Swift側。下記のようにバッファを用意して、

var timeBuffer: MTLBuffer! = nil
timeBuffer = device.makeBuffer(length: MemoryLayout<Float>.size, options: [])
timeBuffer.label = "time"

フラグメントシェーダ関数の引数にバッファをセットします。インデックスが変わる点に注意。

renderEncoder.setFragmentBuffer(timeBuffer, offset: 0, at: 1)

時刻の更新時にバッファを更新します。

let pTimeData = timeBuffer.contents()
let vTimeData = pTimeData.bindMemory(to: Float.self, capacity: 1 / MemoryLayout<Float>.stride)
vTimeData[0] = Float(Date().timeIntervalSince(startDate))

GLSLを移植する際の改変点

GLSL を Metal に移植してくる準備が整いました。ほとんど同じ、と書きましたが細部はやはり違います。以下、大まかな移行ポイントです。

  • GLSLのフラグメントシェーダでは、最後に gl_FragColor にvec4値をセットすることで出力とするが、return で float4 なり half4 なりを返す

(例)GLSLの場合

gl_FragColor = vec4(color, 1.0 );

Metalの場合

return float4(color, 1.0);
  • 関数はプロトタイプ宣言が必要
    • これがないと、ビルド時に "No previous prototype for function 〜" というwarningが出る
  • vec2, vec3, vec4 -> float2, float3, float4
  • ivec2, ivec3, ivec4 -> int2, int3, int4
  • mat2, mat3, mat4 -> float2x2, float3x3, float4x4
    • コンストラクタも微妙に違う(float2x2ならfloat2を2つ渡す。公式ドキュメントp15あたり)
  • const -> constant
  • mouse.x, mouse.y -> 適当に0.5とか

また出てきたら追記します。


GLSL Sandboxから移植してみる

GLSL Sandboxでいくつかピックアップして上記手順でMetalに移植し、iOSで動かしてみました。それぞれの移植にかかった時間は5分ぐらいです。ほとんど単純置き換えで済みました。


http://glslsandbox.com/e#36694.0

f:id:shu223:20161113193424g:image


http://glslsandbox.com/e#36538.3

f:id:shu223:20161113193507g:image

※デフォルトのITERATIONS 128では3fpsぐらいしか出なかったので、ITERATIONS 64に変更


http://glslsandbox.com/e#36614.0

f:id:shu223:20161113194708g:image


まとめ

GLSLをMetalに移植する手順について書きました。


上にも書きましたが、Metalをさわりはじめたときはシンプルなものすら書き方がわからなくて四苦八苦したので、「GLSLのコードも参考になるんだ!」と気付いたときはMetalの敷居がグッと下がった気がしました。


MetalはiOS 10からニューラルネットワーク計算のライブラリも追加されたこともあり、自分的に今一番熱い分野です。引き続きシェーダの具体的な書き方や、SceneKitを併用して3D空間内のノード上にMetalでテクスチャを動的描画する方法、デバッグツールの使い方等、色々と書いていきたいと思います。



*1:線とか円とかの単純なものでも、カメラプレビューで動的かつリアルタイムに、かつ他の重い画像処理と一緒に、といった場合、そして描画数が多かったり毎フレームの更新が必要な場合、やはりUIKitやCoreGraphicsでは厳しい場面が出てきます。

2016-09-29

フリーランスを休業して就職します

2014年からフリーランスiOSプログラマとして活動を始めて2年と8ヶ月。フリーランスという働き方は自分には最高にしっくりきてて、毎日楽しくお仕事させていただいてたのですが、色々とタイミングが重なりまして、タイトルの通り、いったん休業して「会社員」になることにしました。


どこに就職するのかと言いますと、サンフランシスコにあるFyusionというスタートアップにジョインします。


f:id:shu223:20160929075342p:image:w400


無事H-1Bビザが通りまして、ちょうど昨日、スタンプの押されたパスポートが郵送されてきたところです。


フリーランスとしての実績もまとめたいところですが長くなるのでここでは省略して、ご報告の意味でも、自分の考えを整理しておく意味でも、就職することにした経緯や理由等を書いておこうと思います。


経緯

上述しましたが、僕はフリーランスという立場を100%楽しんでいましたし、海外企業も含めて「就職」したいという願望はありませんでした *1


以下は今年の3月ごろの話です。当時の状況としては、

という感じで、「フリーランスとして」「日本をベースにしつつ」「たまに海外に」行けたら楽しいなというスタンスで動いていました。


投資家からのコンタクト

3月はじめ頃のある日、とあるベンチャーキャピタルの方から会いたいという連絡をいただきました。この時点では何の用事かわからなかったのですが、普通に考えて投資先のアプリ開発を手伝って欲しいという話だろうなと。


(VCの人とか上位レイヤーすぎて、末端で手を動かしてるエンジニアなんて駒としか思ってなさそう)・・・という勝手な偏見もありつつ、ちょっと疑心暗鬼のままお会いしたのですが、まずは自己紹介がてらそのVCの投資先について一通りご説明いただいて、これがまた僕的にはどの会社のプロダクトもおもしろかったわけです。*3


で、実は投資先の会社のCEOが僕と話したいと言ってきてる、と。(たぶんGitHubで見つけたんだと思います。それしか入り口がないので)


その会社がFyusionなわけですが、この時点でもう僕は少なくとも何らかの形で関わりたいと思うぐらいには惹かれていて(後述します)、でもどういう「話」なのかはわからないのでまずは話してみよう、という感じでした。


CEOとのスカイプ

その翌週ぐらいにCEOのRaduとスカイプすることになり、僕が次の用事があったので実質3分ぐらいしか話せなかった *4 のですが、その3分でRaduは、ユーと仕事をしたい、働き方はパートタイムでもフルタイムでもリモートでも希望通りでいいよと。で、僕は働くなら一緒に顔を突き合わせてやりたい、と。おおそれじゃあビザの申請マジで急がないといけないからすぐにファウンダー達と話してよ、と。


3分で一気に事が進みました。


ちなみにこのとき確か3月中旬ぐらい。H-1Bビザの申請は4/1にオープンして、一瞬で埋まります。そしてさらに僕が3月後半からドイツに行く予定があり、申請書類の準備期間は実質一週間ぐらいしかありませんでした。


ファウンダー陣とのスカイプ

メールで時間調整して、翌日の午前中にはファウンダー陣とスカイプすることになりました。


正直、グダグダ、どころか95%相手が何言ってるかわからなかったです。第一声でPardon?って言った気がしますが聞き返しても聞き取れないのでそれも言わなくなりました。


唯一、"Printer"とか特徴的な単語がひとつだけ聞き取れたりして、「Canon時代の仕事について聞いてますか?」と確認してしゃべる、みたいな感じでどうにかこうにか乗り切りました。


参考:


そしてオファー

とはいえ全然トンチンカンなコミュニケーションをしてたとは思うので、これは「ない」だろうなと思ってたら、スカイプの30分後だか1時間後だかにオファーのメールが!


条件を確認して、外出していた奥さんに電話かけて「〜ということなんだけどサインしていい?」って聞いて、サインして返送。あちらからもすぐにサイン入りのが返ってきました。


のべ2時間ぐらいのスピード就活でした。ビザ申請の期限という後押しがなかったらもっと迷っていたかもしれません。


Fyusionに惹かれた点

大きく分けて2点あります。

「欲しいスキル」が得られそうだった

僕が身につけたいと思っているスキルに、「英語」「コンピュータビジョン」「3Dプログラミング」「機械学習」があります。


で、Fyusionは、

  • CEOのRaduは、3D点群処理のオープンソース・プロジェクト「Point Cloud Library (PCL) 」の設立者
  • OpenCVのコミッタでもある
  • 他のファウンダー陣・メンバーもロボット工学・3Dコンピュータビジョン・機械学習とかの博士号もってる人がゴロゴロ
  • 提供しているサービスもそれらの技術をベースとしている
  • もちろん英語を使う

というわけで、全部揃っているなと。


やろうとしていることが腹落ちした

彼らは「空間写真」を撮るアプリ「Fyuse」というプロダクトを既に世に出していて、


f:id:shu223:20160929091526p:image:w300

(Fyuseのわかりやすい記事:動画ともパノラマとも違う“空間写真”ってなんだ? Fyuse創業者に話を聞いた | TechCrunch Japan


こういうものを撮影してソーシャル上にシェアできるアプリです。

f:id:shu223:20160929085556g:image:w200

(Fyuseの空間写真をアニメーションGIFに変換したもの)


このアプリは一見飛び道具感があるのですが、中では実際に撮影された動画とスマホの各センサの値から対象を3次元モデルとして解析しています。


f:id:shu223:20160929041931p:image:w600


上に貼った例をよく見ると、人間の向きと3次元のロゴの向きが一致していることがわかると思います。



これはいわば「普通のスマホのカメラを3Dスキャナにする技術」をSNSという使ってもらいやすい形で提供しているようなもので、


「3次元データがたくさんあれば我々の得意分野である3Dコンピュータビジョンの技術でいろんなおもしろいことができるぞ!」


というところに彼らのやりたいことがあります。単にギミッキーな写真撮影SNSをつくってるわけじゃないぞと。



たとえば最近では、このFyuseで撮ったデータをHoloLensでホログラム投影、みたいなことをやってたりします。


僕はハードウェアという「現実世界のモノ」と繋がるアプリの開発を色々やってきて、やはりその「現実世界を見る『目』」のところで技術的強みがあると楽しいよなー、ということを常々感じていたので、彼らのやろうとしていることは非常に腹落ちしたわけです。



あと、Fyuseは普通に撮影フォーマットとしてもかなり可能性があるんじゃないかと思っています。一見ギミッキーですが、写真よりも多面的に記録でき、動画よりも軽量で柔軟に閲覧でき、2Dだけど3Dモデル的な情報も持っているという点で、「空間を捉える」ためのフォーマットとして普遍的な良さがあるなと。


2ヶ月間リモートワークしてみてのPros/Cons

フリーランスでお手伝いしていたところは7月までに収束させて、8月からリモートで手伝い始めてます。当然Pros/Cons両方あります。

Pros
  • AVFoudation, Core Image, Metal/MetalKit/MetalPerformanceShaders, Acceralateと、iOSアプリ開発の中でも特に興味のある部分の実装に携われている
  • iOS 10とかの新機能を積極的に使っていく雰囲気がある
    • バージョン互換とかは後から考えよう、という感じ
  • CEO, CTO, その他ファウンダー陣全員が毎日ゴリッゴリにコードを書いている
    • 一番ソースを把握してるのは彼ら。
Cons
  • チャットの速さに全然ついていけない
    • 全部読んでたら仕事にならない
    • 流し読みしても情報量0%なのでもはやメンションくれない限り読んでいない
  • フリーランスとしての立場が恋しい
    • おもしろい仕事の話をいただいたり、おもしろいことをやってる人に会っても、そこから展開させられないのがもどかしい

サンフランシスコには引っ越しません

あっちに住んで仕事をしてもOKなビザを獲得したわけですが、家庭の事情もあり、基本的には東京にいます。今のところは、1ヶ月アメリカ(オフィス)、2ヶ月日本(リモートワーク)、ぐらいのつもりです。


が、変わるかもしれません。フリーランスとしての働き方も、最初はリモート指向だったけど早々にお客さんのところに行ってやるスタイルに変えたり、短納期案件が楽しいとかじっくりやる方が楽しいとか時期によって色々変遷があったりもしたので、日米往復生活もやりながら試行錯誤していくつもりです。


まとめ

というわけで、長くなりましたが、フリーランス生活をエンジョイしていたところで急に降ってきたご縁で大きく方向転換することになりました。


そもそもの目的である「身につけたいスキル」は身につくのか、アメリカと日本の往復生活は成立するのか、会議では全然聞き取れないだろうけど仕事になるのか等々、いろいろと不安もあります。通用しなくてすぐに逃げ帰ってくるかもしれません。


が、せっかくの機会なので、楽しみつつ色々と吸収してこようと思います!


*1:3年ほど前はありましたが

*2:詳細はこちら:iOSDCで発表しました『海外のiOSカンファレンスに登壇する - 完全版』 #iOSDC - Over&Out その後

*3:今回就職する会社ではないところで、その後アプリ開発をお手伝いしたところもあります。そこのプロダクトも相当ぶっ飛んでておもしろいので許可がとれたら紹介したい

*4:27分ぐらいRaduが会社の説明をしてて、残り3分になったところで「11時から別のスカイプあるんだけど・・・」とやっと切り出した

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とディープラーニング』について話しました

一昨日メルカリさんのオフィスで開催された 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:公式の写真がいずれシェアされるっぽいです!

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 | 11 | 12 |
2016 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 11 |