大学3年生ともなると、周りである程度インターンシップ行く人が出てくるものです。ですが、「私は流されないぞ」という厨二病的な何かを持った私はインターンシップのことは特に考えていませんでした。決して面倒くさかったわけではない!
8月17~27日の間、Wantedlyでインターンシップしてました。こういうことに前向きでない私がインターンシップすることになった経緯と、インターンシップで何したかを軽く紹介します。(細かいこと話すとあれなので)
経緯
以前、関西にいた頃に日本Androidの会絡みでお世話になってた住友さん(@cattaka_net)経由で4月にWantedlyに誘われ、久しぶりに住友さんと再会しつつ、川崎さん、山本さんも交えて私の近況を話したりWantedlyがどういう会社なのか聞いたりしました。その時点では目の前の実験や授業に忙殺されており、数カ月後に控える夏休みのことをほとんど考える余裕はなく、インターンシップに前向きな回答はしつつも、灰色(つまり埋まっても空いてもいない、よくわからない)の8,9月の予定に手付かずでした。いや、小倉唯ちゃんのツアーの予定は確保してましたがね…。(お気に入りは「パンドラ♡ショコラ」です)
5月になり、Wantedlyのインターンシップの募集が始まり、山本さんからご紹介いただきました。
“2018年卒エンジニア向け!!SUMMER INTERNSHIP 2016 “: https://www.wantedly.com/projects/52751
ただ、私はプロダクトとして市場に何かを生み出すより、研究者として根っことなる知を開拓したいと夢見ており、大学院に進学するつもりでした。なので、正確には上記募集の対象ではないのですが、せっかくなので”Infrastructure Engineer”の方で別枠参加することになりました。スケジュールを決めるにあたり私の方のカレンダーが着々と埋まり始め、最終的に 8月17~27日という短期のインターンシップになりました。
私が持ってるインフラエンジニアとして持ってるスキルはかなり古典的なもので、コンテナなどには完全に乗り遅れた状態です。ネットワークではVLAN組んだり、上のレイヤーでは仮想マシンクラスタで可用性あげるとか言ってるわけです(だからタグVLAN正義!)。上のWantedlyのインターンシップの紹介を見ての通り、WantedlyではもうすでにMicroserviceの考え方が導入されており、仮想マシン単位での管理が染み付いた私はサボってきたノウハウの更新の一気にやらないと行けないわけです。
振り返ってみると高校のときに自力でコンテナっぽいことやろうとして爆死したことありましたね…。きちんと調査ができないと車輪の再発明しようとして爆死という悲しいことになるので、広い視野を持たないと行けないなと思います。
逆に、このインターンシップで一気にMicroservice習得するぞ!という魂胆で夏休みを迎えました。
その後、紆余曲折を経て私が実際に取り組んでいたのは「画像処理」です。
OpenCVで画像処理
インフラの話は忘れてください。
画像処理を駆使してある目的を達成する技術を確立するのが、私が担当した業務の目的です。インターンシップ期間中、相川さんの下について、事前に相川さんが目星をつけていた手法や論文、すでに書かれているコードをベースに、手法の取り込みと検証、評価し相談しながら技術を向上させていきました。実際にコードを書いてる現場にいると業務で最前線で書いている方の知識量やコーディング力、集中力がすごい高い水準にあって、すごい場所に来たな…頑張ってついていくぞ、と言った感じでした。(実際かなり体力を消耗してしまい、継続して業務をこなしていくため自分自身をどうマネジメントしていくかを考えないと、将来社会に出たときに仕事にならないことを痛感しました…。)
画像処理といえばOpenCVと言った感じで、ここでもOpenCVを使っていました。なお、私のOpenCV歴は0年、春学期の実験項目の1つとして与えられたプログラムをちょいと弄っただけでした。ただ、レポートを書くに当たり基本的な座標の取扱いは学んでおり、また中学の時に3Dのゲームを作りたくて学んだ射影行列に関する知識はあり、実際に今回の業務をこなすにあたり活用できました。製品固有の応用知識はあっという間陳腐化して吹き飛んでしまいますが、理論に近い要素というのは5年以上前であろうと変わらず使えるということを実感させられました。なお、そこまで古いと自分が忘れてるので結局調べました。(だめじゃん。まぁゼロベースより理解は圧倒的に早い)
Python 2+OpenCV 3で様々な技術を試していきました。
Canny edge detection
http://docs.opencv.org/3.1.0/da/d22/tutorial_py_canny.html などを参考
Sobelフィルターによる微分画像を2つの閾値を使ってヒステリシスに2値化された(つまり境界かそうでないかがはっきりしている)出力を生成する手法です。
これ自体を動かすにはOpenCVの関数を呼び出すだけでできるのですが、実際のユースケースではただ実行するだけでは満足する結果が得られません。閾値の調整とCannyの実装自体のカスタマイズという2つのアプローチからこの手法をうまく適応する事になり、後者のためにはまず実装を把握する必要があるため、OpenCVのコードを読むことになりました。
何も考えずにmasterでコードを見てたため、当時最新の https://github.com/opencv/opencv/blob/5f30a0a076e57c412509becd1fb618170cbfa179/modules/imgproc/src/canny.cpp を開いたのですが…。「マジか」って顔になるコードです。oclはOpenCLの略であり、ocl名前空間はそのための機能を収めるものです。(GPUに送り込むkernelはこれです。)そして、__m128iという型や_mm_sub_epi16というマクロはSSE2用のマクロであり、コンパイルする際にインラインアセンブラを介して、SSE2の命令に変換されます。このあたりのマクロは”emmintrin.h”に収まっており、お手軽に(?)SIMD命令が使えるものです。(ジョークのように聞こえるかもしれないが、レジスタの割り当てを考える必要が無いだけですごいお手軽だ。本当にアセンブリを手で書いたら死ぬ)
なお、最近のIntel CPUではレジスタサイズが256bitであるAVX命令も実装しており、整数演算もできるAVX2を使って、LIGHTS OUTを解くというプログラムを過去に書きました。このコードを読むのに無駄にこの経験が生きることになるとは…。 https://gist.github.com/Mine02C4/c2a58fbf4dc1270166cb
平たく言えば今のOpenCVの実装はGPUを使うかSIMDを使うかという、高速化技術の投入を前提としたものになっており、素人が読めたもんじゃないと…。頑張って読んで、相談した結果、ひとまず改良は見送りになりました。
なお、実装を手軽に読みたい方向けの妥協案にOpenCV 2.4のコードを読むという方法があります。先の実装の場合 https://github.com/opencv/opencv/blob/2.4/modules/imgproc/src/canny.cpp がそれですが、見ての通り愚直に書かれてます。ここを見る限り並列化のコードが見えないので、おそらくシングルスレッドで走ってるのでしょうね。読みやすいですが、OpenCV 3.1とではだいぶパフォーマンスに差が出そうです。(私は計測していない)
Active contour model
このあたりを参考にしました。実装したのはSnake法です。過去にOpenCVでも実装があったのですが、消されました。とりあえず手法としてどうかを検証するため、遅いのを覚悟でPythonで実装しました。ただ、論文などの資料を調べていくと曲線のエネルギーの定義が文献により異なったり、画素のエネルギー算出が離散化した頂点だけってあまりにも離散化が雑ではとか、そもそもの手法にかなり疑問をいだきつつも実装、評価、調整、評価、調整、評価…と繰り返したが結局うまく行かずボツに。
GrabCut
http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_grabcut/py_grabcut.html などを参考
「背景だと確定している範囲」「前景だと確定している範囲」を元に混合ガウス分布を推定、パラメータ最適化、最小カットを求めるを繰り返して、前景と背景を分離する手法です。これもOpenCVに実装があるため、試すなら簡単です。この手法はユーザーの補助を受ける際に便利な手法で、例えばPhotoshopの自動選択ツールみたいなことができる手法です。でも、Photoshopの自動選択ツールほど高速には動かなかったので、あれは別の技術なのかなぁ…。
実際にガッツリ試したのはこれぐらいです。とりあえずどんなことをやってたか的な意味では十分なので画像処理に関してはこのあたりで切り上げます。
画像処理技術を検証するためにはGUIでリアルタイムで結果を確認したい!
ということで、PyQtを使って検証用GUIを作りました。QtDesignerを使って枠を作ったところに、検証用のデータを入れ込むメソッドを作って、上で紹介したような画像処理技術がどの程度の精度なのか、パラメータをいじるとどうなるのか、画像を差し替えたらどうなるのか、をリアルタイムで見られるGUIです。
業務環境
会社の雰囲気などは https://www.wantedly.com/companies/wantedly/post_articles/31028 などWantedlyのページに写真があったりします。IT系の学生であれば馴染み深いかなり自由な空間です。広いスペースにディスプレイが置かれた机が並んでおり、そこに自分のPCを繋いで開発するスタイルです。椅子の座り心地が最高でしたね…。(家の椅子もグレードアップしたいなぁと思って、いま探してます。おすすめの椅子とかあったらTwitterとかで教えてください。)
あと、むちゃくちゃMac率高いです。というかほぼみんなMacです。一方、私はThinkPad + Windows 10です。あのオフィスの中のエンジニアでWindows使ってる人、もしかした私だけだったかもしれませんね…?ただ、過去に働いたことある場所でも私以外全員Macということはよくある話で、それでも特に業務に支障ないです。直接いじる、コンピューターの世界との窓口(コンソール)としてWindowsを最も信頼している、というだけの話で、普段から書くコードの実行環境はLinuxだったり、PaaSだったりするわけですから、プログラミングをする上で手元のOSというのは大きな問題ではない時期なのかもです。ただ、プロプラなソフトはそうはいかない…(iOS…)
インターンシップを振り返って
振り返ってみると、いろんなことに手を出し、そしていろんな知識が得られたと思います。何より相川さんの様々なアドバイスから得られたものは多く、今後の糧にしていきます。
技術面以外では、とりあえず体力をつけないと、自分のパフォーマンスがあっという間に低下していくことを実感しました。インターンシップ前とインターンシップ後で疲労度に大きな差があったということは、そのペースで動き続けると破綻を来すという意味ですから、自己管理という観点からは失敗していたといえます。慣れ、なんですかね…?技術面よりこっちの方の課題が個人的には大きいです。
なお、冒頭では「流されないぞ」的な事書いてましたが、周りの学友がインターンシップ行ってるか行ってないかの情報はほとんど持っておらず、「流れを把握してない」が正解です。