Hatena::ブログ(Diary)

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

2017-02-07

それでもCourseraの機械学習コースをオススメする理由

先日、オンライン学習サイトCourseraの機械学習コース "Machine Learning by Stanford University" を修了しました。


f:id:shu223:20170207160051j:image

(感動のエンディング動画)


ただ、機械学習に興味があって情報収集を始めてる人にとって、「Courseraの機械学習コースがおすすめですよ」という話は


「はい、知ってます


という感じではないでしょうか。


僕もそんな感じで、幾度となく人や記事に同コースを薦められたりしつつ、たぶん2年ぐらいスルーし続けてきたと思います。


しかし約2ヶ月前、ひょんなきっかけから本講座を始めてみて、やはり評判通り最高だったと思うと同時に、僕と同じような感じでこのコースが良いらしいと知りながらもスルーし続けてる人は多いんじゃないかと思いまして、(おせっかいながらも)自分の脳内にあった「やらない理由」を列挙しつつ、「いや、それでもやった方がいいですよ」というのを書いてみたいと思います。


「スタンフォードの授業」レベル高そう

世界最高峰のスタンフォード大学の授業、いくら「入門です」と言われても、


「それはレベルの高い中での入門でしょ?」


と思ってました。技術書を読んでもさっぱり頭に入ってこない人の気持ちなんてわからないでしょうよ、と。


いえ、この授業はサルでもわかります。・・・とは言えません


やっぱり数式がたくさん出てきて何言ってるのかわからなくなります。眠くなります。でも少なくともスタンフォードに入学できる程の世界最高峰の前提知識が必要ってことはないです。


高校レベルの数学、プログラミングが出来れば前提知識としては十分で、Andrew先生は数式の意味を説明するのがめちゃくちゃうまいです。項を削ぎ落としてシンプルにしたところから、順序立ててその数式の性質を説明してくれて、それが機械学習でどう役立つのか、という話をしてくれるので、納得感・腹落ち感があります。


そして時には、「この数式の意味はわかってなくても偉い人が実装したライブラリ使えば機械学習はできるから大丈夫だ」と言ってくれたりもします。わからない人の気持ちがわかってる先生だなと随所で感じます。


わからない分野の話を、英語で学ぶなんて...

全編に日本語字幕があります。自動翻訳の気持ち悪い日本語ではなくて、ボランティアによる自然な日本語です。


当初僕には「英語の動画を日本語字幕で見るのは何か負けた感がある」「英語で観ると英語の勉強にもなって一石二鳥」という変なこだわりもありましたが、

  • 機械学習を学ぶのが先決
  • (英語で観ることで)心理的ハードルが高くなって講座をやらなくなっては本末転倒

と開き直って全て日本語で観ました。


その後色々なオンラインコースが出てきてるし、もっと良いのがあるんじゃない?

このコースがいつからあるのかわかりませんが、たぶん2012年にはもうあったと思います。今では最初から日本人が日本語で解説している講座もあるでしょうし、ディープラーニングまでカバーしているものもありますし、評価が高いものもあります。


このコースが優れている点として、Andrew先生の説明がわかりやすい、実践的な内容である、といったことがよく挙げられますが、それらももちろん良いわけですが、


毎週のプログラミング課題の提出が義務付けられている


という点で、僕は他のオンライン講座と比べて圧倒的に良いと思いました。


動画で学んだニューラルネットワークとかレコメンドシステムを自分で実装して、毎週提出する必要があります*1


これが本当に素晴らしくて、

  • 動画を見てよく理解できなくても、自分でプログラムを書いてみるとよく理解できる
  • 動画を見て理解できたと思っていても、自分でプログラムを書いてみると理解が曖昧だった部分が浮き彫りになることがある
  • ちゃんと学んだという実感がある

という効果があると感じました。他のオンライン講座ではあまりこの形式は見たことなくて、どんなに動画が良くても、結局これがないと意味ないような、とさえ思います*2



ちなみに最近、『ゼロから作るDeep Learning』という書籍がとても評判が良く、これでゼロから学び始めた/学ぼうと思っている、という人も多いと思います。


ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装
斎藤 康毅
オライリージャパン
売り上げランキング: 65


僕も最近買って読んでみて、この本の「手を動かして自分で実装してみる」というコンセプトの良さに通ずるものが、このCourseraの機械学習コースもある、と思いました。上述しましたが学んだことは全て自分で実装することになるので。


ちなみにこの本とCourseraの機械学習コースは(被る部分もありますが)カバーする範囲が違うので両方ともやって損はないと個人的には思います。ディープラーニング本はディープラーニングに到達するための要素技術/知識を最短距離で学ぶ感じですが、Coursera機械学習コースはもっと機械学習の基本事項を広く網羅する感じです。*3


OctaveじゃなくてPythonでやりたい

「今機械学習やるならPythonだし、なぜOctave・・・?」というところで避けてしまう人も多いかもしれません。


もちろん僕もOctaveは初めて触りましたしこの講座以外でもう触ることもないんじゃないかとさえ思いますが、Octave独自の使い方とか記法を学ぶ、というオーバーヘッドはほとんどなかったと思います *4


プログラミング課題でやった実装は自分で中身を理解している(どういう関数を使っているか、なぜそういう計算をしているか)ので、つくったものをあとから他の言語やフレームワークに移植するのも簡単そう、と思っています。


今忙しいから落ち着いたらやろう

ここまで読んで、「良さそうだな」って思った方もいらっしゃるかもしれません。でも同時に「今忙しいので、落ち着いたらやろう」と思った方は多いんじゃないかなと推察します。仕事は毎日あるし、エンジニアは学ぶことは他にもいくらでもあるし。


僕もそうでした。仕事もプライベートもめちゃめちゃ忙しかったし、優先的に学ぶべき技術も他にあったので、「1ヶ月後ぐらいには今よりは落ち着いてるはずだからそのときに」って思いかけたのですが、ふとコースのカリキュラムを見て考えが変わりました。


「ニューラルネットワークぐらいはちゃんと理解したいな」と思っていたのですが、本コースでニューラルネットワークについて学ぶのはWEEK4, 5。ちゃんと1ヶ月後に受講開始したとして、順当に進めて、ニューラルネットワークの基礎を学べるのがその1ヶ月後。


この機械学習/ディープラーニングが盛り上がってる中、最低でもあと2ヶ月は自分はスタート地点にすら立てていないことになるのか、と愕然とし、すぐに始めることにしたわけです。


当初は修了することは重視してなかったので、いきなりニューラルネットの章だけやることも考えました。が、本コースのカリキュラムは知識が積み上がっていくようにデザインされていて、序盤の「線形回帰」とか「ロジスティック回帰」で学んだ知識はその後の章のあらゆる部分に関係してきたので、最初から通しでやってよかった、と思っています。


続けるコツ

こうやっておすすめしているわけですが、機械学習で何かをやる具体的な予定があるわけでもなく、仕事もプライベートも普通に忙しい、という状況においては実際のところ完走するのはなかなか大変なんじゃないかと思います。


僕は第1週目は「機械学習の歴史」みたいな流し見しても良い内容だろうと思って最初は気軽に始めてみたのですが、最初の動画だか2つ目の動画だかでもういきなり数式がバリバリ出てきて面食らった記憶があります。普通に気が重いです。


そんな中でも続けられた理由が3つほどあるなと思うので参考までに書いておきます。


1. 中間目標があった

当初は完走するつもりはなくて、とりあえず第5週のニューラルネットワークまではやろう、と思っていました。


で、第5週目までやって、修了証書が欲しいわけでもなかったのでやめてもよかったわけですが、その先のカリキュラムに「次元削減」「レコメンドシステム」等いくつか学びたい項目があったので、もうちょっとやってみるか、と。


8週目ぐらいまでやったとき、最後の第10週、第11週はプログラミング課題がないことに気づきました。実質あと2週がんばれば完走じゃん!と。


そんなこんなで、中間目標を見ているうちに完走できた、という話です。


2. 「挫折したらもう一生オンライン講座で勉強できない体になる」という意識があった

自分の性質上、一度自分の意志を折った前例をつくってしまうと、もうダメなんですよね。そこが基準になってしまう。


「今週めっちゃ忙しいけど、一週でもサボったらもうこの講座をやることはないだろう」


「この講座を完走しなかったら、もう一生どんなオンライン講座も完走することはないだろう」


極端だと思われるかもしれませんが、人生を40年近くやってきて実際そんな感じだったので、「ここでオンライン講座という貴重な学習の選択肢を失うわけにはいかない」という思いで後半は進めていました。


3. 適度に飛ばしながら進めた

例えば(上述した通り)Octaveの書き方の動画は飛ばしましたし、前半には結構あるテキストによる解説とPDFは全部飛ばしましたし、プログラミング課題の"optional"問題も容赦なく飛ばしました。やった方がいいのは間違いありませんが、挫折するよりは前に進んだほうがいいので。


まとめ

というわけでCourseraの"Machine Learning"、おすすめです!


*1:自動ですぐに採点されるようになっています

*2:宿題として課されなくても自分で手を動かして学べる人は別

*3:個人的には、先にCourseraの方をやり、後からこの本で(既に知っているところは飛ばしつつ)やった方がわかりやすいのでは、と思いました。

*4:序盤でOctaveの使い方の動画があるが、ほとんど飛ばして、テストと課題で必要になる度にググる、という方法で十分乗り切れました

2017-01-11

「シリコンバレーで働くエンジニアと考える、これからのキャリア」という授業をしました

オンライン動画学習サービスSchoo(スクー)で、「シリコンバレーで働くエンジニアと考える、これからのキャリア」と題した授業をさせていただきました。*1



撮影を生放送で行い、視聴者参加型で行う授業でした。もちろんキャリアに正解なんてないし、キャリア観も人によって千差万別なので、僕が何かを教える、というよりは、まずは僕の経験や考えを共有して、あとはコメント・質疑応答ベースでみんなで考えていきましょう、的なコンセプトです。


f:id:shu223:20170111081424j:image:w600


講義

最初に30分(ホントは20分の予定だったのですが🙇🏻)の講義パートがありました。


講義資料はこちら。*2



  1. 自己紹介(僕のキャリアの変遷をざっと説明)
  2. 僕のキャリア観(理想)
  3. その実現のために意識していること4つ

という3段構成です。


以下に簡単に抜粋します。


自己紹介(キャリアの変遷)

20代は大企業志向 → ベンチャー → スタートアップ → フリーランス → いまは30人ぐらいのスタートアップ


f:id:shu223:20170111081032j:image:w600

給与の変遷グラフというちょっと生々しい話もあります) *3


僕のキャリア観
  • グリーンカードを取得し、海外に移住したい
  • いずれは起業し、世界を変えたい
  • 技術で世界を良くしたい

いずれも素晴らしいことだと思うけど、そこを目指しているかというとそうでもない。


f:id:shu223:20170111205931j:image:w600


時流や自分の興味が移り変わる中で、その時々でおもしろいと思える選択肢を取れる自分でありたい


→ 言うのは簡単だけど、実践するのはなかなか大変

  • 同じ程度の成功では達成感を感じられない
    • かといってより大きい成功をし続けるのは簡単ではない
  • 同じことをやっていると飽きる
    • アプリをつくることが「無条件に」楽しい、という時代はとうに過ぎた
    • 海外で仕事してテンション上がっても3日で慣れる
  • 新しい技術を短時間でマスターするような天才でもない

「おもしろがり続ける」のは大変!


そんなキャリア観の実現のために意識していること4つ

1. 勉強を仕事に繋げる

  • 新たな刺激のある仕事を獲得するために、新しい技術を習得する必要がある
    • 短時間でマスターするような天才ではない
    • 必要に迫られてない勉強を継続することは難しい
  • 20時間の法則:未経験の人から見ると「すごい!」っていうぐらいのレベルにはなる
  • 自分の得意領域と組み合わせれば、仕事を獲得できる
    • フルタイムで経験を積める
    • 仕事だから続けられる!稼げる!

2. "Searchable"になる

  • おもしろい仕事が来るポジションにいるには?
    • 求人が出たり、プロダクトが話題になるタイミングで自分からアクションするのでは遅い
    • おもしろい人がおもしろいことを始めるタイミングで声をかけてもらいたい
  • 「自分が何ができる人で、何をやりたい人か」を示し、それを必要とする人に見つけてもらえるようにする

3.「許容できるリスク」を知る

  • 技術力だけ追い求めても上には上がいてキリがない
    • ので、何か別のところで違いを出したい
    • 自分の経験上、ちょっとした「行動力」で意外な程に違いが出る
  • 他人はなかなかやらない「ハイリスク・ハイリターン」な行動があるとして、そのリスクを「自分は」許容できるのであれば、それは自分にとって「ローリスク・ハイリターン」な行動となる
  • → リスクを取らずにリターンを得られる
  • 例:英語も話せないのに海外に飛び込む「不安」は自分にとって許容できるリスク
  • 逆の例:車を運転して事故るかもしれないというのは他人にとって許容できるリスクのようだが僕にとっては許容できないリスク(怖くてできない)

4. 引き際も大事

  • モチベーションMaxで取り組むほうが雇い主/自分双方にとって良い
  • おもしろい仕事をやってるときは遊びの予定よりも仕事の方がおもしろい
  • 日曜夜に残念な気持ちになるなら黄色信号
  • → 引き際も大事

質疑応答

残りの時間は質疑応答でした。やはりキャリアについてはみなさん気になるところが多いようで、授業が延長されるぐらいにコメント、質問をたくさんいただきました。


実際のQ&Aはスクーで見ていただくとして、以下に目次を載せておきます。

  • アメリカに行った理由
  • Q.英語はどのようにして身につけたのでしょうか?
  • Q.日本と海外で働くのどちらが面白いですか?
  • Q.アメリカの就職事情は?スタートアップへの就職で大切なポイントはどこでしょうか?
  • Q.質問です!海外で仕事することに関して奥様から反対とか無かったのですか?
  • Q.シリコンバレーだからこそ日本と環境面で何が異なるかを知りたいです。
  • Q.アメリカで求められるエンジニアってどんな人ですか。データ分析?人工知能?
  • Q.現在、海外で働きながらフロントエンジニアを目指していますが、カヤック時代は一日に何時間、プログラミング学習をしていましたか?(平均睡眠時間が8時間と仰っていたので)
  • Q.シリコンバレーで起業する準備としてするべきことを教えてください。
  • Q.堤さんがエンジニアとして海外に居ても日本に居ても1日の中で最も大切にしていることは何でしょう
  • Q.シリコンバレーにおいて、エンジニアのキャリアはどういうものがあるのですか?ずっとプログラマーのままの人もいらっしゃいますか?
  • Q.日本とアメリカでは開発に対する考え方(リスク等)に違いがあると思います。その考え方の違いについてお話を伺いたいです。
  • Q.面白い仕事をどのように探し続けているですか?教えて頂けますか?
  • 受講生の皆様へのメッセージ

撮影風景

スタジオはこんな感じでした。


f:id:shu223:20170106201910j:image:w600

(カメラが3台、モニタも3台、でかい照明もあります)


スタジオに行くまで、普通のハンディカムみたいなので撮影するもんだと思ってました。。こういう本格的な撮影は初めてなので、楽しかったです。


関連記事/参考資料

本授業に関連する記事をまとめておきます。

プログラミング初心者時代の話
海外登壇
フリーランス時代の海外での仕事
その他海外関連
今回の就職の経緯
情報発信について

おわりに

スクーの皆様、生放送に参加していただいた皆様、どうもありがとうございました!

f:id:shu223:20170111081523j:image:w600

(スクーのみなさんと)


最後に改めて授業へのリンクを載せておきます。


*1:僕が働いてるのはサンフランシスコであってシリコンバレーには含まれないらしいのですが、僕自身も最近知ったぐらいなので、そこらへんは許容していただけるとありがたいです😅

*2:スライド共有サービスにアップしてブログに載せてもいいかはスクーさんに確認済みです

*3:こうやってみると今が一番高くて「さすがアメリカ!」ってなるかもしれませんが、僕のアメリカでの評価はまだまだで、1日単価でいうと日本でのフリーランス時代の方が少し多いぐらいでした。フリーランス時代はお客さん仕事は6〜7割にして、残りの時間を新しい技術の勉強や書籍の執筆に充てていたので、年収としては今より低くなっています。

2016-12-01

Metalのコンピュートシェーダに関する諸々

Metal の compute shader について。随時書いていきます。


[[ thread_position_in_grid ]] って何?

こういう感じで、カーネル関数の引数から受け取れるやつ。

kernel void
add_vectors(const device float4 *inA [[ buffer(0) ]],
            const device float4 *inB [[ buffer(1) ]],
            device float4 *out [[ buffer(2) ]],
            uint id [[ thread_position_in_grid ]])
{
    out[id] = inA[id] + inB[id];
}

変数名としては id, gid, tid となっているのをよく見かける。


Metal Shading Language Specification / Guide』によると、

thread_position_in_grid identifies its position in the grid.

とシンプルに書かれている(4.3.4.6 Attribute Qualifiers for Kernel Function Input)。


これだけじゃその名前が表現している以上のことがわからないのでグリッドやスレッドの説明も引っ張ってくると、

When a kernel is submitted for execution, it executes over an N-dimensional grid of threads, where N is

one, two or three. A thread is an instance of the kernel that executes for each point in this grid, and

thread_position_in_grid identifies its position in the grid.

Threads are organized into threadgroups. Threads in a threadgroup cooperate by sharing data through

threadgroup memory and by synchronizing their execution to coordinate memory accesses to both

device and threadgroup memory. The threads in a given threadgroup execute concurrently on a

single compute unit12 on the GPU. Within a compute unit, a threadgroup is partitioned into multiple

smaller groups for execution.

ちょっとよくわからない。。


ここの回答にわかりやすい説明があった。

`thread_position_in_grid` is an index (an integer) in the grid that takes values in the ranges you specify in `dispatchThreadgroups:threadsPerThreadgroup:`. It's up to you to decide how many thread groups you want, and how many threads per group.

In the following sample code you can see that `threadsPerGroup.width * numThreadgroups.width == inputImage.width` and `threadsPerGroup.height * numThreadgroups.height == inputImage.height`. In this case, a position in the grid will thus be a non-normalized (integer) pixel coordinate.


なるほど、`dispatchThreadgroups:threadsPerThreadgroup:` を呼ぶときに渡すサイズ(`threadsPerGroup`と`numThreadgroups`)によって「グリッド」の範囲が決まり、`thread_position_in_grid` はそのグリッド内のインデックスを保持する、と。


テクスチャのサイズを取得

カーネル関数が、たとえば以下のように定義されていれば、

kernel void computeShader(texture2d<float, access::read> tex [[ texture(0) ]],

この引数texに渡されてくるテクスチャのサイズは、

    float w = tex.get_width();
    float h = tex.get_height();

という感じで取得できる。


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時から別のスカイプあるんだけど・・・」とやっと切り出した

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 | 12 |
2017 | 01 | 02 |