2023年の振り返りと2024年の抱負

あけましておめでとうございます🎍

年末にブログ書こうと思っていたのに気づいたら年明けて1週間経ってました。

2023年の振り返りと2024年の抱負を書こうと思います!

2023年の振り返り

ボルダリング

2023年、一番大きな変化はボルダリングにハマったことだと思う。 会社の同僚に誘ってもらって始めたら見事にどハマりしてしまった。

ボルダリング、パズル的な頭を使う要素と身体能力の両方使うので面白いなと感じてる。 ジムごとに壁や課題の特徴が違ってて、いろんなジムを開拓するのも楽しい。

自分のインスタも気づけばボルダリングの動画ばっかり上げるクライミングアカウントになってた。

ライミングシューズも物足りなさを感じて2足目を買ってしまった。まさかこんな早く買い替えるとは思ってなかった。

11月にはノボロックの外岩講習に参加して外岩にも挑戦することができた。ジムと違って手足の置き場に悩んだり、ホールドと違って滑るので難しかった。

しまなみ海道

9月には夏休みを使ってしまなみ海道にサイクリングへ。

レンタサイクルで80kmくらいの道のりを走った。天気も良かったし、景色がすごく綺麗だった。 自分の足で移動するのは楽しい。

四国に行ったのも初めてだったけど、すごく良いところだった。また行きたい。

ISUCON初出場

ISUCON13 にクックパッド新卒メンバーで出場した。普段モバイルアプリ開発をメインでしているのでISUCONで扱う技術はあまり馴染みのないものも多いがその分、新しい技術分野に触れるきっかけになって楽しかった。

せっかく出るならちゃんとスコアを残したいと、チームメンバーと時間を合わせて4日くらい過去問を練習したり、当日使う環境構築用のスクリプト用意したりちゃんと準備して挑めたのが良かった。

初期スコアのまま終了になったら悲しいなと思っていたけど、最終スコア12,971で(トップのチームと比べると全然まだまだだけど)ちゃんとスコアを残せてよかった。

とはいえアプリケーション側の改善しか入れられなくて、DNS水責めは何もできなかったし3台あったサーバも1台しか使ってなかったのでもっと総合格闘技っぽい楽しみ方ができるようになりたいなと思った。また機会があれば出てみたい。

退職

2024年の1月で5年間勤めたクックパッドを退職することにした。12月末に最終出社で現在は有休消化中。

メインではモバイルアプリ開発のエンジニアとして働いていたが、ハードウェアの開発に携わったり、新規事業で「レシピ」と「かいもの」をつなぐような新しい価値を提供するためのサービス開発をしたり、採用に携わったり幅広く挑戦できた。

techlife.cookpad.com speakerdeck.com

5年間色々なことがあったし、沢山成長させてもらえたと思う。優秀で優しい良い人たちに囲まれて働けて良かった。

2024年の抱負

転職

2月からは新しい会社で働き始める予定である。初めての転職ということもあり、転職先で成果が出せるかドキドキしているけど、環境を変えて心機一転頑張りたい。

クックパッド時代の上司に「あつやさんは楽しんでいる時が成果が出る時ですね」と言われたことがある。 僕自身は作ることが好きで、作ったものによって人に貢献することが好きである。 プロダクトに貢献することでユーザーを喜ばせたり事業を伸ばしたり、学びを還元することで組織に貢献したり、そういった動き方ができているとき自分は楽しさを実感するので、次の会社でもこれは大事にしたい。

ボルダリング

去年1年ボルダリングして、横パンで6級→4級が登れるくらいになった。今年は横パンで3級を安定して登れるようになりたい。 去年外岩もデビューできたので、今年は名前付きの課題が登れるといいな。 そろそろコンペも出てみたい。あとリードクライミングも挑戦してみたい。

入院

実は来週から手術入院の予定がある。

肩に脂肪腫ができてしまった。良性腫瘍の判定なのですぐに大事になるわけではないのだが、サイズが大きめのため悪化時にリスクがあるため摘出手術を受けることにした。

人生初の全身麻酔 & 手術 (入院も物心ついてからは初) なのですごくドキドキ。 今年の初詣は "無事に手術終わりますように" のお願いをしました。

さいごに

2024年もよろしくお願いします!

2022年振り返りと2023年の抱負

あけましておめでとうございます!

2022年の振り返りと2023年の抱負を書こうと思います。

2022年の振り返り

1月

Nellのマットレスを買いました。シングルベッドをダブルベッドに買い替えて睡眠環境がめっちゃ良くなった!

2月

新型コロナウイルスに罹った。。。

  • コロナっぽい症状がでた時にどうしていいのか分からずパニックになったり、土日で空いてる病院なくて2万円払ってPCR受けたのはいい思い出
    • 熱が引いた後も2~3週間くらいコロナ後遺症で咳喘息になってた
    • ユニバ行く予定を諦めた😢

コロナ症状ある期間で体重が3kg落ちた

3月

静岡に行って人生初さわやかをしました。さわやかのハンバーグ、柔らかくて飲み物だった。また食べに行きたいな

INN THUNDERBOLT PROJECT BY FRGMT & POKÉMON に泊まった!黒カビゴンと黒ピカチュウのぬいぐるみをおうちにお迎えしました

PS5も買った!

4月

カンデオホテルズ大宮に連泊しました。カンデオホテルズはサウナが最高で大好きなホテルです

函館にも行きました。桜の季節の五稜郭はいいぞ

5月

ジムに通い始めました!今年のベストサブスク。金で買える健康は最高!

同じ部署のメンバーと福岡に旅行に行きました!福岡はご飯美味しくて最高。何回でも行きたい

6月

家庭用脱毛器を買いました。元々腕や脚の体毛濃くて割とコンプレックスだったのですが週1回半年続けてたら大分目立たなくなってきました。今年のベストバイ

xn--rckyc9e.com

7月

好きな女の子ができて楽しかった期。毎週遊びの予定を入れてたけど付き合ってからは1週間で振られてしまった😢👋

8月

iOSDCの準備で大忙し。大変だったけど会社のメンバーと一緒に資料作ったり発表練習会したり楽しかった。ブースの企画とかもやってたので、とにかくバタバタだった。

プライベートは傷心旅行を兼ねて金沢に行きました。金沢、駅前に観光地がまとまってて観光しやすかった。

ちょっと足を伸ばして新石川県立図書館まで行ったらすごくよかったです。1日時間潰せてしまう。また行きたいな

9月

iOSDCが3年ぶりのオフライン開催で楽しかったです。久しぶりに会う人も沢山いて懐かしい気持ちだった

iOSDC登壇お疲れ様を兼ねて潮見プリンスホテルに3泊引きこもってスプラトゥーンやったのも楽しかった。

www.princehotels.co.jp

10月

DroidKaigiの初オフライン参加しました。去年からAndroidも書いててDroidKaigi行ってみたかったので行けて良かった。

2月に行けなかったユニバにも行けて最高!!

11月

Cookpad TechConfにスタッフとして参加しました。多くの方が来場してくださって、活気を感じられたのが嬉しかったです。

札幌に旅行も行きました。ホテルエミシアのテレワークプランで4泊したんですが、電源アリ、軽食・フリードリンク付きのカフェで仕事して、疲れたら併設されてる温泉施設のサウナで整える環境が良かったです。またやろう

www.hotel-emisia.com

12月

イベント会場貸し切って忘年会しました。ジャンプOK・発声OKのライブ近年失われてしまっていたので楽しかった〜! gp.yokohama-coast.com

2日前に突然誘ってもらって、前日に航空券取って鹿児島旅行に行ったのもいい思い出。黒豚も魚も鳥刺しも白熊アイスも美味しかった。鹿児島また行きたい!

実家帰るついでに期限切れそうだった無料宿泊特典を使ってW大阪に泊まった!最高だったのでまた泊まりに行きたい

2023年の抱負

  • ジムは継続するぞ💪

    • 健康大事。健康のために始めたんですが、「痩せた?」って言ってもらえるの普通に嬉しいので来年はもう少し体型絞ろうかな
  • 旅行は好きなので引き続き行くぞ

    • 2022年も色々なところに行ったけど2023年も色々なところに行って沢山美味しいものを食べるぞ!
    • カメラ(Sony α7iii)を持ってるのだけど旅行の時とか全然持ち出せてないので、もう少し軽いカメラ買おうかなと考え中🤔 (GR IIIxが気になっている)
  • 昔やってた弓道をまたやろうか考え中

    • 中学時代弓道をやっていて初段までは取ったんですが、多分今やっても弓引けないので弓道教室から再開したいな
  • 活動の幅を広げたい。外にも出て行きたい

    • モバイル以外にも手を出したいし、なんならエンジニアリング以外のサービス開発に必要な事もどんどんやっていきたい。
    • あと、社内に引きこもりがちなのでなんとかしたい。社外向けに技術記事書いたりブログ書いたり学生時代の方がしてたよな…と思いつつ、元々内向的な性格がコロナで余計に内向的になっているので、もう少し社外に出て行きたい。。。
  • アイコンをなんとかしたい

    • 色々なアカウントで使ってるtry! Swift 2018のRikoのフォトパネル持った写真、アイデンティティにもなってるんですが、今年で撮影から5年経ってしまいそろそろ年齢詐称気味なので、インターネットアカウントのアイコンをなんとかしたい!!

さいごに

今年も健康で楽しく過ごしたい!2023年もよろしくお願いします!

iOSDC Japan 2022で「施策基盤としてのディープリンク」という発表をしました! 〜ウラ話を添えて〜

ididblog

iosdc.jp

今年もiOSDCに参加してきました。3年ぶりのオフライン開催、すごく楽しかったです。2017年から参加してるので5年目のiOSDCでした。

自分の過去のiOSDCへの参加形態を振り返ってみると

(2020年と2021年ブログ書くのサボってますね...私)

このような形で参加していて、さて今年はというとCfPを採択していただけて4年ぶりにレギュラートークのスピーカーとして参加することになりました🎉

2018年にレギュラートークスピーカーをした頃はまだ学生で、その時はデバイス管理の話をしてました (懐かしい...)

speakerdeck.com

施策基盤としてのディープリンク 〜なめらかにアプリが開く体験のために〜

speakerdeck.com

今年登壇した内容が「施策基盤としてのディープリンク 〜なめらかにアプリが開く体験のために〜」になります。

登壇ウラ話

実は最近、メイン業務はAndroidアプリ開発を行なっています。登壇の時に紹介を行ったレシピサービス クックパッド上で買物体験を提供するチームに所属しており、そこでAndroidアプリを書きつつ、iOSはチームメンバーのコードレビューに入ったり、趣味リファクタリングをする程度の関わり方になりつつあります。

iOS/Android両方経験のあるエンジニアということもあり施策基盤を用意するような関わり方も増えてきたのですが、実はエンジニアがディープリンクを一度仕組みとして用意してしまった後その後活用するのは施策オーナーが多く「アプリへの流入に対してどういう仕組みを活用できるのか」、「施策の効果を最大限発揮するためにどういう改善ができるのか」、「計測したい数値をどう把握できるようにすればよいのか」といった点に関してエンジニアと施策のオーナーの共通認識を取れていないケースが多いのでは?と感じるようになりました。

例えば、施策オーナーが言う 「ディープリンクを用意して欲しい」 は Firebase Dynamic Linksを使ったDeferred Deep Linkingに対応したダイナミックリンクが必要なのか、Custom URL Schemeのルーティングを実装して欲しいのか、はたまたUniversal Linksが必要なのか...

用語の認識を揃えるところから進めないと、お互い曖昧な認識のまま事が進み、施策開始のタイミングで必要なアプリへの流入経路が用意されていなかったということが発生しそうだと考えました。

ただ、ディープリンク関連の用語は似たような言葉も多く、列挙されてるだけではあまり理解が進まないと感じたので、最初は図を作って社内共有するところから手をつけ始めたました。

社内ブログに書いた記事

社内でも結構評判が良くて、「ディープリンク関連の用語の整理や施策に応じてどういう仕組みを活用できるのかはエンジニアにとって有益な知見になるのでは?」と考えるようになり今回のiOSDCでの登壇に繋がったのでした。

Twitterでいただいた感想

ありがたいことに沢山の方に登壇を見ていただき、Twitter上でも沢山感想をいただきました。(本当にありがとうございました!!!嬉しかったです!)

いくつかピックアップさせていただいたのですが、自分の登壇の原点になった「ディープリンク関連の用語の整理や施策に応じてどういう仕組みを活用できるのかはエンジニアにとって有益な知見になるのでは?」に対して、登壇を見ていただいた方に自分の発表した知見を届けられたように感じて、登壇して良かったなと改めて思えました!

さいごに

実は、今年クックパッドのスポンサーブースの企画のリードをしてました。バックパネル作ったりテーブルクロス作ったりTシャツ作ったりパネル作ったり、イベントの企画したり、事前告知ブログ書いたり、@cookpad_tech のツイート運用したり!(この辺の深い話は会社のテックブログにでも書こうかな)

3ヶ月くらい準備に時間を使ってたのですが、ノベルティちゃんと封入業者に届いてるか心配になったり、当日スタッフが混乱しないか不安になったりしながらの日々だったり😇

当日も自分の登壇が終わると今度は社員メンバーの登壇を撮影したりブース企画したり、過去1バタバタなiOSDCでした (笑)

自分の登壇も同僚の登壇も、ブース運営も大きな問題なく3日間を乗り越えられてよかった!きっとiOSDC Japan 2022は自分にとっても思い出深いiOSDCになるんだろうなあ〜!来年に向けてまた頑張るぞ💪

2020年行ったところ、泊まったところ

あけましておめでとうございます。

2020年も終わるので何か記事を書こうと思っていたのですが、気づけば新年を迎えてしまっていました。

表題の通りで、2020年に行ったところや泊まったところをまとめてみようと思います。

1月

神戸

www.kobe-porttower-hotel.com

ここに泊まりました。温泉サウナ付きなので選んだのですが、結構よかったです。 お風呂上がりの休憩スペースでアイスやビールが売っていて、♨️ 🔜 🍺の体験が最高でした

神戸ハーバーランドにも近くて、ハーバーランドでも食事や観光を楽しめました。

博多

わいわいswiftc 番外編ワークショップ #3 - 福岡 に参加するために博多に行きました

randb.jp

泊まったのはここ。なるべくお金をかけずに博多にいくぞ!という気持ちでの旅行だったので、飛行機はJALのマイルで、宿は博多駅から近くてリーズナブルなホテルを探していたら、ここを見つけました。 無料朝食がついてるのが嬉しかったです。朝食のゆでたまごが美味しくて、2回くらいおかわりしました🥚🥚

博多に行った時に2つ温泉にも入ってきました。

www.namiha.jp

みなと温泉は博多ふ頭にある温泉で、露天風呂から波の音を聴きながら入れたのが印象的でした。 お風呂上がりには九州のみどり牛乳をいただきました。

www.manyo.co.jp

万葉の湯は温泉リゾート施設のような感じになっていて、かなり大きな施設でした。 由布院温泉と武雄温泉の二つの源泉が一つの温泉施設で楽しめるようになっていて、お得ですね。 サウナもハーブサウナとスチームハーブサウナの二種類あったのが印象的でした。

2月

群馬

昨年は仕事の関係で群馬にいくことが多かったです。

ikaho-sakurai.com

伊香保温泉の旅館さくらいに行きました。 2月の群馬すごく寒かったのですが、その分露天風呂が気持ちよかったです。 夜、朝両方温泉入ったのですが、朝風呂では冬の澄んだ空気と共に榛名・赤城の山々を一望できて気持ちがやすらぎました。

旅館で朝ごはんいただいたのですが、こちらも美味しかったです。

3月〜5月

ちょうどコロナが流行り出してきて、会社も完全リモートになったのがこの頃で、ひたすら家に引きこもってました

6月

札幌

1週間ほど札幌に行っていました。5末までずっと家に引きこもっていた結果、精神状態がおかしくなりそうで環境を変えたかったので、無理やり札幌旅行を計画しました。仕事もホテルにこもって札幌からリモートしていました。

www.apahotel.com

泊まってたのはアパホテルです。この頃はGoToトラベルも無かったのですが、ホテルのテレワーク割プランで2500円/泊くらいで泊まれました。 大浴場付きでこの値段なら安いなと思ってここにしたのですが、大浴場が閉鎖中で悲しかったです。

余談ですが、学生時代からアパホテルをよく使っていて、ポイントが沢山貯まっていたので先日カタログギフトと交換しました。

温泉は北のたまゆら温泉と新千歳空港温泉に行ってました。

www.e-u.jp

www.new-chitose-airport-onsen.com

新千歳空港温泉、空港の温泉とは思えないほど本格的でいい湯でした。

7月

有給付与日が8月なのですが、7/1の時点で有給義務化で定められている年5日の年次有給休暇の取得義務に対して2日しか有給とっておらず7月に3日休む必要が出てしまったので、どこか旅行にいくことにしました。

どこか行きたい場所があったわけではなく、休暇をずっと家で過ごすのも忍びなかったので、JALどこかにマイルを使って旅行することにしました。

どこかにマイルの結果、福岡空港を引き当てたので九州観光をしてきました。 とはいえ、博多には1月に行っているので博多から特急でいける長崎、大分(別府)をメインで観光することにしました。

という経路で移動しました。移動経路にかなり無駄があるように見えるのですが、区間変更できないので博多空港発着を考えると上記のようなルートになってしまいました。 特急はJR九州予約ネットから予約すると早割が効くので、よかったです。

長崎

www.candeohotels.com

カンデオホテルズ長崎新地中華街に泊まりました。これまでカンデオホテルズ名前も知らなくて、露天とサウナがあるからという理由で予約とったのですが、カンデオホテルズを知れたのが2020年一番の功績かもしれません。 このホテル、サウナがマジで良くて、サウナの環境といい水風呂の温度といい、脱衣所にウォータークーラー設置してあるのも良くて無限に最高でした。

www.candeohotels.com

後から知ったのですが、このホテルの代表の方がサウナ好きの方のようで(上の記事参照)、サウナ好きが作ったスカイスパ そりゃ最高にきまっとるやんけ〜!という具合です。

気づけばすっかりカンデオホテルズの虜になってしまいました。

大分

www.kamenoi.com

ここに泊まりました。ホテルの朝食ブッフェで出てきた地獄蒸しが美味しかったです。 せっかく別府に行ったので、別府の温泉にいくつか入ってきました。(ホテルの温泉大浴場も入ったのですがあまり記憶に残ってない。。。)

www.hyotan-onsen.com

一つ目がひょうたん温泉というところで、19本の滝湯がずらーっと並んでいるのが圧巻でした。 お昼過ぎにここの温泉に行ったのですが、すごく天気が良くて夏っぽい青空を見ながら長時間ぼーっと露天風呂に入っていました。

お風呂上がりにいただいた温泉蒸しプリンとかぼすうどんが美味しかったです。

hoyoland.webcrow.jp

もう一つが別府温泉保養ランドで、ここはいろいろと凄かったです。 山の中にある(バスを30分以上乗って行った)温泉で、見た目も古い町役場のような見た目の温泉施設で、かなり年季が入ってました。

混浴の泥湯が有名な温泉でした。 水着の着用はもちろん無く、男女の仕切りもあってないような物なので、泥湯からでようとするとタオルで隠すのに一苦労みたいです。(自分が行った時は男性客だけでした)

泥を落とすためのシャワーしかないので髪の毛を湯船につけることができなかったり、入るのにやや敷居高く感じてしまうところもありますが、温泉はものすごく気持ちよかったです。「本物の温泉に入ってる!」って感覚でした。 番台のおじさんも優しくてまた行ってみたい温泉でした。

8月

東京

www.candeohotels.com

長崎で泊まったカンデオホテルズがすごく体験が良くて、近場にある新橋のカンデオホテルズにも泊まりに行きました。 ここも長崎とはまた少し違った感じのスカイスパでした。気持ち良くてよかったのですが、個人的ナンバーワンはまだ長崎です笑

9月

名古屋

実家に帰省しました。中部国際空港経由で帰省したので、中部国際空港の風(フー)の湯に行きました。 www.centrair.jp

温泉自体は新千歳空港温泉の方が好きなのですが、ここは滑走路に面していて飛行機を眺めながら温泉に入れるのでよかったです。

10月

1年で一番の転機があったのが10月なのですが、どこか旅行したりはしませんでした。

10月他に書くこともないので余談ですが、神奈川にある宮前平源泉 湯けむりの庄、近場で行けて好きな温泉なので月1~2くらいで行っています。

www.yukemurinosato.com

会社がフレックスなのですが、16~17時代で退勤する時は大体仕事終わりにここに行っています。

11月

札幌

実は今年2回目の札幌でした。北海道、ご飯が美味しいので何回でも行きたくなってしまう。 小樽運河みたり、ルタオでケーキ食べたり、お寿司食べたりしました。

www.jrhotels.co.jp

泊まったのはJRタワーホテル日航札幌でした。 客室が23階~34階に位置していて、お部屋のグレード関係なく札幌の街並みを楽しむことができました。

朝食ビュッフェで丼に海鮮盛り放題で、オリジナル海鮮丼を作って食べることができたのが面白かったです。そして美味しい。。。

埼玉

www.candeohotels.com

どんだけカンデオホテルズ泊まるんだよ。という感じですが大宮のカンデオホテルズに泊まりに行きました。 この時、さいたま市が宿泊促進キャンペーンをやっていて3,000円/泊の補助をGoToトラベルの値引きと別で受けることができたので、2500円/泊で泊まることができてお得でした(さらに地域共通クーポンももらえる)

サウナは言わずもがな最高でした。

12月

箱根

hanaori.jp

ロマンスなカーに乗って、箱根・芦ノ湖のはなをりに行きました。 宿泊予約サイトのReluxで2020年旅館人気ランキング1位になった宿で、設備の綺麗で全体的に木の温かみのあるお宿でした。 温泉はもちろん、足湯があったり、お部屋も部分的に畳が使われていて、ゆったりくつろげました。

夕飯はビュッフェスタイルで、小鉢取り放題だったのですが、この小鉢のお料理が美味しくて小鉢を沢山取りました。 これとは別でメインや汁物、デザートなどもあって満足度高かったです。

総評

GoToのおかげもあって普段なかなか泊まりづらい宿にも泊まることができました。 コスパよく旅行するのが好きで、学生時代はコストをできるだけ抑えつつ、値段に見合ったパフォーマンスを得られるかどうかという観点で旅行することが多かったのですが、Cost per performanceのパーセンテージ自体は維持しつつコストにベットすることでパフォーマンスも引き上げられるかどうかという観点で旅行するのも楽しそうだなと思うようになりました。 今年はホテルのクラブラウンジに行ってみたいので、ラウンジアクセスのある部屋に泊まるぞ!という気持ちで2021年もやっていこうと思います。

iOSDC2019に当日スタッフとして参加しました!

f:id:n_atmark:20190908001830j:plain

これは何

2019/9/5(木)~9/7(土)で開催されたiOSDC2019に当日スタッフとして参加したので、「当日スタッフはいいぞ。 」というのをブログで発信して、ぜひこのブログを読んだ方にも来年以降当日スタッフやってみてほしいな!という気持ちで、 モンスターハンターワールド:アイスボーンのダウンロード待ち時間が暇だったので 忘れないうちに、ブログにまとめようと思います!!

なんで当日スタッフやろうと思ったの

natmark.hateblo.jp

昨年のiOSDC2018ではスピーカーとして参加したので、今年もスピーカーとして参加しようと思っていました。しかしCfPを通せず(実はそんなにネタが無くて、1つ絞り出してみたもののあえなく撃沈)一般参加しようと思っていました。 そんな時に、コアスタッフをされている会社の先輩の@su-さんから当日スタッフを誘われたので、申し込んでみることにしました。

当日スタッフの申し込み

当日スタッフは一般公募で、 @iosdcjpのツイートで募集されていました。

なにやるの

  • メインは担当(受付担当/部屋担当/HQ...)をしつつ、day0(前夜祭)の朝に会場準備をしたり、day2(最終日)の夜に片付けという内容です。
    • 僕の担当はトラックAの部屋担当でした。(初スタッフで一番大きな部屋の担当になってしまい、初日は結構焦った💦)
    • 当日の司会進行や、タイムキーパー、PA(映像音響)・参加者の方の誘導などをやりました。
      • もちろん一人では無くて、各部屋担当が5~6名いて、部屋担当を指揮してくださるコアスタッフの方もいらっしゃるので、初めてでも全然問題なく担当をこなすことができました 🙆‍♂️(マニュアルも作ってもらえているので安心です!!何も心配いりません!!)

大変なの?

  • これ見て!!!
day0(前夜祭) day1 day2

準備があった初日と、片付けをした最終日はやっぱり消費カロリー高めですね。初日の消費カロリー750kcalというのは、体重58kgの人が90分ランニングするのと同じくらいの消費カロリーだそうです。

f:id:n_atmark:20190908003954p:plain

これを大変と思うかどうかは人次第ですが..........................................................
僕はしっかり疲れました!!!

大変だけど良かったところ

  • カンファレンスの裏側を知ることができる

    • 普段、参加者側で参加していると知れないようなことがたくさんあります...!!
      • 「iOSDCの会場のトラックAとトラックBの結合はこうなってるのか〜」とか、
      • 「こんなところにスタッフ控え室あったのか!!!」とか
      • ノベルティの数こんなに多いの!?!?」とか f:id:n_atmark:20190908004802j:plain (この箱全部、受付で配っていたトートバックが入ってます!!!)
      • 「録画・配信機材こんな風になってたのか!!」とか f:id:n_atmark:20190908004545j:plain
  • iOSDCの雰囲気を知ることができる!

    • iOSDC初めての方こそiOSDCの当日スタッフおすすめです!!!!
  • スタッフの皆さんが優しい!!!

    • カンファレンススタッフ慣れされてる方が多くて、いろいろ教えてもらえました👏
    • レッドブルを差し入れでもらったり、北海道からスタッフ参加されている方に白い恋人をもらったり(ありがとうございました!!)
  • 懇親会でどこのテーブルに行っても「スタッフお疲れ様でした!!」と言ってもらえる。最高!!🎉🎉🎉🎉

    • これだけでスタッフやって良かったーーーーー!!と思える。オススメです!

なにより達成感が半端ないです!3日間、1日1日がすごく濃いので、やりきった感がすごい!
そしてビールが最高にウマい!!(しかも、iOSDCで提供されるビールは良いビールが揃ってる)
ここまで読んでくださった方、当日スタッフオススメです!!

また来年のiOSDCで!#ididblog

Findyのコントリビューションオブザイヤーに当選した

昨年、Findyさんのコントリビューションオブザイヤーという企画がありました。

findy-code.io

Findy内での2018年のコントリビューションをTwitterにシェアすると、5名の方に下のような豪華プレゼントが当選するキャンペーンで

  1. 「技術書買おうぜ」セット:1名さま(Amazonギフト券1万円分)
  2. 「草を生やそう」セット:1名さま(草シール・草Tシャツ・草サンダル)
  3. 「スタートアップに関わりたいエンジニア」セット:3名(Findy Engineering Book Vol.1, 2)

僕もTwitterに2018年のコントリビューションを投稿しました!

そしたら、なんと「技術書買おうぜ(Amazonギフト券1万円分)」セットが当選しました!!

f:id:n_atmark:20190301224327p:plain

ありがとうございます!!!!!

f:id:n_atmark:20190301224631j:plain

さっそく、ちょうど読んでみたかった

2冊をAmazonで買いました💪

1万円分ギフト券いただいたので、他に欲しい技術書が出てきたらまた購入してブログで買ったもの紹介できればと思います🙆‍♂️

(FUN Advent Calendar 2018) 入門Android Neural Networks API

この記事は、FUN Advent Calendar 2018 7日目の記事です。

前置き

今年もアドベントカレンダーの時期がやってきましたね。@n_atmarkです。

今年は、卒業研究で扱っているAndroid Neural Networks API(以下NNAPI)について書こうと思います。

入門 Android Neural Networks API

Android Neural Networks APIとは

Android8.1 (APIレベル27)から利用可能になったオンデバイス上で機械学習推論を行うためのAPIで、NNAPIを経由することで機械学習推論を行う際にハードウェア高速化を行うことが可能になります。 f:id:n_atmark:20181124002626p:plain

NNAPIに入門する前に

NNAPIの抽象化

  • NNAPIは4つの主な抽象化を使用しています

  • モデル: 数学的操作のグラフ

  • コンパイル: 上記モデルを下位レベルのコードにコンパイル
  • メモリ: メモリマップされたファイル、メモリバッファをさす
    • アプリケーションは通常、モデルを定義するのに必要なすべてのテンソルを含む1つの共有メモリバッファを作成
    • メモリバッファを使用して、実行インスタンスの入力と出力を格納できる
  • 実行: 入力セットにNNAPIモデルを提供し、結果を収集するためのインスタンス

NNAPIのモデル抽象化

さらに、NNAPIのモデルはオペランドとオペレーションという2つの抽象化がされています

NNAPIがサポートする操作(オペレーション)

NNAPIがサポートする操作として以下のようなものがあります。

  • 数学演算
    • ANEURALNETWORKS_ADD
    • ANEURALNETWORKS_MUL
    • ANEURALNETWORKS_FLOOR
  • 配列演算
    • ANEURALNETWORKS_CONCATENATION
    • ANEURALNETWORKS_DEPTH_TO_SPACE
    • ANEURALNETWORKS_DEQUANTIZE
    • ANEURALNETWOKRS_RESHAPE
    • ANEURALNETWORKS_SPACE_TO_DEPTH
  • イメージ操作
    • ANEURALNETWORKS_RESIZE_BILINEAR
  • 検索操作
    • ANEURALNETWORKS_HASHTABLE_LOOKUP
    • ANEURALNETWORKS_EMBEDDING_LOOKUP
  • 正規化操作
    • ANEURALNETWORKS_L2_NORMALIZATION
    • ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION
  • 畳み込み演算
    • ANEURALNETWORKS_CONV_2D
    • ANEURALNETWORKS_DEPTHWISE_CONV_2D
  • プーリング操作
    • ANEURALNETWORKS_AVERAGE_POOL_2D
    • ANEURALNETWORKS_L2_POOL_2D
    • ANEURALNETWORKS_MAX_POOL_2D
  • アクティベーション操作
    • ANEURALNETWORKS_LOGISTIC
    • ANEURALNETWORKS_RELU
    • ANEURALNETWORKS_RELU1
    • ANUERALNETWORKS_RELU6
    • ANEURALNETOWORKS_SOFTMAX
    • ANEURALNETWORKS_TANH
  • その他の操作
    • ANEURALNETWORKS_FULLY_CONNECTED
    • ANEURALNETWORKS_LSH_PROJECTION
    • ANEURALNETWORKS_LSTM
    • ANEURALNETWORKS_RNN
    • ANEURALNETWORKS_SVDF

NNAPI Flow

NNAPIが推論を行うまでのフローは以下のようになっています f:id:n_atmark:20181124003539p:plain

NNAPIに入門する

今回、NNAPIに入門するためにAndroidNDKのnn_sampleを例に説明します。 github.com

2つの入力を受け取って、1つの出力を返すサンプルになっています。 f:id:n_atmark:20181124010135p:plain

モデル構造は加算と乗算だけのシンプルなものになっています。 f:id:n_atmark:20181124011443p:plain

レーニングデータへのアクセス

NNAPIが提供している ANeuralNetworksMemory_createFromFd 関数を用いて、ファイルディスクリプタを渡すことで、訓練データをファイルから取得し、メモリバッファを作成します。

// 訓練されたデータを含むファイルからメモリバッファを作成
ANeuralNetworksMemory * memoryModel = NULL;
int fd = open(“training_data”, O_RDONLY);
ANeuralNetworksMemory_createFromFd(size + offset, PROT_READ, fd, 0, &memoryModel);

オペランドを追加する

NNAPIが提供している ANeuralNetworksModel_addOperand 関数を用いて、モデルにオペランドを追加します

// 空のモデルを定義する
ANeuralNetworksModel * model;
ANeuralNetworksModel_create(&model);

// [200]のテンソルを定義
ANeuralNetworksOperandType float32TensorType{
        .type = ANEURALNETWORKS_TENSOR_FLOAT32,
        .dimensionCount = 1,
        .dimensions = dimensions,
        .scale = 0.0f,
        .zeroPoint = 0,
};
// アクティベーション関数用のオペランドを定義
ANeuralNetworksOperandType scalarInt32Type{
        .type = ANEURALNETWORKS_INT32,
        .dimensionCount = 0,
        .dimensions = nullptr,
        .scale = 0.0f,
        .zeroPoint = 0,
};

ANeuralNetworksModel_addOperand(model, &scalarInt32Type); // for NONE activation function
ANeuralNetworksModel_addOperand(model, &float32TensorType); // tensor0
ANeuralNetworksModel_addOperand(model, &float32TensorType); // tensor1
ANeuralNetworksModel_addOperand(model, &float32TensorType); // tensor2
ANeuralNetworksModel_addOperand(model, &float32TensorType); // tensor3
ANeuralNetworksModel_addOperand(model, &float32TensorType); // intermediateOutput0
ANeuralNetworksModel_addOperand(model, &float32TensorType); // intermediateOutput1
ANeuralNetworksModel_addOperand(model, &float32TensorType); // multiplierOutput

// addOperandした順番に、オペランドにindexがついてる
uint32_t fusedActivationFuncNone = 0;
uint32_t tensor0 = 1;
uint32_t tensor1 = 2;
uint32_t tensor2 = 3;
uint32_t tensor3 = 4;
uint32_t intermediateOutput0 = 5;
uint32_t intermediateOutput1 = 6;
uint32_t multiplierOutput = 7;

学習済みデータから取得した、重みやバイアスなどの定数値をオペランドの値に設定する

ANeuralNetworksModel_setOperandValue関数、ANeuralNetworksModel_setOperandValueFromMemory関数を利用して、以下のようにtensor0、tensor2に学習済みデータから取得した定数値を指定します。

int32_t fusedActivationCodeValue = ANEURALNETWORKS_FUSED_NONE;
ANeuralNetworksModel_setOperandValue(model, fusedActivationFuncNone, &fusedActivationCodeValue, sizeof(fusedActivationCodeValue)); // 非活性化関数FUSED_NONEを設定
ANeuralNetworksModel_setOperandValueFromMemory(model, tensor0, memoryModel, offset, tensorSize * sizeof(float)); // tensor0に学習済みデータから取得した定数値を指定
ANeuralNetworksModel_setOperandValueFromMemory(model, tensor2, memoryModel, offset + tensorSize * sizeof(float), tensorSize * sizeof(float)); // tensor2に学習済みデータから取得した定数値を指定

オペレーションを追加する

ANeuralNetworksModel_addOperation関数を用いてオペレーションを追加します

std::vector<uint32_t> add1InputOperands = { tensor0, tensor1, fusedActivationFuncNone };
ANeuralNetworksModel_addOperation(model, ANEURALNETWORKS_ADD, add1InputOperands.size(), add1InputOperands.data(), 1, &intermediateOutput0); // tensor0とtensor1を加算

std::vector<uint32_t> add2InputOperands = { tensor2, tensor3, fusedActivationFuncNone };
ANeuralNetworksModel_addOperation(model, ANEURALNETWORKS_ADD, add2InputOperands.size(), add2InputOperands.data(), 1, &intermediateOutput1); // tensor2とtensor3を加算

std::vector<uint32_t> mulInputOperands = { intermediateOutput0, intermediateOutput1, fusedActivationFuncNone };
ANeuralNetworksModel_addOperation(model, ANEURALNETWORKS_MUL, mulInputOperands.size(), mulInputOperands.data(), 1, &multiplierOutput); // intermediateOutput0とintermediateOutput1を乗算

入力と出力として扱うオペランドを指定する

ANeuralNetworksModel_identifyInputsAndOutputs 関数を用いて、入力と出力として扱うオペランドを指定します

// 入力と出力として扱うオペランドを指定する
std::vector<uint32_t> modelInputOperands = {
        tensor1, tensor3,
};

ANeuralNetworksModel_identifyInputsAndOutputs(model, modelInputOperands.size(), modelInputOperands.data(), 1, &multiplierOutput);

ANeuralNetworksModel_finish(model);

コンパイラインスタンスを作成

ANeuralNetworksCompilation_create 関数を用いて、上で作成したモデルからコンパイラインスタンスを作成します

ANeuralNetworksCompilation *compilation;
ANeuralNetworksCompilation_create(model, &compilation);
ANeuralNetworksCompilation_setPreference(compilation, ANEURALNETWORKS_PREFER_FAST_SINGLE_ANSWER);
ANeuralNetworksCompilation_finish(compilation);

ここで、ANeuralNetworksCompilation_setPreference関数を用いることでコンパイラのオプションを指定することができます。指定できるものは以下のようなものがあります。

  • ANEURALNETWORKS_PREFER_LOW_POWER
    • バッテリー使用率を最小限に抑えて実行(頻繁に実行される場合に適している) 
  • ANEURALNETWORKS_PREFER_FAST_SINGLE_ANSWER 
    • より多くの電力消費が発生したとしても、できるだけ早く回答を返す
  • ANEURALNETWORKS_PREFER_SUSTAINED_SPEED 
    • 連続するフレームのスループットを最大にする(カメラからの連続フレームを処理する場合など)

モデル実行インスタンスを作成する

上で作成したコンパイラインスタンスからANeuralNetworksExecution_create関数を用いて実行インスタンスを作成します。

ANeuralNetworksExecution *execution;
ANeuralNetworksExecution_create(compilation, &execution)

入力値を指定する

ANeuralNetworksExecution_setInput関数を用いて、入力を設定します

std::vector<float> inputTensor1;
std::fill(inputTensor1.data(), inputTensor1.data() + tensorSize, inputValue1); //tensor1の形に合わせて[200]分をinputValue1で埋める

ANeuralNetworksExecution_setInput(execution, 0, nullptr, inputTensor1.data(), tensorSize * sizeof(float)); //ANeuralNetworksModel_identifyInputsAndOutputsで指定した入力ユニットのindex

ANeuralNetworksExecution_setInputFromMemory(execution, 1, nullptr, memoryInput2, 0, tensorSize * sizeof(float)); //memoryからも指定可能

出力先を指定する

ANeuralNetworksExecution_setOutput関数を用いて出力先を指定します

ANeuralNetworksExecution_setOutputFromMemory(execution, 0, nullptr, memoryOutput, 0, tensorSize* sizeof(float)); //ANeuralNetworksModel_identifyInputsAndOutputsで指定した出力ユニットのindex

// memoryを使用しない場合
float32 output[200];
ANeuralNetworksExecution_setOutput(execution, 0, nullptr, output, tensorSize* sizeof(float));

モデルを実行する

ANeuralNetworksExecution_startCompute関数を用いることで、モデルを実行できます

ANeuralNetworksEvent *event = nullptr;
ANeuralNetworksExecution_startCompute(execution, &event); // 推論の実行

// 実行の完了を待機
ANeuralNetworksEvent_wait(event);
ANeuralNetworksEvent_free(event);
ANeuralNetworksExecution_free(execution)

かけ足でしたが、ここまでの操作によってNNAPIを持ちいて機械学習推論を実行することができるようになりました。

まとめ

今回NNAPIについて紹介しましたが、実際は自分でNNAPIを直接操作することは殆どなく、モバイル向け機械学習フレームワークのML KitやTensorFlow Liteを用いる例が多くあまり触れられない部分だと思います。

おそらくこの記事を読んでNNAPIをさわるぞ!という人も少ないかと思いますが、もし興味があれば記事中でも紹介した googlesamples/android-ndk をみてみたり、さらにNNAPIの内部実装 android/frameworks/ml/nn/runtime/NeuralNetworks.cppをのぞいてみると面白いかもしれません。

明日は@akashi_akatsuki明石君の、「Prologでコード進行をコーディングする」です。