Quantcast
Channel: その後のその後
Viewing all 314 articles
Browse latest View live

「iOS 12 Programming」のCore ML 2の章で勉強になったことのメモ

$
0
0

遅ればせながら、私も執筆に参加した「iOS 12 Programming」を読んでいます1。で、sonsonさん執筆のCore ML 2の章がめちゃくちゃ勉強になったのでメモ。

iOS 12 Programming

iOS 12 Programming

  • 著者:加藤 尋樹,佐藤 紘一,石川 洋資,堤 修一,吉田 悠一,池田 翔,佐藤剛士,大榎一司,所 友太,
  • 製本版,電子版
  • PEAKSで購入する

Core MLのカスタムレイヤー

iOS 11.2から、Core MLがサポートしていないニューラルネットワークのレイヤーを、開発者が独自にコードを書いてカスタムレイヤーとして使えるようになったようです。

Core ML Toolsでmlmodelに変換する際に、convertメソッドの引数にカスタムレイヤー名と、カスタムレイヤーをハンドリングするためのcallback関数をdictionaryで渡し、iOS側ではMLCustomLayerプロトコルに準拠する形でそのカスタムレイヤーの処理を実装します。

これだけだと全然よくわからないと思うのですが、書籍にはサンプルつきで具体的に丁寧に解説されているので、詳細はぜひ書籍を読んでみてください。

カスタムレイヤーがどう役立つのか

僕は機械学習は素人なので、基本的にCoreMLを案件で使う際には、誰か機械学習の専門家が別にいて、その人がTensorFlowなりで学習したモデルをiOSに組み込むという座組になることがほとんどです。ので、自分でCoreMLがサポートしてないレイヤーを使ったモデルを自分で構築することはないのですが、iOS側ではこういう手段もある」ということを知っていて機械学習屋さんに可能性を提示できるという点でこれは重要情報だなと。

実際にこれまでの実案件の中で「Core MLではこのネットワークはサポートされてないんだよね〜」ということを機械学習屋さんが言っていたことはあった(僕は具体的にはよくわかってない)ので、そこで「カスタムレイヤーでそこだけSwiftで実装するという手段もありますよ」という提案ができるのは大きいと思います。

Accelerate, Metalの利用

さらに、カスタムレイヤーを実装する際に、AcclerateフレームワークSIMD命令を利用)を使う実装、およびMetal(GPUを利用)を使う実装も示されているのが興味深かったです。

Core MLは内部的にはAcclerate/Metal(GPU)を利用しているというのはWWDCの資料等で見てきましたが、これまではそこは完全にブラックボックスで、開発者が実際にMetalのコードを書くことはありませんでした。カスタムレイヤーの登場によって、またMetalを自分で書く場面が増えたということで、「Metal入門」著者としては嬉しい限りです2

ニューラルネットワークの圧縮

Core ML 2で追加された、ニューラルネットワークの情報量を圧縮する、つまりmlmodelファイルのサイズを小さくする機能についての解説があります。仕組みから解説されています。

Create MLを使って画像認識モデルをつくる場合は転移学習を使うことで比較的軽量にモデルがつくれますが、そうじゃないタイプのモデルの場合、ファイルサイズは結構大きくなりがちです。アプリのファイルサイズは10年前程ではないにしろ、やはり機械学習モデル導入の障壁のひとつとなりうるところですので、こうした手段を知っておくことは必要でしょう。

まとめ

iOS 12 Programming」のCore ML 2の章で勉強になった点についてまとめました。他にもCreate MLについての解説もあります。気になった方はぜひPEAKのサイトで目次・無料サンプルをチェックしてみてください。(直販のみです、Amazonでは買えません)

iOS 12 Programming

iOS 12 Programming

  • 著者:加藤 尋樹,佐藤 紘一,石川 洋資,堤 修一,吉田 悠一,池田 翔,佐藤剛士,大榎一司,所 友太,
  • 製本版,電子版
  • PEAKSで購入する

  1. 著者の一員なのに読んでいないのかと怒られそうですが、自分の担当章で手一杯で、読めていません。PEAKS永野さんや編集で参加された横田さんが横断的にチェックしています。

  2. 本書の検証によると、今回の実装・実行環境ではGPUでの処理は実行されなかったそうですが。。


try! Swift Tokyo 2019の復習 #tryswiftconf

$
0
0

平日に戻ったら復習の機会もなくなるのでできるだけスライドとかで復習していきます。ここに書いた以外にも素晴らしいセッションがたくさんありましたが、会場で理解が追いつかなかったもの、あまりちゃんと聞けなかったものを中心に。

Keypath入門 - Introduction to Swift Keypaths

speakerdeck.com

SwiftのKeyPathを使って型の抽象化を行う話。例として、以下のような全然違う要素を持つStructを抽象化するのはProtocolだとできないけど、KeyPathを使えばできるよ、と。

f:id:shu223:20190325060340p:plain

こういうStructがあるとして、

structUser {
    varusername:String
}

varplayer= User(username:"マリオ")

で、Swiftのキーパスではこんな感じでUserの持つusernameにアクセスできる。

player[keyPath: \User.username] ="リンク"

(この書式、全く知らなかった)

こんな感じで変数に格納することもできる。

letnameKeyPath= \User.username
player[keyPath:nameKeyPath] ="ルイージ"

で、キーパスには色々種類があるという話と、

  • KeyPath<Root, Value>
  • WritableKeyPath<Root, Value>
  • ReferenceWritableKeyPath<Root, Value>
  • PartialKeyPath
  • AnyKeyPath

合成できるという話があって、

f:id:shu223:20190325060633p:plain

これらの性質を使って、冒頭に挙げたSettingsを表す要素の全然違うStructをどう抽象化するか、という具体例について説明される。

あとKeyPathはHashableなのでDictionaryのキーにも使えますよ、とか。

Swiftにおける音の成形

スライドはGitHubにある。

github.com

このセッションは音の基礎から始まって、で、iOSではどうやるの?というところでCore Audioは難しいからAudioKit使おう、という流れ。

音声処理は興味がある。が、あんまり「音楽」の文脈では興味がなくて、どっちかというと「現実世界をセンシングする」という文脈で興味がある。このセッションは音楽寄りの話なのでそういう意味では僕の興味にストライクではなかったが、AudioKitがディレイやリバーブのような基本的な処理だけじゃなくてAKMoogLadderみたいなかなりアプリケーションよりのところまで含んでいるというのは知見だった。

試しにAudioKitのプロジェクトでvoiceでクラス群をフィルタしてみると、SamplerVoiceとかSynthVoiceとか興味深いクラスがあるし、MIDI系の実装も充実している。あとAudioKitのリポジトリはAudioKitというアカウントにあって、

github.com

サンプルとか、音をパーティクルでビジュアライズするプロジェクトもある。

Metalを使用。あとでちゃんとコードを読んでみようと思う。

f:id:shu223:20190325061041p:plain

(iPhoneでも普通に動いた)

PixarのようなグラフィックをSwiftで実現する

レイトレーシングの話。iOS 12でMetalに追加されたレイトレーシングの話かと思いきや、

developer.apple.com

シンプルなレイトレーサーをSwiftで自前実装する、という話だった。めちゃくちゃいい。自分で実装するというのは理解度が全然違う。

コードはGitHubにある。

github.com

"Pete Shirley"という人の書籍を参考に書いたコードらしい。

Much of the code is derived from Pete Shirley's Ray Tracing Minibooks, with a few added extras.

で、このリポジトリ、Swiftのファイルが2つとビルドスクリプトしか入ってない。Xcodeプロジェクトはなく、コマンドからビルドして各フレームの画像をppmで出力し、それらをffmpegに食わせてmp4として吐き出すというもののようだ。

中身を見ると、Metalを使ってないどころか、SceneKitもCore ImageもCore Graphicsも使ってない。Foundationだけ。

(ということをツイートしたら、レイトレーシングという(iOS界隈では)ニッチな話題にもかかわらず結構な反響があった)

次のようなアルゴリズムらしい。

  • Line sphere intersection
  • Path tracing
  • Lamberian scattering
  • Fresnel equations
  • Schlick approximation
  • Perlin noise
  • Rodrigues rotation formula

これはたぶんコードを読むだけでは何やってるかわからないやつだ。。まぁそれぞれのアルゴリズムの日本語名を調べて、何をやってるのか(中身の詳細はブラックボックスでもいいので)理解する、ぐらいのことはやりたい。

SwiftSyntax で便利を実現する基礎

SwiftSyntaxというSwiftの公式ライブラリがあって、それを使って構文解析したり、コードの一部を書き換えたり(修正コードを生成)する方法の紹介。

speakerdeck.com

めっちゃわかりやすいけど、会場ではボーッとしてて(スライドが日本語だったのでそこが気になって回想モードに入ってしまった)、『SwiftSyntaxは公式ライブラリである』というところを聞き逃してしまい、構文解析がどのように行われるかを解説しているのか、Swiftのコンパイラ実装の一部を取り出してツールとして利用するような話をしているのか、みたいに理解の迷子になってしまった。プレゼンを聞くときは冒頭は絶対に聞き逃してはいけない。。

Swift type metadata

SwiftのType metadataを通じてSwiftのランタイムを理解しよう、というセッション。

speakerdeck.com

letmetatype:Int.Type= Int.self

このInt.Typeは「メタタイプ(Metatype)」と呼ばれる型で、クラスや構造体、列挙型、プロトコル等、型を表すための型{型名}.selfでこのメタタイプを型自体から取得できる。

で、このセッションの主役である"type metadata"は、Swiftランタイムにおいて型の情報を表すデータで、Metatypeはtype metadataへのポインタである、とのこと。

これを用いて、Method swizzlingも可能になる。

classAnimal {
    funcbar() { print("bar") }
    funcfoo() { print("foo") }
}

structClassMetadata {
    ...// VTablevarbarRef:FunctionRefvarfooRef:FunctionRef
}

letmetadata= unsafeBitCast(
    Animal.self, to:UnsafeMutablePointer<ClassMetadata>.self
)
letbar= withUnsafeMutablePointer(to:&metadata.pointee.barRef) { $0 }
letfoo= withUnsafeMutablePointer(to:&metadata.pointee.fooRef) { $0 }
bar.pointee = foo.pointee
letanimal= Animal()
animal.bar() // foo

これを利用したOSSがStubKitで、

github.com

Decodableに準拠している任意のクラスや構造体を1行で初期化できるようにしてくれる、というものらしい。

import StubKit

// Codable structstructUser:Codable {
  letid:Intletname:Stringletsex:Sex
}

letstubUser= try Stub.make(User.self)
// User(id: 1234, name: "This is Stub String", sex: .female)

便利そう。

通常の開発ではあまり見ることのない言語の「内部」を読み解き、さらに実用面での使いどころを考え、OSSにまで落とし込む(しかもかなり普遍性がある)という一連の所業は見習いたい。

ポートレートモードを自作しよう / Making Portrait mode yourself

深度情報が付属しない2D画像、しかも現実世界の写真だけじゃなくてたとえばマンガやアニメの画像も背景をぼかしたりしたい、という試み。

speakerdeck.com

深度推定の機械学習モデル使うのかなと思ったが、違った。それだと期待した性能が出ない(機械学習なので、学習させたシーンの背景しか分離できない)ので、"GrabCut"なるアルゴリズムを採用したとのこと。

LTなのでアルゴリズムの詳細説明はなくサッと次のスライドに行ってしまったので、帰ってググってみたところ、2004年の論文で提案されたアルゴリズムのようだった。

try! Swiftの当該セッションの実装コードを見ると、OpenCVにそのものズバリな関数が用意されていて、それを使っているようだった。

cv::grabCut(sourceMat, maskMat, rectangle, bgModel, fgModel, iterationCount, cv::GC_INIT_WITH_RECT);

これはいいことを知った。デュアルカメラやTrueDepthがハイエンドiPhoneに限定されたスペックである以上、iOSが13になろうと14になろうとデプス取得手段がないデバイスで撮影された画像への対処は必要で、こういう手段もある、というのは知れてよかった。

OpenCVの公式サイトに色々とドキュメントがある。

docs.opencv.org

画像処理界隈ではよく知られたアルゴリズムのようで、"grabcut opencv"でググると日本語情報もたくさん出てくる。

つづく

復習したいセッションのリストはまだまだあるので、つづきます。

「iOSエンジニアのためのmacOSアプリ開発入門」という本を書きました #技術書典 #技術書典6

$
0
0

macOS/Cocoaアプリ開発の技術書を書きました。macOSアプリ開発は、

  • 使用言語はSwift
  • IDEはXcode
  • 標準フレームワークの多くがiOSと共通

と、iOSアプリ開発と共通点が多いため、iOSエンジニアにとっては比較的とっつきやすいはずです。

・・・が、「UIKitではなくAppKitだし、なんだかんだと色んな点で違っていてめんどくさそう」という気がして興味はあるけど未だ手付かずという方も多いのではないでしょうか。

そこで本書では、iOSエンジニアの視点から「これ、macOSではどうやるの?」という事項を集めてまとめてみました。各項の解説は「iOSエンジニアに伝われば十分」という観点で非常に簡潔に書いてあるので、本書をパラパラと眺めてみるだけでも「違いといってもこんなもんか。簡単そうだからやってみよう。」という気分になるはずです。

f:id:shu223:20190409214248j:plain:w200:leftf:id:shu223:20190409214305j:plain:w200:leftf:id:shu223:20190409214318j:plain:w200:left

電子版をBOOTHにて販売中

個人出版で、BOOTHにて電子版を販売しています。

booth.pm

macOS Mojave 10.14, Xcode 10.2, Swift 5.0対応、46ページ。今後価格改定する可能性はありますが、今のところなんとたったの800円です。

ページ数少ないけど大丈夫?

重厚長大な技術書もエンジニア心をくすぐられますが、コンテンツがあふれる昨今、「積まずにサラッと読める」というのもひとつの価値だと考えています。

いつかやるmacOS開発に向けて積んでおくのではなく、DLしてすぐに開き、数分パラパラ眺める読み方を推奨します。

この数分で「ふーんこんな感じなのね」と思っていただければ本書のコンセプトとしては成功です。

macOSアプリをつくる予定がない?

macOSアプリはiOSアプリと比べてまだマネタイズしづらいイメージがあると思います。実際どうなのか、僕もApp StoreでmacOSアプリをリリースしたことがないのでよくわかりません。

しかし、iOSエンジニアであれば開発環境として日々macOSで作業していると思います。開発作業の中で「これめんどいなー、サクッと自分用ユーティリティアプリがつくれたらいいな」と思ったことはないでしょうか。

本書はそれぐらいのライトなmacOSアプリ開発を想定しています。

目次

はじめに

第1章 基礎の基礎

  • 1.1 プロジェクト作成
  • 1.2 座標系
  • 1.3 ビューの背景色
  • 1.4 Interface Builder

第2章 基本 UI コンポーネント

  • 2.1 ボタン
  • 2.2 画像表示
  • 2.3 ラベル
  • 2.4 テーブル
  • 2.5 アラート

第3章 アニメーション

  • 3.1 ビューのアニメーション
  • 3.2 アニメーション速度を変更する
  • 3.3 Auto Layoutのアニメーション

第4章 画面遷移

  • 4.1 標準セグエ
  • 4.2 同じウィンドウ内で画面遷移させる
  • 4.3 遷移アニメーションを自作する

第5章 その他iOSと手順が違う点

  • 5.1 カスタムフォントを利用する
  • 5.2 subviewの順序を変える
  • 5.3 マウスクリックイベントをハンドルする
  • 5.4 カスタムセルを作成する
  • 5.5 xibからのビューを作成する
  • 5.6 画面サイズとウィンドウサイズ
  • 5.7 クロスプラットフォーム

第6章 macOS独自の機能

  • 6.1 ファイルを開く
  • 6.2 メニューを追加する
  • 6.3 コンテキストメニューを追加する
  • 6.4 ステータスバー常駐アプリケーションを作成する
  • 6.5 起動中のアプリケーションのリストを取得する
  • 6.6 他のアプリケーションを操作する

第7章 Cocoa Bindings - 7.1 Cocoa Bindingsで配列をテーブルに表示する

製本版

「技術書典6」にて製本版を販売します。印刷部数が少ないくせに特殊用紙を使ってオフセット印刷したので原価がかなりかかっており次回はたぶんもうないスペシャル仕様です。会場に来られる方はぜひ「け13」までお越しください。

techbookfest.org

API Diffsから見るiOS 13の新機能 - Vision #WWDC19

$
0
0

iOSエンジニア諸氏のツイートを見ているとSwiftUIが圧倒的インパクトっぽい今回のWWDCですが、そのへんは識者の方々にお任せして、「その他フレームワーク」で気になった新APIを見ていきたいと思います。

f:id:shu223:20190603103013j:plain

まずはVision。

人間検出

VNDetectHumanRectanglesRequest

人間を矩形で検出。

↓はOpenCV使ったやつですが、こういうのです。

f:id:shu223:20190604093836p:plain

ARKitのpeople segmentationがインパクトありすぎて「矩形で検出」というのは印象薄いですが、「こういうのもあったな」と頭の片隅に置いておくといつか用途があるかもしれません。

文字認識

VNRecognizeTextRequest

文字認識。今まであった文字領域検出じゃなくて、文字認識、いわゆるOCR的なやつです。

今まで無料で使えるやつだとtesseractとSwiftOCRぐらいしか選択肢がなかったのが、ついに標準でサポート・・・!感無量です。(対応言語は後で調べる)

qiita.com

github.com

対応言語はsupportedRecognitionLanguages(for:revision:)というメソッドをたたけば調べられそう。あとでやってみます。

動物検出

VNDetectAnimalRectanglesReques

VNAnimalDetectorのtype propertyとして今のところcatdogが用意されており、つまりイヌネコ認識が可能となります。ペットが写ってる写真とかを判別できるようになったわけですね。

画像の類似度を計算

  • VNGenerateImageFeaturePrintRequest
  • VNFeaturePrintObservation

"Analyzing Image Similarity with Feature Print"というサンプルが公開されており、画像間の類似度が計算できるようになったようです。後でコード読んでみます。

画像分類?

VNClassifyImageRequest

画像分類は前からできたはずだけど、この新クラスは何だろう?

Image Saliency

State of the Unionでも出てきたこのキーワード。"silent"は辞書によると「顕著な」(英英では"most noticeable or important.")の意味。

VNGenerateAttentionBasedSaliencyImageRequest

Generates a heat map that identifies the parts of an image most likely to draw attention.

画像内で、もっとも注意を引く部分を特定するヒートマップを生成・・・?"draw attention"な箇所ってのがよくわかりませんね。試してみます。

VNGenerateObjectnessBasedSaliencyImageRequest

Generates a heat map that identifies the parts of an image most likely to represent objects.

画像内で、もっともオブジェクトを表している部分を特定するヒートマップを生成する。ここでいう「オブジェクト」はこちらで指定できるのでしょうか。あとでもうちょっとAPIを見てみます。

VNSaliencyImageObservation

上2つのrequestの結果として得られるクラス。VNPixelBufferObservationを継承し、グレースケールのヒートマップデータを持つ。

var salientObjects: [VNRectangleObservation]? { get }

というプロパティを持っていて、salient Objectsの矩形を複数保持できるようになっています。

Saliencyのサンプルコードとドキュメント

この"Saliency"関連では、"Highlighting Areas of Interest in an Image Using Saliency"というサンプルコードと、"Cropping Images Using Saliency"というドキュメントがあります。

API Diffsから見るiOS 13の新機能 - CoreML公式配布モデル #WWDC19

$
0
0

iOS 13の新API発掘シリーズその2です。

f:id:shu223:20190603103013j:plain

以前の公式配布CoreMLモデルと言えば、imagenetベースの物体検出がほとんどで、あまり新鮮味のあるモデルは配布されていませんでした。

qiita.com

なので、自作するか、サードパーティ製のを探して使うことがほとんどでした。

qiita.com

note.mu

・・・が、今日見てみると、楽しそうなモデルがたくさん追加されているではありませんか!

というわけで前回のVision編に続き、本記事では(APIではありませんが)CoreMLの公式配布モデルについて見ていきます。

デプス推定

  • FCRN-DepthPrediction
    • Depth Estimation

redict the depth from a single image.

画像からデプスを「推定」します。つまり、単眼カメラでも、デプスデータを持っていない既存写真からも、デプスが取得できるようになる、ということです。ここからAVDepthDataを生成することもできるはずです。

・・・ということはデプスを利用する機能が実質的にデバイスを限定する機能ではなくなるといえるのではないでしょうか。今まではデプスを使う機能を提供しようにもiPhone X系とか7 Plus, 8 Plus系のハイエンドデバイスのユーザーしか使えなかったので、興味やアイデアはあってもなかなか採用しづらかったのではないかと思います。

これでついにデプス利用機能が多少は普及しそうですね。参考書籍を貼っておきます。

shu223.booth.pm

(もちろん今回の発表をふまえてアップデート予定です)

セグメンテーション(領域分割)

  • DeeplabV3
    • Image Segmentation

Segment the pixels of a camera frame or image into a predefined set of classes.

f:id:shu223:20190604103249p:plain

サムネイル画像によると人間のセグメンテーションのように見えますが、解説を読むと"predefined set of classes"とあり、複数のクラスに対応しているようです。

試しに.mlmodelファイルをダウンロードして埋め込まれているdescriptionを読んでみると、

person, dog, cat and so on

とあります。人の他に犬や猫もセグメンテーションできるようです。

関連: iOS 12のPortrait Matteがすごい/ #iOSDC 2018で登壇します - その後のその後

物体検出(YOLO)

  • YOLOv3

    • Object Detection
  • YOLOv3-Tiny

    • (Real-time) Object Detection

Locate and classify 80 different types of objects present in a camera frame or image.

物体を「画像内のどこにあるか」の情報を含め検出してくれるモデル。リアルタイム検出用の"Tiny"版もあります。

f:id:shu223:20190604103336p:plain

質問への回答を生成

  • BERT-SQuAD
    • Question Answering

Generate answers to questions about paragraphs of text.

公式配布モデルでは唯一の自然言語処理用。

指定したパラグラフ内のテキストに関して、質問を与えると回答を生成してくれるようです。

f:id:shu223:20190604103357p:plain

API Diffsから見るiOS 13の新機能 - Core Image #WWDC19

$
0
0

iOS 13の新API発掘シリーズその3です。今回はCore Image。

髪・肌・歯のマスク

iOS 12の"Portrait Matte"は全身セグメンテーション用のマスクだったわけですが、それの「髪・肌・歯」版が取れるようになったようです。

developer.apple.com

static let auxiliarySemanticSegmentationHairMatte: CIImageOption
static let auxiliarySemanticSegmentationSkinMatte: CIImageOption
static let auxiliarySemanticSegmentationTeethMatte: CIImageOption

関連: "Portrait Matte"とは?

shu223.hatenablog.com

デプスブラー

CIContextにデプスブラーフィルタを生成するメソッドが追加。disparityImage(視差画像)、portraitEffectsMatte(全身セグメンテーション用マスク画像)、hairSemanticSegmentation(髪のセグメンテーション画像)を渡せて、出力としてCIFilterオブジェクトが返ってきます。

developer.apple.com

func depthBlurEffectFilter(for image: CIImage, 
            disparityImage: CIImage, 
      portraitEffectsMatte: CIImage?, 
  hairSemanticSegmentation: CIImage?, 
               orientation: CGImagePropertyOrientation, 
                   options: [AnyHashable : Any]? = nil) -> CIFilter?

allowLowPower

また、CIContextOptionに以下の型プロパティが追加されていました。

static let allowLowPower: CIContextOption

ドキュメントには解説がありませんが、ヘッダになにか書いてあるかも知れません。パフォーマンスかなにかを犠牲にして消費電力を抑えるオプションでしょうか?

CIFilterの各フィルタの初期化メソッド

今までは次のように文字列でフィルタ名を指定して初期化しないといけなかったのですが、

letfilter= CIFilter(name:"CISepiaTone")!

iOS 13ではドーンと(たぶん)全フィルタの初期化メソッドが追加されました。

一覧は長いので本記事の末尾に載せますが、たとえば上に示したsepia toneフィルタは次のメソッドで初期化できます。

class func sepiaTone() -> CIFilter & CISepiaTone

CIImageのAVSemanticSegmentationMatteからの初期化メソッド

AVSemanticSegmentationMatteはまだ紹介してませんが、名前からしてPortraitMatteの汎用版(Portrait Matteは人間の全身専用マスクだが、もうちょっと汎用的に領域分割するマスク)で、そこからCIImageを生成するメソッドが追加されています。

init?(semanticSegmentationMatte:AVSemanticSegmentationMatte)
init?(semanticSegmentationMatte:AVSemanticSegmentationMatte, options:[CIImageOption : Any]?)

パパッと既存の(≠オリジナルの)画像処理を適用するにはやっぱりCore Imageが簡単なので、これは必須ですね。

CGImageSourceを渡すイニシャライザも追加されています(今までなかったんだっけ。。?)

init(cgImageSource:CGImageSource, index:Int, options:[CIImageOption : Any]?)

AVSemanticSegmentationMatteオブジェクトにはプロパティからアクセスできる(持っていれば)ようです。

varsemanticSegmentationMatte:AVSemanticSegmentationMatte?

一色のCIImageを生成する?

ドキュメントには解説がなかったのですが、CIImageに以下のような型プロパティが追加されています。一色塗りのCIImageオブジェクトを生成するのでしょうか?

classvar black:CIImageclassvar blue:CIImageclassvar clear:CIImageclassvar cyan:CIImageclassvar gray:CIImageclassvar green:CIImageclassvar magenta:CIImageclassvar red:CIImageclassvar white:CIImageclassvar yellow:CIImage

CIFilterに追加された初期化メソッド一覧

上で解説した、CIFilterを生成するメソッド一覧です。しれっと新たに追加されたフィルタもあるかもしれません。

classfunc accordionFoldTransition() ->CIFilter& CIAccordionFoldTransition
classfunc additionCompositing() ->CIFilter& CICompositeOperation
classfunc affineClamp() ->CIFilter& CIAffineClamp
classfunc affineTile() ->CIFilter& CIAffineTile
classfunc attributedTextImageGenerator() ->CIFilter& CIAttributedTextImageGenerator
classfunc aztecCodeGenerator() ->CIFilter& CIAztecCodeGenerator
classfunc barcodeGenerator() ->CIFilter& CIBarcodeGenerator
classfunc barsSwipeTransition() ->CIFilter& CIBarsSwipeTransition
classfunc bicubicScaleTransform() ->CIFilter& CIBicubicScaleTransform
classfunc blendWithAlphaMask() ->CIFilter& CIBlendWithMask
classfunc blendWithBlueMask() ->CIFilter& CIBlendWithMask
classfunc blendWithMask() ->CIFilter& CIBlendWithMask
classfunc blendWithRedMask() ->CIFilter& CIBlendWithMask
classfunc bloom() ->CIFilter& CIBloom
classfunc bokehBlur() ->CIFilter& CIBokehBlur
classfunc boxBlur() ->CIFilter& CIBoxBlur
classfunc checkerboardGenerator() ->CIFilter& CICheckerboardGenerator
classfunc circularScreen() ->CIFilter& CICircularScreen
classfunc cmykHalftone() ->CIFilter& CICMYKHalftone
classfunc code128BarcodeGenerator() ->CIFilter& CICode128BarcodeGenerator
classfunc colorBlendMode() ->CIFilter& CICompositeOperation
classfunc colorBurnBlendMode() ->CIFilter& CICompositeOperation
classfunc colorClamp() ->CIFilter& CIColorClamp
classfunc colorControls() ->CIFilter& CIColorControls
classfunc colorCrossPolynomial() ->CIFilter& CIColorCrossPolynomial
classfunc colorCube() ->CIFilter& CIColorCube
classfunc colorCubeWithColorSpace() ->CIFilter& CIColorCubeWithColorSpace
classfunc colorCubesMixedWithMask() ->CIFilter& CIColorCubesMixedWithMask
classfunc colorCurves() ->CIFilter& CIColorCurves
classfunc colorDodgeBlendMode() ->CIFilter& CICompositeOperation
classfunc colorInvert() ->CIFilter& CIColorInvert
classfunc colorMap() ->CIFilter& CIColorMap
classfunc colorMatrix() ->CIFilter& CIColorMatrix
classfunc colorMonochrome() ->CIFilter& CIColorMonochrome
classfunc colorPolynomial() ->CIFilter& CIColorPolynomial
classfunc colorPosterize() ->CIFilter& CIColorPosterize
classfunc comicEffect() ->CIFilter& CIComicEffect
classfunc convolution3X3() ->CIFilter& CIConvolution
classfunc convolution5X5() ->CIFilter& CIConvolution
classfunc convolution7X7() ->CIFilter& CIConvolution
classfunc convolution9Horizontal() ->CIFilter& CIConvolution
classfunc convolution9Vertical() ->CIFilter& CIConvolution
classfunc copyMachineTransition() ->CIFilter& CICopyMachineTransition
classfunc coreMLModel() ->CIFilter& CICoreMLModel
classfunc crystallize() ->CIFilter& CICrystallize
classfunc darkenBlendMode() ->CIFilter& CICompositeOperation
classfunc depthOfField() ->CIFilter& CIDepthOfField
classfunc depthToDisparity() ->CIFilter& CIDepthToDisparity
classfunc differenceBlendMode() ->CIFilter& CICompositeOperation
classfunc discBlur() ->CIFilter& CIDiscBlur
classfunc disintegrateWithMaskTransition() ->CIFilter& CIDisintegrateWithMaskTransition
classfunc disparityToDepth() ->CIFilter& CIDisparityToDepth
classfunc dissolveTransition() ->CIFilter& CIDissolveTransition
classfunc dither() ->CIFilter& CIDither
classfunc divideBlendMode() ->CIFilter& CICompositeOperation
classfunc documentEnhancer() ->CIFilter& CIDocumentEnhancer
classfunc dotScreen() ->CIFilter& CIDotScreen
classfunc edgePreserveUpsample() ->CIFilter& CIEdgePreserveUpsample
classfunc edgeWork() ->CIFilter& CIEdgeWork
classfunc edges() ->CIFilter& CIEdges
classfunc eightfoldReflectedTile() ->CIFilter& CIEightfoldReflectedTile
classfunc exclusionBlendMode() ->CIFilter& CICompositeOperation
classfunc exposureAdjust() ->CIFilter& CIExposureAdjust
classfunc falseColor() ->CIFilter& CIFalseColor
classfunc flashTransition() ->CIFilter& CIFlashTransition
classfunc fourfoldReflectedTile() ->CIFilter& CIFourfoldReflectedTile
classfunc fourfoldRotatedTile() ->CIFilter& CIFourfoldRotatedTile
classfunc fourfoldTranslatedTile() ->CIFilter& CIFourfoldTranslatedTile
classfunc gammaAdjust() ->CIFilter& CIGammaAdjust
classfunc gaussianBlur() ->CIFilter& CIGaussianBlur
classfunc gaussianGradient() ->CIFilter& CIGaussianGradient
classfunc glideReflectedTile() ->CIFilter& CIGlideReflectedTile
classfunc gloom() ->CIFilter& CIGloom
classfunc hardLightBlendMode() ->CIFilter& CICompositeOperation
classfunc hatchedScreen() ->CIFilter& CIHatchedScreen
classfunc heightFieldFromMask() ->CIFilter& CIHeightFieldFromMask
classfunc hexagonalPixellate() ->CIFilter& CIHexagonalPixellate
classfunc highlightShadowAdjust() ->CIFilter& CIHighlightShadowAdjust
classfunc hueAdjust() ->CIFilter& CIHueAdjust
classfunc hueBlendMode() ->CIFilter& CICompositeOperation
classfunc hueSaturationValueGradient() ->CIFilter& CIHueSaturationValueGradient
classfunc kaleidoscope() ->CIFilter& CIKaleidoscope
classfunc labDeltaE() ->CIFilter& CILabDeltaE
classfunc lanczosScaleTransform() ->CIFilter& CILanczosScaleTransform
classfunc lenticularHaloGenerator() ->CIFilter& CILenticularHaloGenerator
classfunc lightenBlendMode() ->CIFilter& CICompositeOperation
classfunc lineOverlay() ->CIFilter& CILineOverlay
classfunc lineScreen() ->CIFilter& CILineScreen
classfunc linearBurnBlendMode() ->CIFilter& CICompositeOperation
classfunc linearDodgeBlendMode() ->CIFilter& CICompositeOperation
classfunc linearGradient() ->CIFilter& CILinearGradient
classfunc linearToSRGBToneCurve() ->CIFilter& CILinearToSRGBToneCurve
classfunc luminosityBlendMode() ->CIFilter& CICompositeOperation
classfunc maskToAlpha() ->CIFilter& CIMaskToAlpha
classfunc maskedVariableBlur() ->CIFilter& CIMaskedVariableBlur
classfunc maximumComponent() ->CIFilter& CIMaximumComponent
classfunc maximumCompositing() ->CIFilter& CICompositeOperation
classfunc median() ->CIFilter& CIMedian
classfunc meshGenerator() ->CIFilter& CIMeshGenerator
classfunc minimumComponent() ->CIFilter& CIMinimumComponent
classfunc minimumCompositing() ->CIFilter& CICompositeOperation
classfunc mix() ->CIFilter& CIMix
classfunc modTransition() ->CIFilter& CIModTransition
classfunc morphologyGradient() ->CIFilter& CIMorphologyGradient
classfunc morphologyMaximum() ->CIFilter& CIMorphologyMaximum
classfunc morphologyMinimum() ->CIFilter& CIMorphologyMinimum
classfunc morphologyRectangleMaximum() ->CIFilter& CIMorphologyRectangleMaximum
classfunc morphologyRectangleMinimum() ->CIFilter& CIMorphologyRectangleMinimum
classfunc motionBlur() ->CIFilter& CIMotionBlur
classfunc multiplyBlendMode() ->CIFilter& CICompositeOperation
classfunc multiplyCompositing() ->CIFilter& CICompositeOperation
classfunc noiseReduction() ->CIFilter& CINoiseReduction
classfunc opTile() ->CIFilter& CIOpTile
classfunc overlayBlendMode() ->CIFilter& CICompositeOperation
classfunc pageCurlTransition() ->CIFilter& CIPageCurlTransition
classfunc pageCurlWithShadowTransition() ->CIFilter& CIPageCurlWithShadowTransition
classfunc paletteCentroid() ->CIFilter& CIPaletteCentroid
classfunc palettize() ->CIFilter& CIPalettize
classfunc parallelogramTile() ->CIFilter& CIParallelogramTile
classfunc pdf417BarcodeGenerator() ->CIFilter& CIPDF417BarcodeGenerator
classfunc perspectiveCorrection() ->CIFilter& CIPerspectiveCorrection
classfunc perspectiveTile() ->CIFilter& CIPerspectiveTile
classfunc perspectiveTransform() ->CIFilter& CIPerspectiveTransform
classfunc perspectiveTransformWithExtent() ->CIFilter& CIPerspectiveTransformWithExtent
classfunc photoEffectChrome() ->CIFilter& CIPhotoEffect
classfunc photoEffectFade() ->CIFilter& CIPhotoEffect
classfunc photoEffectInstant() ->CIFilter& CIPhotoEffect
classfunc photoEffectMono() ->CIFilter& CIPhotoEffect
classfunc photoEffectNoir() ->CIFilter& CIPhotoEffect
classfunc photoEffectProcess() ->CIFilter& CIPhotoEffect
classfunc photoEffectTonal() ->CIFilter& CIPhotoEffect
classfunc photoEffectTransfer() ->CIFilter& CIPhotoEffect
classfunc pinLightBlendMode() ->CIFilter& CICompositeOperation
classfunc pixellate() ->CIFilter& CIPixellate
classfunc pointillize() ->CIFilter& CIPointillize
classfunc qrCodeGenerator() ->CIFilter& CIQRCodeGenerator
classfunc radialGradient() ->CIFilter& CIRadialGradient
classfunc randomGenerator() ->CIFilter& CIRandomGenerator
classfunc rippleTransition() ->CIFilter& CIRippleTransition
classfunc sRGBToneCurveToLinear() ->CIFilter& CISRGBToneCurveToLinear
classfunc saliencyMap() ->CIFilter& CISaliencyMap
classfunc saturationBlendMode() ->CIFilter& CICompositeOperation
classfunc screenBlendMode() ->CIFilter& CICompositeOperation
classfunc sepiaTone() ->CIFilter& CISepiaTone
classfunc shadedMaterial() ->CIFilter& CIShadedMaterial
classfunc sharpenLuminance() ->CIFilter& CISharpenLuminance
classfunc sixfoldReflectedTile() ->CIFilter& CISixfoldReflectedTile
classfunc sixfoldRotatedTile() ->CIFilter& CISixfoldRotatedTile
classfunc smoothLinearGradient() ->CIFilter& CISmoothLinearGradient
classfunc softLightBlendMode() ->CIFilter& CICompositeOperation
classfunc sourceAtopCompositing() ->CIFilter& CICompositeOperation
classfunc sourceInCompositing() ->CIFilter& CICompositeOperation
classfunc sourceOutCompositing() ->CIFilter& CICompositeOperation
classfunc sourceOverCompositing() ->CIFilter& CICompositeOperation
classfunc spotColor() ->CIFilter& CISpotColor
classfunc spotLight() ->CIFilter& CISpotLight
classfunc starShineGenerator() ->CIFilter& CIStarShineGenerator
classfunc straighten() ->CIFilter& CIStraighten
classfunc stripesGenerator() ->CIFilter& CIStripesGenerator
classfunc subtractBlendMode() ->CIFilter& CICompositeOperation
classfunc sunbeamsGenerator() ->CIFilter& CISunbeamsGenerator
classfunc supportedRawCameraModels() ->[String]!classfunc swipeTransition() ->CIFilter& CISwipeTransition
classfunc temperatureAndTint() ->CIFilter& CITemperatureAndTint
classfunc textImageGenerator() ->CIFilter& CITextImageGenerator
classfunc thermal() ->CIFilter& CIThermal
classfunc toneCurve() ->CIFilter& CIToneCurve
classfunc triangleKaleidoscope() ->CIFilter& CITriangleKaleidoscope
classfunc triangleTile() ->CIFilter& CITriangleTile
classfunc twelvefoldReflectedTile() ->CIFilter& CITwelvefoldReflectedTile
classfunc unsharpMask() ->CIFilter& CIUnsharpMask
classfunc vibrance() ->CIFilter& CIVibrance
classfunc vignette() ->CIFilter& CIVignette
classfunc vignetteEffect() ->CIFilter& CIVignetteEffect
classfunc whitePointAdjust() ->CIFilter& CIWhitePointAdjust
classfunc xRay() ->CIFilter& CIXRay
classfunc zoomBlur() ->CIFilter& CIZoomBlur

API Diffsから見るiOS 13の新機能 - その他諸々 #WWDC19

$
0
0

Vision編CoreML公式配布モデル編Core Image編と、巨大な新API群の端っこの方から記事を書き始めたわけですが、その後どのフレームワークについて書こうとしても調査内容が膨大になってしまってうまくまとまらず、もう眠くなってしまったのでざっくり箇条書きで書いておいて明日以降にまたじっくり調査することにします。

f:id:shu223:20190603103013j:plain

SoundAnalysis

developer.apple.com

Analyze streamed and file-based audio to classify it as a particular type.

機械学習ベースで音を分類したりするらしい。何の音を分類してくれるのかAPIリファレンスからはわからなかったのだけど、次のドキュメントで、

The SoundAnalysis framework operates on a model that you’ve trained using a Create ML MLSoundClassifier

と書いてあって、Create MLでつくったCore MLモデルを使って音を判別するようだ。

ってことで、レイヤーとしてはVisionの音声処理版(Visionは画像処理版)と解釈しとくとよさそう。

セマンティック・セグメンテーション / AVSemanticSegmentationMatte

前からしてPortrait Matteの汎用版。Portrait Matteは人間の全身専用マスクだが、もうちょっと汎用的に領域分割するマスクが取れるようになると。

関連メソッドは前回記事にも書いた:

CoreML公式配布モデルの「DeeplabV3」がMatte抽出にあたって内部で使われているのか、別の仕組みなのかは気になる。

AVSemanticSegmentationMatte.MatteTypeという構造体があり、今のところ次のような種類があるようだ。

staticlethair:AVSemanticSegmentationMatte.MatteType

A matting image that segments the hair from all people in the visible field of view of an image.

staticletskin:AVSemanticSegmentationMatte.MatteType

A matting image that segments the skin from all people in the visible field of view of an image.

staticletteeth:AVSemanticSegmentationMatte.MatteType

A matting image that segments the teeth from all people in the visible field of view of an image.

このへんの髪・肌・歯のセグメンテーションについては前回記事にも書いた。

AVCapturePhotoOutputに関連APIがいくつか追加されている。

developer.apple.com

varavailableSemanticSegmentationMatteTypes:[AVSemanticSegmentationMatte.MatteType]

An array of semantic segmentation matte types that may be captured and delivered along with the primary photo.

varenabledSemanticSegmentationMatteTypes:[AVSemanticSegmentationMatte.MatteType]

The semantic segmentation matte types that the photo render pipeline delivers.

AVCapturePhotoにも。

funcsemanticSegmentationMatte(for:AVSemanticSegmentationMatte.MatteType) ->AVSemanticSegmentationMatte?

Retrieves the semantic segmentation matte associated with this photo.

AVCaptureMultiCamSession

developer.apple.com

A subclass of AVCaptureSession that supports simultaneous capture from multiple inputs of the same media type.

"AVMultiCamPiP: Capturing from Multiple Cameras"というサンプルがあるので、あとで実行してみる。

Core Haptics

developer.apple.com

Compose and play haptic patterns to customize your iOS app's haptic feedback.

サンプルもある。

このドキュメントも興味深い。"Apple Haptic and Audio Pattern (AHAP)"なるファイルフォーマットがあるらしい。

Audio Effects

そんなに新機能を期待してなかったAudioToolboxのリファレンスを見ていたら、iOS 13+なサンプルが2つもあった。

どちらも"Audio Effects"関連。どのへんがiOS 13なのかまだちゃんと読んでないが、あとで見てみる。

AVSpeechSynthesisVoiceGender

以前からある音声合成機能の、合成音声に男女の区別がついた。

case female
case male
case unspecified

これに伴い、AVSpeechSynthesisVoiceにはgenderプロパティが追加された。

vargender:AVSpeechSynthesisVoiceGender { get }

AVSpeechSynthesizer

なんかちょこちょこと新APIがある。

varmixToTelephonyUplink:BoolvarsynthesizerAudioSession:AVAudioSession
funcwrite(AVSpeechUtterance, toBufferCallback:AVSpeechSynthesizer.BufferCallback)

MKPointOfInterestCategory

MKMapViewに次のようなプロパティが追加されていて、

varpointOfInterestFilter:MKPointOfInterestFilter?

地図上の"Point of Interest"をフィルタできる。めちゃくちゃ多くの種類が定義されているので、ここでは触りだけ。

staticletairport:MKPointOfInterestCategory

The point of interest category for airports.

staticletamusementPark:MKPointOfInterestCategory

The point of interest category for amusement parks.

MKMultiPolygon

MapKitの新クラス。WWDCキーノートを聞きながら

こんな妄想をしてたのもあって、「ポリゴン」という字面からSceneKitと連携するなにかかと一瞬期待したが、よく考えたらMKPolygonというクラスは昔からあって、3Dメッシュ表現手法としてのポリゴンではなくて普通に本来の意味での「多角形」だった。(で、どういうものなのかはまだわかってない)

Create ML

いずれ別記事で書きたいので省略するが、つくれるモデルの種類が増えている。

Create MLって何だっけ?という方はこちらをどうぞ:

shu223.hatenablog.com

VisionKit

Visionとはまた別の新フレームワーク。ドキュメントスキャナ的なものをつくる機能を提供してくれている?

developer.apple.com

VisionKit is a small framework that lets your app use the system's document scanner. Present the document camera as a view controller, which covers the entire screen like the camera function in Notes. Implement the VNDocumentCameraViewControllerDelegate in your own view controller to receive callbacks from the document camera, such as completed scans.

watchOSのIndependent App

これめっちゃいいじゃないですか。今まで2つのApp Extensionで構成されてたのがどうなるのか気になる。プロジェクト生成してみる。

On-device speech recognition

オンデバイスで音声認識。SFSpeechRecognitionRequestに、以下のプロパティが追加されている。

varrequiresOnDeviceRecognition:Bool { getset }

その他もちろん気になるフレームワーク群

(SwiftUIとかCombineとかはもちろんキャッチアップするとして)

  • ARKit 3
  • RealityKit
  • Reality
  • Core ML 3
  • Metal
  • MetalKit
  • Metal Performance Shaders
  • Natural Language

etc...

[2019年度版]ドラッグ&ドロップで機械学習のモデルがつくれる「Create ML」の使い方(macOS 10.15 Catalina) #WWDC19

$
0
0

ドラッグ&ドロップで超簡単にオリジナルの機械学習モデルがつくれてしまうCreate MLが大幅パワーアップしました。

新機能が増えたのと、使い方が若干変わった(より簡単になった)部分があるので、最新版として本記事をお送りします。

なお、NDAに配慮してスクリーンショットはAppleの公開資料および現行バージョンのもので代用することにします。

developer.apple.com

developer.apple.com

Create MLの起動方法

これまではCreate MLはまだ独立したアプリとして提供されておらず

import CreateMLUI

letbuilder= MLImageClassifierBuilder()
builder.showInLiveView()

みたいなコードをPlaygroundから実行してアプリケーションのUIにアクセスしていました。

しかしmacOS 10.15 Catalina / Xcode 11で提供される最新バージョンでは、独立したアプリ(Create ML.app)として提供されるようになりました。

Xcode 11のメニューから、

[Xcode] > [Open Developer Tool] > [Create ML]

を選択することで起動します。

使用方法:画像分類器(Image Classifier)

プロジェクトの作成

[File] > [New Project] を選択するとテンプレート選択画面が立ち上がるので、"Image Classifier"を選択します。

f:id:shu223:20190608104742j:plain
テンプレート選択画面。これはWWDCセッションスライド内にあったスクショだが、実際に試すとテンプレートはImage ClassifierとSound Classifierの2つしかなかった(2019.6.7現在)

データセットを用意する

どういうデータを用意するかですが、チュートリアルによると、

  • ラベルごとに最低でも10枚の画像
  • ラベルごとに枚数のバランスをとること(チーターは10枚、ゾウは1000枚、みたいなことをしない)

Use at least 10 images per label for the training set, but more is always better. Also, balance the number of images for each label. For example, don’t use 10 images for Cheetah and 1000 images for Elephant.

  • JPEGやPNG等、画像フォーマットはなんでもいい(UTIがpublic.imageに適合していれば)
  • サイズは揃ってなくてもOK
  • サイズもなんでもいいが、最低でも299x299ピクセルはあった方が良い

The images can be in any format whose uniform type identifer conforms to public.image. This includes common formats like JPEG and PNG. The images don’t have to be the same size as each other, nor do they have to be any particular size, although it’s best to use images that are at least 299x299 pixels.

あとは実際に推論を行うのと同じ状況で学習データも収集した方がいいとか、いろんな角度、ライティングの状況のデータがあった方がいい、ということが書かれています。

If possible, train with images collected in a way that’s similar to how images will be collected for prediction.

Provide images with variety. For example, use images that show animals from many different angles and in different lighting conditions. A classifier trained on nearly identical images for a given label tends to have poorer performance than one trained on a more diverse image set.

ラベルをフォルダ名にし、その配下にトレーニングデータ、テストデータを配置します。

f:id:shu223:20180606071547p:plain

学習&モデルの評価

データフォルダをドラッグ&ドロップします。

f:id:shu223:20190608110725p:plain

テスト(モデルの評価)もドラッグ&ドロップ。

f:id:shu223:20190608110811p:plain

オプショナルで、最大イテレーション回数を指定したり、トレーニングデータにノイズやブラーを付加したり、回転を加えたりといったパラメータを指定することもできます。

f:id:shu223:20190608110855p:plain

Playボタンをクリックすると、学習が開始されます。

f:id:shu223:20190608111115p:plain

学習が完了すると、スコアが表示されます。

f:id:shu223:20190608111212p:plain

f:id:shu223:20190608111423p:plain

モデルを保存する

学習したモデルを .mlmodelファイルとして保存します。

f:id:shu223:20190608111515p:plain

アプリに組み込む

作成した .mlmodelファイルをiOSアプリに組み込んで使用します。

実装方法はこちらの記事を参考にしてください。

qiita.com

また画像分類の .mlmodelファイルをドラッグ&ドロップで試せるアプリをGitHubで公開しているので、こちらもぜひ活用してください。

github.com

使用方法:音声分類器(Sound Classifier)

(続く)

関連(SoundAnalysisについてちょっと書いてます):

qiita.com


「エンジニアと人生」というYouTubeチャンネルを始めました

$
0
0

「エンジニアと人生」というYouTubeチャンネルを始めました。

www.youtube.com

技術の小難しい話はおいておいて、「生き様」に焦点をあてていろんなエンジニアにお話を伺う、というコンセプトの雑談チャンネルです

ソフトウェアエンジニアという職業は今や売り手市場で、パソコンとネットがあればどこでも仕事ができ、国や言語を超えて通用し、ブログやオープンソースで発信することでプレゼンスも向上しやすく、「生き方の選択肢が多い」職業のひとつです。エンジニアにもそうでないみなさまにも、人生の可能性を感じてワクワクしていただけるような内容にしたいと思います。

  • Vol. 1

www.youtube.com

  • Vol. 2

www.youtube.com

  • Vol. 3

www.youtube.com

チャンネル登録していただけると嬉しいです。

ちなみに今のところはいずれも音声コンテンツです。 Voicyという音声プラットフォームで配信している内容を再編集して動画を作成しています。

voicy.jp

以下関連ツイート:

  • このチャンネルを始めた動機

  • 初動画公開

  • 初チャンネル登録

  • 初コメント

  • 編集作業

フリーランスのお仕事まとめ2019

$
0
0

2020年に入って既に10分の1ほど過ぎてしまいましたが、2019年にやったお仕事のまとめです。

機械学習×iOS

  • とある有名アプリへの機械学習モデル組み込み実装
    • 実稼働中
    • 実績公開OKか未確認なので控えておく
  • 「まごチャンネル」の子供写真検出

  • とある広告案件向けのプロトタイプ
    • 個人的には関われてめちゃくちゃ嬉しいし内容もおもしろいのだけどまだまだ公開できない

ARKit, Metal, デプス, カメラ, 画像処理関連

  • とある海外のアプリの動画向けエフェクト
    • 渡航費や滞在費は先方持ちで1週間海外に滞在
    • MetalやARKit 3を用いた動画エフェクトの実装
  • とあるカメラアプリへのデプス関連機能実装
    • watchOSも使用
  • アプリで3Dスキャン -> 3Dプリントデータ作成(プロトタイプ)
  • とある雑誌×AR案件(プロト)
    • ARKitも他のARライブラリも使わないAR
  • とある海外案件でのデプス機能実装(その機能だけを実装したサンプルが成果物)

BLE関連

  • とあるIoTプロダクトを利用した実証実験用プロト開発
    • とある業界向けソリューションで、別の業界の現場に行けるのは楽しかった
  • とあるスマートロック
    • BLEのパフォーマンス改善・・・起動〜利用開始までの所要時間が数分の1に短縮された(結局要因はBLEだけではなかったが)

展示系

  • ニューヨークのポスター美術館「Poster House」のサイネージ向けmacOSアプリ(BASSDRUM)

(9月には義母が手伝いに来てくれて、念願かなってNYに実際に見に行くことができた)

  • 「不思議な宿」のiPadアプリ(ブルーパドル)

www.youtube.com

技術書の執筆

2019年のひとつのテーマは「技術発信のマネタイズ」だったが少しずつ結実してきた。

新刊

  • Keras & Core ML Tools
    • 今一番力をいれて更新しています
    • 「詳解Core ML Tools - coremltools, Keras, TensorFlow」に改題予定

既刊の更新

その他発信活動

  • 「三重県立桑名工業高校」での講演

note.com

  • noteの有料マガジン
    • 有料バリアにより心理的安全に守られつつ日々の勉強メモを気軽に投稿するための場
    • 合計143本書いた(←マガジン外の記事も含む)

  • 単価公開note
    • めちゃくちゃ売れた...技術書は3ヶ月フルコミットで書いて印税の合計50万いかないぐらいだったが、これは書くのに1時間もかかってなくてたぶん100万ぐらい売れた
    • しかしこれは自分の文章力とかじゃなく10年間ひたすらものをつくり行動し発信してきた結果なので再現性はまったくないと思っている

note.com

「Core ML Tools実践入門」という本を書きました #技術書典

$
0
0

iOS×機械学習といえばCore ML。既製のCore MLモデルを扱うのは非常に簡単なのですが、

  • TensorFlowやKeras等の機械学習ツールで作成した独自モデルをCore MLモデルに変換したい
  • モデルサイズを小さくしたい
  • 複数サイズの入力をサポートしたい
  • オンデバイスで更新できるようにしたい

等々、つまり 自分でCore MLモデルをつくりたい・カスタマイズしたい場合にはCore ML Tools(coremltools)を使いこなすことが不可欠です。

が、こんなに重要なツールなのに意外にも情報が少なく、日本語情報どころか英語の公式ドキュメントすら全然網羅的ではありません

というわけで自分で勉強しつつ書いた本がこちらです1

f:id:shu223:20200309090337j:plain

Core ML Toolsの利用方法を実践形式でさまざまなモデルをつくりながら学んでいきます。最初はわずか2行のコードで変換することからはじめてCore ML Toolsに入門しつつ、もっと高度な変換方法や、モデルのサイズを縮小する方法、パイプラインを構築する歩法、オンデバイスで学習できるようにする方法等も解説していきます。

また巻末には「逆引きリファレンス」も収録しています。開発の現場で「どう書くんだっけ?」となったときに大いに役立つことでしょう。

A5版、150ページ。サンプルコードはGitHubよりダウンロード可能です。普段は電子版だけで2300円のところ、3月いっぱい開催される「技術書典 応援祭」期間中のみ紙+電子セット2000円で販売しています。40部しかないのでお早めに!

techbookfest.org

目次

第1章 準備

  • 1.1 Core ML Toolsとは
  • 1.2 Kerasとは
    • 1.2.1 KerasとCore ML Tools
    • 1.2.2 tf.kerasとスタンドアロン版Keras
  • 1.3 Keras/TensorFlow/Core ML Toolsの環境構築

第2章 Core ML Toolsはじめの一歩

  • 2.1 2行のコードで学習済みモデルをロードする
  • 2.2 2行のコードでCore MLモデルに変換する
  • 2.3 変換したモデルを.mlmodelファイルとして保存

第3章 Core MLモデル作成の基礎

  • 3.1 HDF5ファイルを読み込む
  • 3.2 Core MLモデルに変換する
  • 3.3 Core MLモデルの入力の型を変更する
  • Core MLモデルから自動生成されるSwiftコード
  • Visionはどのように画像分類モデルを判定するか?

第5章 オンデバイス学習 - UpdatableなCore MLモデルの作成

  • 5.1 モデルのパーソナライゼーション
  • 5.2 ベースとなるモデルの作成
  • 5.3 Updatableなモデルに変換する
  • 5.4 損失関数をセットする
  • 5.5 最適化アルゴリズムをセットする
  • 5.6 エポック数をセットする
  • 5.7 モデルを保存する

第6章 オンデバイス学習 - iOSで学習

  • 6.1 MLUpdateTask
    • 6.1.1 mlmodelc
    • 6.1.2 MLBatchProvider, MLArrayBatchProvider
    • 6.1.3 MLTask
    • 6.1.4 オンデバイスモデル更新タスクの全体感
  • 6.2 学習データの準備
  • 6.3 学習タスクの実行
  • 6.4 オンデバイスで学習したモデルを保存する / MLUpdateContext, MLWritable
  • 6.5 推論処理の実行

f:id:shu223:20200309090819g:plain

第7章 TensorFlowモデルの変換 - 基礎編

  • 7.1 tfcoreml
  • 7.2 tfcoremlを用いたCore MLモデルへの変換(最小実装)
    • 7.2.1 学習済みモデル(.pbファイル)を読み込む
    • 7.2.2 出力テンソルの名前を取得する
    • 7.2.3 tfcoremlを用いて変換する
  • 7.3 より扱いやすいCoreMLモデルに変換する
    • 7.3.1 クラスラベルを指定する
    • 7.3.2 入力の型を画像に変更する
  • 7.4 iOSで推論を実行
  • 7.5 入力画像の前処理を指定する

第8章 TensorFlowモデルの変換 - 画風変換モデル

  • 8.1 学習済みモデルからグラフ定義を読み込む
  • 8.2 変換に必要なグラフの情報を取得する
    • 8.2.1 入力テンソルの名前を取得する
    • 8.2.2 出力テンソルの名前を取得する
  • 8.3 tfcoremlを用いて変換する
    • 8.3.1 入力テンソルのshapeを指定する
  • 8.4 Core MLモデルの出力の型を変更する
  • 8.5 iOSで画風変換を実行
    • 8.5.1 複数の入力を持つCore MLモデルをVisionで使う
    • 8.5.2 出力画像を取得する

f:id:shu223:20200309090946g:plain

第9章 Flexible Shape - 超解像モデル

  • 9.1 Flexible Shapeとは/使いどころ
  • 9.2 超解像モデルをCore MLモデルに変換する
  • 9.3 Flexible Shapeを適用する
  • 9.4 iOS側での推論処理の実行

第9章 Core MLモデルのサイズを小さくする

  • 9.1 本章で利用する感情認識モデルについて
  • 9.2 重みを16ビット化する
    • 9.2.1 16ビット化が推論結果の精度に与える影響
    • 9.2.2 Core MLモデルを16ビット化する手順
  • 9.3 クォンタイズ
  • 9.4 iOSでの推論結果の比較
  • 9.5 さらなるモデルサイズ削減
    • 9.5.1 ルックアップテーブルを利用した量子化
    • 9.5.2 モデルの一部を共通化

第10章 パイプラインモデルとリンクモデル(Linked Model)

  • 10.1 パイプラインの構築
    • 10.1.1 coremltools.models.pipelineモジュール
    • 10.1.2 PipelineClassifierオブジェクトの生成
    • 10.1.3 パイプラインにモデルを追加
    • 10.1.4 MLModel オブジェクト生成
  • 10.2 リンクモデル(LinkedModel)
    • 10.2.1 リンクモデルとは/リンクモデルを使用するメリット
    • 10.2.2 パイプラインとリンクモデル
    • 10.2.3 リンクモデルの作成方法
  • CreateMLのモデルはなぜ小さいのか
    • CreateMLとパイプライン
    • Vision FeaturePrint

第11章 モデルの可視化

  • 11.1 Netron
  • 11.2 coremltoolsのvisualize_spec
  • 11.3 TensorBoard
    • 11.3.1 TensorFlowモデルのグラフを可視化
    • 11.3.2 Kerasでの学習状況を可視化
  • 11.4 Kerasのplot_model

付録A coremltools逆引きリファレンス

  • A.1 MLModelオブジェクトを生成する
    • A.1.2 .mlmodelファイルから生成する
    • A.1.1 Specから生成する
  • A.2 モデルのSpecを取得する
    • A.2.1 .mlmodelファイルから取得する
    • A.2.2 MLModelオブジェクトから取得する
  • A.3 .mlmodelファイルの保存・読み込み
    • A.3.1 .mlmodelファイルを読み込む
    • A.3.2 .mlmodelファイルとして保存する
  • A.4 NeuralNetworkBuilderを生成する
  • A.5 モデルの中身を調べる
    • A.5.1 モデルを可視化(ビジュアライズ)する
    • A.5.2 モデルのバージョン(Specification Version)を確認する
    • A.5.3 Specをログに出力する
    • A.5.4 ネットワークの情報をログに出力する
    • A.5.5 NeuralNetworkBuilderでモデルの入力・出力形式を確認する
    • A.5.6 モデルのレイヤー一覧を出力する
    • A.5.7 モデルの中間層の入出力形式を調べる
  • A.6 Core MLモデルにクラスラベルを与える
    • A.6.1 ラベル文字列の配列を渡す
    • A.6.2 クラスラベルファイルのパスを渡す
  • A.7 モデルの入力・出力をカスタマイズする
    • A.7.1 入力・出力名を指定する
    • A.7.2 変換時に入力の型を画像型にする
    • A.7.3 変換済みモデルの入力・出力の型を画像型にする
    • A.7.4 入力テンソルのshapeを指定する
    • A.7.5 入力画像の前処理を指定する
  • A.8 モデルサイズを圧縮する
    • A.8.1 重みを16ビット(半精度)化する
    • A.8.2 重みをクォンタイズする
  • A.9 オンデバイス学習関連
    • A.9.1 モデルがUpdatableかどうかを調べる
    • A.9.2 Updatableなレイヤー一覧を出力
    • A.9.3 Updatableなモデルに変換する
    • A.9.4 学習で使用する損失関数をセットする
    • A.9.5 損失関数のサマリを確認する
    • A.9.6 学習で使用する最適化アルゴリズム(オプティマイザ)をセットする
    • A.9.7 最適化アルゴリズムを確認する
    • A.9.8 エポック数をセットする
  • A.10 FlexibleShape関連
    • A.10.1 FlexibleShapeの適用可否を確認する
    • A.10.2 入力・出力の画像サイズを範囲で指定する
    • A.10.3 入力・出力に複数の画像サイズを指定する
  • A.11 misc.
    • 利用中のcoremltoolsのバージョンを確認する

付録B Kerasでカスタムモデル作成

  • B.1 モデルのネットワークを定義する
    • B.1.1 Sequential モデル(とKeras functinal API)
    • B.1.2 Conv2D
    • B.1.3 MaxPooling2D
    • B.1.4 Dropout
    • B.1.5 Flatten
    • B.1.6 Dense
    • B.1.7 モデルのサマリを確認
  • B.2 モデルのコンパイル
    • B.2.1 損失関数
    • B.2.2 最適化アルゴリズム
    • B.2.3 評価関数
  • B.3 モデルの学習
  • B.4 評価
  • B.5 モデルの保存

  1. 日本語でのCore ML Tools専門書は初ですし、今後も出てこないと思います。

Core ML Tools実践入門に「mlmodelファイルフォーマット」の章を加筆しました #技術書典

$
0
0

拙著「Core ML Tools実践入門」に加筆した新版を公開しました。

shu223.hatenablog.com

BOOTH、技術書典 応援祭コンカで電子版をご購入の方は新版を無料でダウンロードしていただけます。

mlmodelファイルフォーマットについて知ると何が嬉しいのか?

知ると嬉しいというより、知らないと損している、といっても過言ではないと思っています。

iOS開発にたとえるのであれば、APIリファレンスの読み方がわからず開発をしているようなものかと。たとえばこの章に書いてあることを理解していないと、たとえば画像分類(Image Classification)を行う.mlmodelモデルでクラスラベルの一覧を出力したいと思ってもどのように出力するのか、そもそも可能なのかといったことがわからないわけです。

クラスラベル一覧はほんの一例で、mlmodelのファイルフォーマットについて理解しておくと、mlmodelの持つあらゆる情報にアクセスできるようになります。coremltoolsを用いてモデルを自作する際、デバッグや最適化に大いに役立つことでしょう。

ドラッグ&ドロップでCore MLモデルを試せる「MLModelCamera」で物体検出モデルをサポートしました

$
0
0

Create MLによって画像分類モデル(Image Classifier)をドラッグ&ドロップでつくれるようになったので、

shu223.hatenablog.com

そのモデル(.mlmodel)をドラッグ&ドロップするだけでリアルタイム画像認識アプリとして試せるOSSをつくりました(2年前に)。

github.com

で、最近1、Create MLが物体検出2モデル(Object Detector)の学習もサポートしたので、

f:id:shu223:20200411151704p:plain

拙作MLModelCameraでも物体検出モデルをサポートしました。

Create MLで学習させた物体検出モデルやAppleが配布しているYOLOv3、coremltools公式リポジトリに変換サンプルのあるSSDといった物体検出モデルをmodelsフォルダ配下に置いてビルドするだけで試せます。

f:id:shu223:20200411151837p:plain:w300

バウンディングボックスの可視化の実装はサイズの換算とか地味に面倒だし既存実装を探すのも面倒、ということでmlmodelを自作する際には非常に便利かと思います。(自分でよく使っています。)


  1. WWDC 2019で発表

  2. Appleのモデル配布ページの日本語では「オブジェクト検出」と訳してたが、ディープラーニングの分野ではこっちの方が一般的だと思われる。

月額500円のオンラインサロンを始めました

$
0
0

今月の中旬頃、オンラインサロンを始めました。

f:id:shu223:20200525110314p:plain

エンジニアと人生コミュニティ - CAMPFIRE (キャンプファイヤー)

5/13に募集開始し、翌日には100名の募集枠が埋まりました。今は定員いっぱいで新規で入っていただくことはできない状態ですが、自分にとって非常に新鮮な試みなので、初心を忘れないうちにそのコンセプトやねらいについて書いておこうと思います。

オンラインサロン=胡散臭い?

という認識を持っている方も結構多いのではないでしょうか。

  • 基本的にサブスク課金
  • 原価のかかるものを売るわけでもない
  • サロン主の拘束時間が明確に決まっているわけでもない

といったところから「労力をかけずにチャリンチャリンなビジネスモデル」を期待してオンラインサロンを始めてしまうインフルエンサーも多い1ため、こういうイメージが蔓延している2のかもしれません。

では弊サロンはどうかというと、掲げているサロンの「売り」が、

フリーランスiOSエンジニア堤修一と語り合うサロンです。Zoomミーティングでキャリア相談、フリーランス関連相談、技術的な相談etc.ができます。

と、基本的に「堤に相談できます」だけなので、あまりスケールしません。相談者の数に比例してかけるべき時間も増えるので、チャリンチャリンビジネスどころか本質的には時給モデルと変わりません。3

始めた動機

ではなぜ始めたのか?何が狙いなのか?

一番目の理由は、「そもそも僕が相談されたい」からです。

この動画でも言ってるように、そもそも僕は「自分の考えをもっと話したい」「でも誰からも聞かれてもないのにペラペラ語り始めるのは恥ずかしい」という(めんどくさい)ジレンマをかかえています。

youtu.be

なので、自分のポッドキャスト/Voicyでゲストが100個も質問を考えてきてくれたときは嬉々として回答したりもしました。

voicy.jp

そういうのもあって、昔々に「タイムチケット」というサービスで30分500円で相談にのっていたことがあり、 僕自身も楽しかったし、わりと好評だったのですが、

www.timeticket.jp

しかし仕事をふくむ自分のすべての活動は時間を原資とするため、さすがに500円では長くは続けられませんでした。(時間を仕事以外の何かに投入することは自分の時給を自分で払うことに等しい)

note.com

そんなわけで、

  • 「相談を受ける」という自分自身も楽しいことをやって、
  • しかもタイムチケット時代よりは収益になる!

というのが本サロンをやる一番の動機です。

始めたきっかけ

話が前後しますが、「相談を受けるだけ」というコンセプトを思いつく以前、KBOY氏のFlutter無料講座 + オンラインサロンサポートのモデルに深く感銘を受け、自分でも入ってみたりしつつも、自分がオンラインサロンをやるイメージはまったくありませんでした。

  • Flutterのように需要のある技術を教えられるわけではない
  • 自分の得意領域であれ、そもそも初学者向けに噛み砕いて技術を教えることには興味がない4
  • コミュニティやSNSコミュニケーションも苦手な自分が「価値のあるコミュニティ構築・運営」なんてできるわけがない

そんなこんなで、1000円や3000円を自分に払ってもらうモデルはまったく見えないなと。5

しかしふと閃いたのが、

「100円だったらどうだろう?」

というアイデアです。

  • タイムチケットで30分500円でやっていたことなので、×100人で1万円ももらえるなら御の字
  • コロナ禍でオンラインミーティングが世の中的に当たり前になっている
  • オンラインミーティングはアーカイブをメンバー限定コンテンツとして後からも見れるようにすることで、リアルタイム参加できなかった人からも不満が出にくい(KBOY氏のサロンに参加しての気付き)
  • しかもアーカイブはコンテンツの蓄積にもなる
  • 可処分時間の不足をずっと感じている中で、子供が寝て奥さんとゆっくり話した後の22時ぐらいからの時間をイマイチ有効活用できていない
  • 技術顧問業は独占的・クローズドに相談にのる⇔サロンでの相談はパブリック/顧問業の相談は即レス⇔サロンでのレスポンスは隔週、といった点で、相談業としてのコンフリクトはしないはず
  • etc...

いろんなピースがカチッとハマった感じがしたのです。あれ、これいいんじゃない?と。

思いついてすぐにTwitterアンケートを取りはじめてみたのが5/12、

(「入らない」が圧倒的1位なのはご愛嬌

当日のうちに500円 or moreの合計が120名を超えたので、需要は確認できたのでやるしかない

→ 鉄は熱いうちに打て、というわけでアンケート翌日の午前中にCAMPFIREコミュニティでサロンをつくって申請

→ 即日審査通過して募集開始

という経緯でほとんど一夜にして一気に事が進んだのでした。

なぜ500円なのか

「なぜ500円なのですか?安すぎませんか?」と聞かれることもあるのですが、 上述したようにそもそも自分が1000円とかで人を集められるイメージがなく、

「100円ならいけるのでは?」

からスタートして、アンケートの結果「500円でもいけそう」となった、という経緯があります。

自分の開発時給がいくらであれ、「現時点での自分のサロンの価格」としては妥当かなと。

(追記)その他のモチベーション

「コンバージョン先」が欲しい

YouTubeチャンネルを持っていて、今のところ購読者数は約700、各動画の再生数は300〜1kぐらいなのですが、 基本的にエンジニア向け、しかもわりとシニア向け(初学者に刺さる内容はほとんどない)であることから、 超人気チャンネルになって再生数がものすごく伸びて広告収入で稼げる、みたいなことはないと思うわけです。

それはそれで、何らかの自分の別のプロダクトにコンバージョンさせればいいわけですが、

  • フリーランス案件をいただいても時間がないし、
  • 本はニッチすぎるので宣伝してもなぁという気がするし

...というわけでコンバージョン先が存在しない、という状態でした。

「エンジニアと人生チャンネル」を見て、僕の考え方や経験に興味を持ってくれた人が「エンジニアと人生サロン」に入ってくれる、というのはなかなか良いコンバージョンなのでは、と。

弊YouTubeチャンネルは趣味/ライフワークとしての一面もありましたが、これでビジネスとしての役割も得たので、時間を投入しやすくなります。

第1回Zoomミーティング

すぐに定員がいっぱいになったので、早速その週末に第1回のZoomミーティングを行いました。以下の相談に回答しました。

  • 相談1

転職である程度ネームバリューがある会社(某M社)に入る際に、iOSだとこれくらいのスキルがあったら良い、こんなアプリが作れるくらいならいい!というような目安やスキルセットが知りたいと思っております。 今は、swiftに加えてfirebaseをメインに開発、勉強進めています。今年からエンジニアとして活動を始めたのでフォーカスする分野なども探っている段階です 転職に関してアドバイス宜しくお願い致します。

  • 相談2

今、カメラと自作AIを使ったアプリのプロトタイプを作ろうとしているのですが、もともと僕pythonのスクリプトでしかプログラムを組んだことがなく、swift、iOS SDK、Xcodeの使い方もよくわかっていないのが現実です。 AIの動作確認だけできればいいため、そこまで難易度高い本はいらんとは思っていたのですが、Xcodeがしょっちゅう更新されるため、どの本読めばいいかわかっていません。 もし、日本語でアプリ開発についておすすめの本ありましたら、おしえていただけると助かります。

  • 相談3

今、linkedin経由でgithubに上げたスクリプトをパーソナライズしてほしいで言われているので、フリーで仕事を受ける場合のtodoとnot todoついて伺いたいです。 フリーでやっていらっしゃる方も結構いらっしゃるようなので、他の方の意見も併せて伺えれば、嬉しいです。

  • 相談4

現在バックエンドエンドエンジニアをしていて、pythonでMLを学習しようと思っています。 クライアント側と少し考え方は異なるかもしれませんが、堤さんがMLの基礎学習に用いた教材やドキュメント等があれば教えていただきたいです。

  • 相談5

最初に海外で働いたときの始まり方と戻ってきてからの海外案件の仕事のとり方についてお聞きしたいです!

  • 相談6

フリーランスに興味がある会社員エンジニアがフリーランスになる良いタイミングについて、皆さんに聞いてみたいです

毎回のZoomミーティングは録画され、相談別に分けられてアーカイブされます。メンバーになるとアーカイブにもアクセスできます。

今後の改善点

本サロンの良くもあり悪くもあるかもしれない特徴が、

  • MetalやCore MLといった技術の話をしたい人たち(→技術面に興味)
  • iOSエンジニアをこれから目指す人たち(→遅咲きエンジニア面に興味?)
  • iOSとは違う分野のエンジニアの人たち(→働き方や考え方に共感)
  • 海外で働いている/働きたい人たち
  • フリーランスとしての働き方に興味がある人たち

と、技術レベルも興味のある点もバラバラ、というあたりです。上の相談リストを眺めてもその傾向はわかっていただけるかと思います。

僕としてはミーティングは途中入退室自由だし、オンラインなので作業しながら聞いててもいいわけだし、アーカイブもされるので、興味のないトピックがあれば聞き流すなり別の作業をするなりしてくれればいいかなーと軽く考えていたのですが、 匿名アンケートをとってみたところ思った以上にこのあたりの不満も散見されたため、次のように改善することにしました。

「専門的すぎる技術の話」問題へのソリューションとして、次回は次のようにしてみます:

  • 「技術の話」とその他の「一般的な話」とをそれぞれ固める(相談1〜3は一般的な話、4〜6は技術の話、みたいに)
  • 技術の話は長くなりそうであれば(何分までとかより話の深さで判断したい)いったん止めて一通りの議題がおわってから続きをやる

あと、僕に相談したいことが具体的にあって入ってきてくれた方は、相談してしまうともうサロンに入り続ける意義がなくなってしまうかもしれません。 また最初は僕の意見を新鮮に感じてくれている人も、だんだんワンパターンに思えてくるかもしれません。(根っこが同じ問題は答えも同じになってしまう)

そんなわけで、本サロンのLTV(Life Time Value)は結構低い気がしてます。まだ1ヶ月目なのでわかりませんが。

とくに後者の問題は「僕自身が同じ回答ばかりする自分に耐えられなくなる」という状況が容易に想像できるため、ゲストを呼んだり、調べつつメモを書いてそれをブログ記事にする実演だったり、案件依頼とそのコミュニケーションについてパネルディスカッションしたり6といったこともやりたいなぁと。

まとめ

オンラインサロンを開設したねらいについて書きました。 もし興味を持ってくれた方がいたら、 以下のページで「お気に入り」に登録しておいていただくと、退会者が出て枠が空いたたときに通知がくると思います。(今のところ2人の方が退会されています)

community.camp-fire.jp

引き続き「エンジニアと人生サロン」(仮)をお願いいたします。


  1. 要出典

  2. 要出典

  3. 実際のところ弊サロンにはそれぞれ自身のチャンネルで有名だったり凄腕フリーランスだったりする人もいて、そういった方々がSlackで質問に回答してくれたりとか、わりとニッチな技術者同士の分科会ができたりとか、頻繁にもくもく会が開催されてたりとかのコミュニティ的なところも良かったりするのですが、それらは「たまたま」の産物であって、僕があらかじめサロンの設計として組み込んだものではないので、オフィシャルには「うちのサロンはこういうところがいいよ」とは掲げていません。

  4. 自分の勉強をアウトプットドリブンで進めるのはよくやります。本とかはその産物。

  5. (2020.9.10追記)2回目の募集からは1000円になりました。今後も価格は変わる可能性があります。

  6. 100名のうち実に18名が現役フリーランス

API Diffsから見るiOS 14の新機能 - 新フレームワーク編 #WWDC20 #iOS14

$
0
0

本日からはじまったWWDC 2020、まだ基調講演しか見てないのですが(SOTUも後で見ます)、ドキュメントは公開されたので、明日から始まるセッションでどのあたりをチェックするか当たりをつけるべく、例年通りAPIの差分を見て気になった新APIをピックアップしていきます。

f:id:shu223:20200623092201p:plain

まずは新フレームワークから。今年の新規追加フレームワーク1は21個。

ML Compute

ニューラルネットワークの学習とバリデーションを行うためのフレームワーク、とのこと。

Accelerate training and validation of neural networks using the CPU and GPUs.

macOS用かな?と思いきやiOSでも利用可

ML Compute utilizes the high performance BNNS primitives made available by the Accelerate framework for the CPU and Metal Performance Shaders for the GPU.

『ML Computeは、CPU用のAccelerateフレームワークとGPU用のMetal Performance Shadersによって利用可能になったハイパフォーマンスなBNNS primitivesを利用しています。』

とのことでこれらのラッパー的な位置づけっぽい。Core MLもBNNSとMPSをラップしており、iOS 13ではモデルの更新も可能になったが、あくまで学習済みモデルを更新するもの。こちらはレイヤークラス群も定義されてるので、PyTorchやTensorFlowみたいにネットワークを実装してiOSやmacOSのGPU/CPUを駆使して学習をまわせる、というものかと。

ちなみにMLCDeviceというクラスがあったのでもしやと思い見てみたが、Neural Engineを指定できるようにはなっていなかった。

https://developer.apple.com/documentation/mlcompute/mlcdevice?changes=latest_major

Metal Performance Shaders Graph

TensorFlowのように多次元テンソルのグラフを構築し、コンパイル、実行するフレームワークらしい。

Build, compile, and execute customized multidimensional compute graphs for linear algebra, machine learning, computer vision, and other similar domains.

f:id:shu223:20200623085100p:plain:w500

(画像は"Build customized ML models with the Metal Performance Shaders Graph"セッションのサムネ)

以前からあったMPSCNNとはどういう関係になるのか、またML Computeを使う場合はこのレイヤー(MPSフレームワーク)を気にする必要はないのか、それともここまで潜る必要があるのか、といったあたりをセッションでチェックする。

ちなみにサンプルコードもある。

Nearby Interaction

名前と一行説明からして、バックグラウンドでのすれ違い通信系(待望)かなと第一印象では思ったが、

Locate and interact with nearby devices using distance, direction, and identifier.

距離、方向、識別子を使用して、近くのデバイスの位置を特定し、対話することができます。(by DeepL)

リファレンスページみたら懐かしのBumpみたいなイラストが載っていて、

f:id:shu223:20200623085821p:plain:w500

なんだ?と思ってOverviewを読んでみると、

Use NearbyInteraction (NI) in your app to acquire the position of nearby iPhones with a U1 chip, such as iPhone 11 or later. To participate in an interaction, devices in physical proximity run an app and consent to share their position and device tokens that uniquely identify their device. When the app runs in the foreground, NI notifies the interaction session of the peer’s location by reporting the peer’s direction and distance in meters.

アプリでNearbyInteraction(NI)を使用して、iPhone 11以降などのU1チップを搭載した近くのiPhoneの位置を取得します。インタラクションに参加するには、物理的に近くにいるデバイスがアプリを起動し、位置情報とデバイスを一意に識別するデバイストークンを共有することに同意します。アプリがフォアグラウンドで実行されると、NIは、相手の方向と距離をメートル単位で報告することで、相手の位置をインタラクションセッションに通知します。

Devices that share their positions using the high frequency of the U1 chip enable a fluid, interactive session in which peer positioning within the physical environment becomes a primary driver of the user experience. For example:

U1チップの高周波数を使用して位置を共有するデバイスは、物理環境内でのピアの位置がユーザ体験の主要なドライバーとなる流動的なインタラクティブセッションを可能にします。例えば、以下のようなものです。(Translated by DeepL)

なんと、U1チップ使うやつだった!これはぜひ試したい。

ちなみにサンプルもある: "Implementing Interactions Between Users in Close Proximity"

SensorKit

ありそうでなかった、その名も「センサーキット」。

Retrieve data and derived metrics from an iPhone’s sensors, or from a paired Apple Watch.

これまで加速度センサーやジャイロetc.のセンサー類を扱う存在だったCore Motionはdeprecatedになるのかなと思ったがまだ現役だった。こちらのフレームワークではペアリングしてるApple Watchのセンサー値も取れるのが違いか。

扱えるセンサー一覧:

staticletaccelerometer:SRSensorstaticletambientLightSensor:SRSensorstaticletgyroscope:SRSensorstaticletonWristState:SRSensorstaticletpedometerData:SRSensorstaticletvisits:SRSensor

App Clips

iOS 14の目玉新機能のひとつであるApp Clips、これは新しいUI/UXだけに何がどこまで実現できるのかを把握するためにも要チェック。

Create an app clip to make some of your app’s functionality available to users who don’t have the full app installed.

f:id:shu223:20200623091704p:plain:w450

WidgetKit

同じくiOS 14の目玉新機能のひとつであるウィジェット。これも専用フレームワークが新規で追加されたとなると当然要チェック。

Show relevant, glanceable content from your app on the iOS Home screen or macOS Notification Center.

f:id:shu223:20200623092105p:plain:w450

StoreKit Test

Create and automate tests in Xcode for your app’s subscription and in-app purchase transactions.(アプリのサブスクリプションとアプリ内購入トランザクションのためのテストをXcodeで作成し、自動化します。 by DeepL)

個人的にはここ最近はアプリ内課金の実装をする機会がないのだけど、これはかなり助かるやつでは...!

System

大層な名前に惹かれたが、中身を見てみたらちょっと期待したものと違った。

Perform low-level file operations using type-safe APIs.

Cの低レベルなファイル操作をSwiftでタイプセーフに書ける、というものらしい。

close ⟶ close()

lseek ⟶ seek(offset:from:)

open ⟶ open(_:_:options:permissions:)

pread ⟶ read(fromAbsoluteOffset:into:retryOnInterrupt:)

pwrite ⟶ write(toAbsoluteOffset:_:retryOnInterrupt:)

read ⟶ read(into:retryOnInterrupt:)

write ⟶ write(_:retryOnInterrupt:)

その他の新フレームワーク

(翻訳はby DeepL)

  • Accessibility
    • Make your apps accessible to everyone who uses Apple devices.(Appleデバイスを使用しているすべての人がアプリにアクセスできるようにしましょう。)
  • App Tracking Transparency
    • Request user authorization to access app-related data for tracking the user or the device.(ユーザーやデバイスを追跡するために、アプリ関連のデータにアクセスするためのユーザー権限を要求します。)
  • Apple Archive
    • Perform multithreaded lossless compression of directories, files, and data.(ディレクトリ、ファイル、データをマルチスレッドでロスレス圧縮します。)
  • Automatic Assessment Configuration
    • Prevent users from accessing specific system features during high-stakes assessment activities, such as administering an exam.(試験の実施など、高額な評価活動中にユーザーが特定のシステム機能にアクセスできないようにします。)
  • Developer Tools Support
    • Expose custom views and modifiers in the Xcode library.(Xcodeライブラリでカスタムビューとモディファイアを公開します。)
  • Exposure Notification
    • Implement a COVID-19 exposure notification system that protects user privacy.(利用者のプライバシーを保護するCOVID-19曝露通知システムを導入する。)
  • Kernel Management
    • Manage the loading and unloading of system extensions in the kernel.(カーネル内のシステム拡張のロードとアンロードを管理します。)
  • Media Setup
    • Enable configuration and account management of media services for use on HomePod.(HomePodで使用するメディアサービスの設定とアカウント管理を有効にします。)
  • Paravirtualized Graphics
    • Add limited graphics acceleration to your guest driver stack.(ゲストドライバスタックに限定されたグラフィックスアクセラレーションを追加します。)
  • Screen Time
    • Share and manage web-usage data and observe changes made by a parent or guardian.(ウェブ利用データを共有・管理し、保護者の変更点を観察することができます。)
  • Uniform Type Identifiers
    • Unified type information for files and data transfer.(ファイルやデータ転送のための統一された型情報。)
  • Wallet Passes
    • Create, distribute, and update passes for the Wallet app.(ウォレットアプリのパスを作成、配布、更新します。)
  • xcselect
    • A function that finds the path to a macOS SDK version on disk.(ディスク上の macOS SDK バージョンのパスを検索する関数です。)

まとめ

APIリファレンスの差分から見て気になる新APIをピックアップするシリーズ、新フレームワーク編でした。次は既存フレームワークの更新を見ていきます。

そしてそのあとは、サンプルやセッションを見てもっと具体的に実装方法や何ができて何ができないのかといったところを探っていきます。

昨年はそれらの知見を書籍にまとめましたが、今年はnoteの有料マガジンにまとめていきたいと思います。

note.com

まだ記事がないので今ならたったの500円です。サブスクではなく買い切り価格です。記事が充実してきたら価格改定していきたい所存です。


  1. https://developer.apple.com/documentation/technologies?changes=latest_majorのリストに載っている単位をここでは便宜的に「フレームワーク」と呼んでいますが、厳密にはフレームワークではないのも混じっています。


API Diffsから見るiOS 14の新機能 - ML・画像・音声編 #WWDC20 #iOS14

$
0
0

本日からはじまったWWDC 2020、明日から始まるセッションに備え、ドキュメントからAPIの差分をみて気になったものをピックアップしていきます。

数時間前に投稿した新規追加フレームワーク編に続き、本記事では既存フレームワークのうち、機械学習(ML)、画像、音声関連のものを見ていきます。

f:id:shu223:20200623162859p:plain

Vision

めちゃくちゃ機能追加されてます。

class VNDetectHumanBodyPoseRequest

人体の姿勢推定。ついに標準機能として入ったわけですね。

qiita.com

class VNDetectHumanHandPoseRequest

手の姿勢推定。これが必要でMediaPipeを試したりしたこともありましたが、もう必要なくなるのでしょうか?

class VNRecognizedPointsObservation

上の姿勢推定の結果はこの型で返ってくるようです。

サンプルもセッションもあるので、深堀りしてマガジンに書いていきます。

Core ML, Core ML Tools(coremltools)

ここはピックアップせずともしっかり見るつもりなので、本記事では割愛。

Create ML

テンプレートめっちゃ増えてます。NDA遵守のためベータアプリケーションのスクショは貼らないでおきますが、「Create MLのテンプレート」といってもピンとこない人もいるかもしれないので、代わりに現行版のテンプレート選択画面(の一部)のスクショをはっておきます。

f:id:shu223:20200623155402p:plain:w300

ここから4つのテンプレートが追加されています。

個人的な感想:

  • 動画用モデル(Action Classification)がおもしろそう。
  • Style Transferはいまさら感(Turi Createにはだいぶ前からあったのになぜ今になって?)
  • Soundカテゴリに追加がなかったのが本当に残念
  • MotionカテゴリにActivity Classificationに加えてAction Classificationも追加。これもApple Watchで試したい

Metal Performance Shaders

機械学習系のAPIはML Computeも出たし個人的にはこのレイヤーで組むことはしばらくなさそうなのでフィルタ系だけを見ていく。

MPSImageEuclideanDistanceTransform

A filter that performs a Euclidean distance transform on an image.

"Euclidean distance transform (EDT)"なる変換を適用するフィルタ。知らないのでググってみたところ、以下の記事がヒット。大変にわかりやすい。

medium.com

応用例も書かれていて、セマンティックセグメンテーションの誤差のメトリクスとして使われることがあるらしい。またErosion / Dilationを計算する手法としても利用されるらしい。ちなみにErosion / Dilationはそれぞれ孤立点の除去、不連続な点の接続と穴埋めのために利用される。

ちなみにここまで書いて気付いたが、このAPIはiOS 11.3からあるもので、新APIは

var searchLimitRadius: Float

というプロパティでした。これはEDTの計算手法を知っていれば名前で利用法がわかる。

MPSImageCanny

今度こそiOS 14の新クラス。ドキュメントには何も書いてないが、名前からいってCanny法によるエッジ検出を行うフィルタだと思われる。

f:id:shu223:20200623172504p:plainWikipediaより)

MPSImageEDLines

iOS 14の新クラス。MPSKernelを継承。ドキュメントに説明なし。

Natural Language

NLTaggerクラスに新しいメソッドが2つ

@nonobjc func tagHypotheses(at index: String.Index, unit: NLTokenUnit, scheme: NLTagScheme, maximumCount: Int) -> ([String : Double], Range<String.Index>)

Finds multiple possible tags for a given linguistic unit, for a single scheme, at the specified character position.(指定された文字位置で、指定された言語単位について、単一のスキームについて、複数の可能性のあるタグを見つけます。)

func tokenRange(for: Range<String.Index>, unit: NLTokenUnit) -> Range<String.Index>

Finds the entire range of all tokens of the specified linguistic unit contained completely or partially within the specified range.(指定された範囲内に完全または部分的に含まれる、指定された言語単位のすべてのトークンの範囲全体を検索します。)

NLEmbeddingクラスに4つの新クラスメソッド

class func sentenceEmbedding(for: NLLanguage) -> NLEmbedding?

Retrieves a sentence embedding for a given language.(指定された言語の文の埋め込みを取得します。)

class func sentenceEmbedding(for: NLLanguage, revision: Int) -> NLEmbedding?

Retrieves a sentence embedding for a given language and revision.(与えられた言語とリビジョンのための文の埋め込みを取得します。)

class func currentSentenceEmbeddingRevision(for: NLLanguage) -> Int

Retrieves the current version of a sentence embedding for the given language.

class func supportedSentenceEmbeddingRevisions(for: NLLanguage) -> IndexSet

Retrieves all version numbers of a sentence embedding for the given language.

NLModelクラスに2つのメソッド

func predictedLabelHypotheses(for: String, maximumCount: Int) -> [String : Double]

Predicts multiple possible labels for the given input string.(与えられた入力文字列に対して,複数の可能性のあるラベルを予測します.)

func predictedLabelHypotheses(forTokens: [String], maximumCount: Int) -> [[String : Double]]

Predicts multiple possible labels for each string in the given array.(与えられた配列内の各文字列に対して,複数の可能性のあるラベルを予測します.)

・・・試してみないとピンとこないので、試してみます。あとこのフレームワークはiOS 12の頃に試して以来な気がしていて、当時は日本語をサポートしている機能は一部だけだった気がします。今一度日本語のサポート状況をみてみたいなと。

Final Cut Pro X

期待していたが更新がなかったフレームワーク

事前に予想、というより期待することを書いていたのですが、見事に外れたものから書いていきます。

note.com

AVAudioEngine

SoundAnalysis

Speech

標準の翻訳アプリが入ったことで、音声認識フレームワークであるSpeechフレームワークも強化されているかと期待しましたが、あてが外れました...

Speechの音声認識、デモとして試すとそこそこうまくいく気がするのですが、いざ実運用しようとすると全然ダメなんですよね。しかし音声認識は汎用性が高いのでどうにかしてほしいなぁと。実はAPIが更新されてないだけで内部的には刷新されているのではとまだ期待しています。

公式配布の学習済みCore MLモデル

昨年はWWDCの会期中に新しいモデルが複数個追加されてテンションあがったのですが、今年は何もなし。

しかしちょっと前にPoseNetモデルが追加されています。

まとめ

本記事では既存フレームワークのうち、ML・画像・音声に関連する気になるAPIをピックアップしました。次はこれら以外の既存フレームワークの更新を見ていきます。

そしてそのあとは、サンプルやセッションを見てもっと具体的に実装方法や何ができて何ができないのかといったところを探っていきます。

昨年はそれらの知見を書籍にまとめましたが、今年はnoteの有料マガジンにまとめていきたいと思います。

note.com

まだ記事がないので今ならたったの500円です。サブスクではなく買い切り価格です。記事が充実してきたら価格改定していきたい所存です。

「エンジニアのための発信講座」をはじめます

$
0
0

(2020.7.15 タイトル変更しました)

弊オンラインサロン開設以来、ずっと「サロンという形態で自分が提供できる価値は何か」とずっと自問してきました。iOSやSwiftといった何か特定の技術を初学者に丁寧に教えるというのは僕の強みを活かすものではないし、自分が旗を振って共同開発をやるというのもピンとこないし・・・ということでもうこの方向しかないだろうと。で、本日!弊サロンのv2.0ともいえる新しいプロジェクトを始動させました。以下サロン内のSlackチャンネルに書いた内容:

講座の説明

本講座の主旨

「サロン主がもしかしたら仕事をふるかも!?」というのは多くのエンジニア系サロンにおいて参加の大きな動機となっているようです。本サロンでもそれは可能ですが、「やりたい仕事の依頼が向こうからくるエンジニアになることをサポートする」方が堤の強みとも合致するし、より本質的では?と考えるに至りました。

どこを目指すか

必ずしもフリーランスを推奨するわけではありませんし働き方の好みは人それぞれで良いと思いますが、それをふまえた上で一例として堤のケースを示しますと、

  • エージェント経由で仕事を受けたことは一度もない
  • 単価はこちらで公開中(有料note)・・・もっと上げても需要はあるだろうが新しいスタートアップの仕事もやりたいので上げ過ぎないようにしている
  • その時々の技術的興味に応じてやりたい仕事だけを選べている
  • 海外からもよく依頼は来る
  • それほど物欲もないし税金が高くなるばかりなので1年の後半はもう働かないぞと思うがつい面白い案件が来てやってしまい、なんだかんだ2000万ぐらいは稼いでしまう(働くつもりがないのに稼いでしまうのでもはや不労所得の感覚)

要は、高単価でも仕事が選べるぐらいたくさんくる、という状況です。

場所や時間の制約を受けず自由に働きたい/海外で働きたい/興味のある仕事だけやっていたい・・・といったあたりは堤の経験からサポートできそうな気がしています。

講座の進め方

  • エントリーする(後述)
  • 堤がレベル別に課題を出す
  • 週報をこのチャンネルに書く(任意)1
  • Zoomミーティング・・・講義&週報を元に個別フィードバック(頻度は検討中)

課題

基本的な方向性としてとにかく発信力を鍛えていただきます。エンジニアとして技術力をつけるのはもちろん当然のこととして、そのスキルと実績をしっかり外に見えるようにして、仕事が転がり込んでくるようにする部分を本講座でサポートします。

【入門】

こちらの動画をご覧ください。(サロン内で毎日投稿している動画のひとつ)

youtu.be

まずはここで言及している以下の条件を満たすよう、なんでもいいので発信活動を行ってください。

- フォロワー/フォロー > 2
- フォロワー > 100

【中級】

フォロワー/フォロー比2以上を維持しつつ、「技術発信をベースに」 フォロワー数2000以上を目指してください。2000ぐらいあれば、良い技術記事を書いた場合、良いOSSを公開した場合等にバズまではいかないにしても「火種」ぐらいは起こせるようになり、良質な発信活動がしっかり報われるようになります。

技術発信の手段としてはQiitaやnoteに記事を書く、GitHubでOSSを公開する、勉強会やカンファレンスに登壇する、何でもOKです。

【上級】

欲しい案件が向こうから来るようにするにはある程度「狙った」ブランディングが必要となるでしょう。個人個人で置かれている状況や持っているスキルや発信チャンネル、目指している方向性によって変わってくると思うので一緒に考えましょう。

参加条件

  • サロンメンバーはどなたでも。
  • ROM専でもOK。時間がない方もたまに参加したりたまに実践してみたりでOKです。

参加方法

このチャンネルで、以下の内容を投稿してください。

- どこを目指すか
- その目指している地点に対する現状
- TwitterアカウントのURLと今現在のフォロー数/フォロワー数
- QiitaアカウントのURLと現在のコントリビューション数
- GitHubアカウントのURLと現在のスター数
- その他発信チャンネルがあれば

ちなみに堤の数字はこんな感じ:

  • Twitter: 979フォロー/9782フォロワー
  • Qiita: 22873コントリビューション
  • GitHub: 24467スター

興味のある方はぜひ!

弊サロンにはこちらから入れます。今のところたったの月額1000円、コーヒー2回分ぐらいです。

community.camp-fire.jp

「オンラインサロン」にうさんくさいイメージをお持ちの方は、こちらの口コミを読んでみてください。

minsalo.com

僕はiOSエンジニアですが、現メンバーの半分以上の方はそれ以外の技術領域(バックエンドやフロントエンドやAndroid)を専門とされていますし、エンジニアではない方や初学者でこれから目指されるという方も大勢いらっしゃいます。どうぞご安心を。ROM専(見てるだけ)の参加形態も全然ありです。


  1. 日報・分報は個人的に推奨しますがチャンネルの流れが早くなりすぎるおそれがあるので各自timesチャンネルをつくってそちらに書いてください

「エンジニアのための発信講座」を2ヶ月やってみた進捗

$
0
0

先日、「エンジニアのための発信講座」の第5回を行いました。開始からだいたい2ヶ月経ったということで、今回は趣向を変えて「中間成果発表会」と題して進捗状況を共有しました。

以下発表スライドです。

f:id:shu223:20200831211130j:plain

f:id:shu223:20200831211205j:plain

f:id:shu223:20200831211219j:plain

f:id:shu223:20200831211235j:plain

f:id:shu223:20200831211602j:plain

f:id:shu223:20200831211616j:plain

f:id:shu223:20200831211634j:plain

f:id:shu223:20200831211648j:plain

(確認できているだけでも複数出ています)

f:id:shu223:20200831211705j:plain

(初めての登壇のハードルの高さを考えるとすごいことかと!)

f:id:shu223:20200831211721j:plain

f:id:shu223:20200831211738j:plain

(メンバーにとある出版社から執筆依頼が来た)

f:id:shu223:20200831211954j:plain

(仕事の依頼が来たメンバーも数人)

f:id:shu223:20200831211922j:plain

(英語で記事を書いていて海外からの引き合いが来始めた人も)

f:id:shu223:20200831212054j:plain

f:id:shu223:20200831212111j:plain

まとめ

なかなか堅実な成果が出ているといえるのではないでしょうか?

なお本講座は、テクニックを弄してフォロワーを急に増やすとかではなく、一時的にだけがんばって本業よりも優先して記事を書くとかでもなく、瞬間的なバズ狙いでもなく、無理なく続けられる方法で記事を書いて徐々に「実のある発信力」をつけていきましょう、というスタンスでやっております。

f:id:shu223:20200901190547p:plain

f:id:shu223:20200901190602p:plain

f:id:shu223:20200901190726p:plain

本講座は「エンジニアと人生コミュニティ」の活動の一環として行っています1

エンジニアと人生コミュニティ - CAMPFIRE (キャンプファイヤー)

過去の講義パートは動画で無料で全公開しています2

youtu.be

youtu.be

youtu.be


  1. エンジニア以外の方々も歓迎です!技術の話をしているわけではありませんので。

  2. 過去回の個別アドバイスの動画はコミュニティ限定で閲覧可能です。

2020年のふりかえり:技術への全振りを緩めて新領域に挑戦

$
0
0

2019年は「技術発信のマネタイズ」を目指した1年だった。有料note → 技術書の個人出版 → 案件と全フェーズをマネタイズするしくみができ、これのおかげで2020年はベーシックインカム的に一定の収益があり、新しいことに挑戦できた1年だった。

(2020年は書籍の利益が約200万、noteが約90万)

以下その振り返り。

2020年、成長サイクルモデルの限界

「成長サイクルモデル」というのを書いてみたことがある。

note.com

興味のある技術を勉強する 
→ 発信する 
→ おもしろい仕事をもらう 
→ スキルと実績ゲット 
→ 発信する 
→ おもしろい仕事をもらう
→ ...

というインプットとアウトプットを両輪として循環するサイクルとなっている。

10年間これで楽しくやってこれたのだが、慢性的に2つの問題を抱えていた。

  • サイクルをまわすすべての動力の源泉が「時間」となっている
  • サイクルが「技術」だけに特化している

前者の問題は根深くて、まぁもうこのサイクルは終わってるよねと先の記事では結論づけている。

まさに現在のモデルは自分の時間というリソースが尽きたところで成長が終わる。時間は慢性的に尽きているのでつまりこの成長サイクルは既に終了している。(時間でお金を買うといっても限界がある)

後者の話は、たとえば僕が友人と飲みに行くとか、読書するとか、そういう活動は全部(このサイクルにあてはめてみれば)時間という源泉を奪うマイナス要因となってしまうということだ。いや行けばいいじゃんと思うかもしれないが、実際のところ、高時給がもらえて、つくるプロダクト/サービスも良くて、勉強したい技術が使えて、クライアントも良い人で仕事がしやすくて、っていう仕事がたくさんあるので、どうしても持ち時間を仕事で埋め尽くしてしまうという事態になっていた。

ホリエモン氏のモデル(上述の成長サイクルモデルの記事に書いた)はこのへん非常にうまい具合になっていて、

f:id:shu223:20210105151323j:plain

  • 基本的に持ち時間をすべて「おもしろいこと」に全振りしておけば勝手にサイクルがまわっていく

  • 本を書くにしても1冊1冊をすべて自身で書き下ろしていく必要はなくて、誰かが過去の文章や講演を再編集したりインタビューしたりしてまとめてくれるので、プロダクト生産の時間コストが限りなくゼロに近づく(ので、おもしろい仕事に全振りできる)。

自分の技術だけに特化したモデルから脱却できないものかなーと考え始めたのが2020年だった。

しかし「持ち時間をすべておもしろいことに全振りしておけば勝手にまわっていく」というサイクルは理想的ではあるけど、僕が仮に全振りしても同じようにはまわらないわけで、自分なりの自分に向いたやり方で理想に近づけていくしかない。そこは考え中。

YouTubeとオンラインサロン

このへんの課題感が、2020年に始めたYouTubeとオンラインサロン(その後コミュニティになった)によりちょっと前進した。

まず1月から開始したYouTubeチャンネル1

www.youtube.com

これのおかげで、会いたい人に会って聞きたい話を聞く、という旧サイクル下ではコスト/機会損失だった行為を自分のサイクルに組み込むことができた。

ほとんど「撮って出し」なので収録以外の時間コストはほぼゼロだし、視聴者のことはほぼ考えず(コンテキストの説明等もほとんどしない)僕が聞きたい話を聞いているので、飲みに行くのと同じような気楽さ・楽しさで運営できている。つまり、マネタイズできなくてもサステナブル。(僕が話したい人がいる限り飲みに行く感覚で続けられる)

さらに、このYouTubeはゲストインタビュー中心だが、その中で僕の「価値観」を発信できていると思う。これは今までのテキストベースのメディアではあまり発信できていなかった部分。さらにもうちょっとチャンネルが大きくなれば、オンラインコミュニティへの送客も期待できる。いい事だらけだ。

5月から始めたオンラインサロン(8月からコミュニティに名実ともに変わった)もまた成り行きで始めたものだけど、これもまた自分の技術「以外」の部分をサイクルに組み込むための重要なチャンネルになっている。

community.camp-fire.jp

そんな感じで、YouTubeとオンラインサロン(コミュニティ)によって、「技術以外の人間活動全般をビジネスサイクルに組み込みたい」というところが前進した2020年だった。

2021年

そんなわけで2020年は今まで技術面に全振りしていた力を少し緩め、 YouTube、コミュニティという新しい領域に挑戦できた。

しかしその反動で技術面は(相対的に)弱くなった2、 YouTube、コミュニティもまだまだ自分の柱と呼ぶには弱い。

そもそも「サイクル」といったものの実はサイクルなんて構築できておらず、 断絶した点と点があるだけでそれらはあまりつながっていない。

この状況、下手したらすべてが中途半端のまま終わってしまいそうな危うさがある。 今は10年間で積み上げたiOSキャリアの余韻で食えてるようなものなので、 下手したら再来年あたりは就職活動してるかもしれない。

というわけで、もうちょっとこれらの活動を育てて、ビジネスとして軌道に載せて、サイクルを構築していくのが2021年にやるべきことかなぁと漠然と考えている。(考え中)


  1. このYouTubeチャンネルは最初はVoicyというクローズドな場で展開していた音声コンテンツをもっとオープンなプラットフォームで出したいなと思ったところからスタート。KBOY氏が遊びに来てくれた際にせっかくだから動画を撮ってみますかーというので初めて撮影してみて、あーこんなに簡単にできるんだというのでなし崩し的に以降のエンジニアインタビューも音声じゃなくて動画でやることになった。

  2. 技術面で開拓したところもあるのだけど、話が逸れるのでこれはまた別の記事で。

過去5年の #iOSDC 登壇の見どころ

$
0
0

iOSDC Japan 2021、非常に楽しませていただきました。多くのセッションとスライドで勉強させていただいたので、いずれまたnoteにでもまとめていきたいと思います。

ところで、私も(幸運にも)2006〜2020まで毎年登壇させていただいておりました。先日ひさびさに動画を見返してみたところ、これが2021年の今見てもなかなか良く、過去のものだからと二度と誰の目にも触れないのは寂しいと思ったので、自分的ベストプレゼン順にご紹介したいと思います。

第1位:飛び道具ではないMetal(2017)

www.youtube.com

みなさんのお時間をなるべく取らないよう、いきなり1位からいきます。自分的ベストプレゼンです。

最初のつかみもよく、最後のQ&Aまで良い

  • 当時ほとんどの人が興味がなかったであろうMetalをテーマにしつつも、ちょっとでも多くの人に興味を持ってもらえるように、という姿勢が感じられるつかみ
  • 難しい内容を独自の切り口で噛み砕いてわかりやすくしている
  • それでいてふんわりとした話ではなくしっかり中身がある
  • 今見ても古くない内容

第2位:Depth in Depth(2018)

www.youtube.com

  • デモが豊富で、「プレゼンならでは」
  • デプスとは、から始まり、視差やToFのしくみの解説、そして応用まで網羅
  • 静止画・動画・ARKitも網羅
  • 今見ても古くない
  • 登壇当日の朝に子供が生まれるというライブ感のあるドラマ

第3位:海外カンファレンスに登壇する(2016)

www.youtube.com

  • 「自分ならでは」の経験をベースにしたテーマ
  • 実際の英会話の録音や、Q&Aで固まった話は勇気づけられる人が多いのでは。
  • 今は時勢が悪いが、またカンファレンスがオフライン開催されるようになったら、海外で働くことや海外案件獲得に興味ある人には参考になる知見があると思う。

第4位:機械学習ブルーオーシャン Core ML(2020)

www.youtube.com

  • 内容としては、Core MLの一歩深いところを解説しようとしている点は良い。が、後半の解説は誰にも伝わってないと思う...(わかってる人だけがわかる系の解説)
  • オンライン開催&事前収録の特性を活かし、録画したものを編集してテンポよくしたのは良いと思う。
  • 自分のYouTubeチャンネルを持っていることを活かし、発表当日に字幕付きのものを公開した点は良かった。

第5位:今こそwatchOS(2019)

www.youtube.com

・・・が、

  • 結局自分でwatchOSアプリ開発をやってないので、散漫だし浅い
  • Metalもデプスも発表・執筆ドリブンで勉強してその後多くの仕事につながったが、watchOSに関してはこれっきり触れる機会がなかった...

余談(iOSDCと人生)

もともとは「過去の登壇も見てほしい!」と思って書き始めた本記事ですが、書いてるうちにいろいろと考えさせられました。

以下記事のテーマとは関係のない余談(内省):

直近の2年のプレゼンが自分の中で下位にあり、このへんで登壇者としては心が折れてしまったような気がします。自分の期待値と、要する努力量と、実際に出せるアウトプット品質のバランスが取れなくなってしまったような感じ。

人生ステージが変わったのもあると思うし、それによって仕事への関わり方が変わったのもあるし、世の中も動くことで相対位置が変わったのもあるし、発信スタイルが変わったのもあるし、それら諸々によってマインドが変化したというのもあるんだろうなぁと。

弊コミュニティのSlackにiOSDC直後に以下のような投稿をしていたのですが、

f:id:shu223:20210927184810p:plain:w400

大規模カンファレンスに出ると、なんか毎度自分の今後の身の振り方について見直したくなる 何を強みにして、どういうあたりに時間を割り振っていくのか、どういう世界に対してプレゼンスを出していって、何をあきらめていくのか、とか。

多くの人の専門性とか、各社における活動とかそこで積んでいる経験とか、発表に対しての反応(≒その人のプレゼンス)とか、 そういういろんな人の生き様を一気にたくさん浴びるからだろうなぁ

僕が登壇者としては心折れてしまった一方で、昔も今も素晴らしい発表をされ続けている方もいて、刺激を受けるし、さて自分はどうしていこうかと人生を考えさせられもしました。

結論はないですが、引き続きどう楽しくエンジニア人生をやっていくか、模索し続けたいと思います。

Viewing all 314 articles
Browse latest View live