SRA 産業第1事業部 鈴木真吾
発表者について
Google I/O とは
Google I/O の内容
Google I/O に参加しよう
鈴木真吾(@giantneco)
所属: 産業第1事業部
言語: Go, C, Scala, etc
Google I/O
Google I/O 2016 に続いて 2 回目の参加
Google 開催の年次開発者向けイベント
毎年 5 月頃に開催
マウンテンビューの Google 本社近くで開催
メインは Android, Web など
アプリ開発者向け
クラウド関連は別のイベントがある
TensorFlow も別のイベントがある
どんなことをやっているか?
キーノート
セッション
コードラボ
サンドボックス
コミュニティミートアップ
アフターパーティー
etc
キーノートで反響が大きかった発表
Google Duplex
Google Assistant が音声で予約を行ってくれた
受け答えがかなり自然
Android P beta
Google 以外の会社もベータに対応
今後、各社端末の新OS対応が早まるかも
Android Jetpack
開発環境結構変わりそう
いわゆる講義形式のもの
3 日間で 164 件のセッションがある
主なセッションとして
Android&Play ... 58件
Web ... 30件
ML&AI ... 16件
入場者数の一部が予約制になって待ち時間がかなり短縮された。
用意された環境でデモを作成して学習できる
Mac + Pixel で開発ができる
実機持ち込みも可能
セッションで聞いた内容をすぐに試すことができる
直接 Googler に質問できる
さまざまなデモの展示
VR&AR
人気
Google Assistants
etc
実機が置いてあったり、インタラクティブなデモを遊べたりして結構楽しい
ミートアップイベントも開催
技術分野ごとのミートアップ
クラウド, Firebase etc
出身地域別のミートアップ
他の日本からきた開発者とはここで出会えるチャンス!
今年は
Google Home Mini
Android Things Starter Kit
がもらえた。
楽しい
2016 に比べて運営は格段によくなっている
待ち時間の短縮
給水ポイント
アルコール飲めるかどうかは事前確認制
日本人も結構来ている
現地でしかできないことをやったほうがいい
Codelabs とか行ってよかった
現地でしかできない体験はある
同時期に SF で他のイベントがある
Maker faire
Day 0 Party
抽選の登録は 2月末あたり
参加人数が多いので、割と当たる確率は多そう
宿泊地
今年はサンフランシスコのほうが宿泊料安かったらしい
交通手段
Uber or Lyft
期間中は Google のクーポンがある
Caltrain 本数少ないので注意
24 時間運行のバスがあるが、深夜は客層に注意
現地天候への対策
昼は暑く、夜は寒い
休める物陰は増えたが、日焼けどめ必須
夜はかじかむぐらい冷えるので羽織れるもの
アレルギーある人は注意
屋外なので花粉が飛んでいる
野鳥が多いので、羽毛などにアレルギーがある場合
Intel の Google I/O 参加者向けパーティー
無料の食べ物とアルコール
Intel エンジニアのデモが見られる
AI 関連
Project Celadon
Intel Computer Vision SDK
Movidius
IoT
Intel System Studio
Sawtooth Core
他、Chrome, VR&AR なども
機械学習のデモが多かった
Rasberry Pi + Movidius による物体検出
駐車場カメラに使う空きスペース検知
方向性としては IoT + ML が多い印象
Android Jetpack
Support Library
Navigation
Paging
Slices
Work Manager
Android KTX
その他
Android Jetpack は開発を効率化するツール&ライブラリ
Support Library & Architecture Components の後継
それぞれのコンポーネントは個別に採用できる
Support ライブラリは androidx の名前空間に統合される
android.support.* → androidx.*
バージョンの整理
バージョンの巻き戻し( 28.0.0 → 1.0.0 )
Support ライブラリは 28.0.0 stable が最後
Semantic Versioning の採用
パッケージルールの変更
androidx.<feature>.ClassName
アプリ内のナビゲーションに必要なものを提供
Navigation Graph
画面遷移を示す XML
GUIで画面遷移設計できる
DeepLink とそのバックスタックの解決
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
app:startDestination="@+id/launcher_home">
<fragment
android:id="@+id/launcher_home"
android:name="com.example.android.codelabs.navigation.MainFragment"
android:label="@string/home"
tools:layout="@layout/main_fragment">
<action
android:id="@+id/next_action"
app:destination="@id/flow_step_one"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_in_left"
app:popExitAnim="@anim/slide_out_right" />
</fragment>
<fragment
android:id="@+id/flow_step_one"
android:name="com.example.android.codelabs.navigation.FlowStepFragment"
tools:layout="@layout/flow_step_one_fragment">
<argument
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Set NavOptions
val options = NavOptions.Builder()
.setEnterAnim(R.anim.slide_in_right) // Override navigation animation
.setExitAnim(R.anim.slide_out_left)
.setPopEnterAnim(R.anim.slide_in_left)
.setPopExitAnim(R.anim.slide_out_right)
.build()
view.findViewById<Button>(R.id.navigate_dest_bt)?.setOnClickListener {
findNavController(it).navigate(R.id.flow_step_one, null, options)
}
// Update the OnClickListener to navigate using an action
view.findViewById<Button>(R.id.navigate_action_bt)?.setOnClickListener(
Navigation.createNavigateOnClickListener(R.id.next_action, null)
)
}
Bundle args = new Bundle();
args.putString("myarg", "From Widget");
PendingIntent pendingIntent = new NavDeepLinkBuilder(context)
.setGraph(R.navigation.mobile_navigation)
.setDestination(R.id.android)
.setArguments(args)
.createPendingIntent();
remoteViews.setOnClickPendingIntent(R.id.deep_link, pendingIntent);
Recycler View に使える遅延読み込みライブラリ
ネットワーク、DB などから遅延読み込み
RXJava サポートあり
class ConcertViewModel {
fun search(query: String): ConcertSearchResult {
val boundaryCallback =
ConcertBoundaryCallback(query, myService, myCache)
// Error-handling not shown in this snippet.
val networkErrors = boundaryCallback.networkErrors
}
}
class ConcertBoundaryCallback(
private val query: String,
private val service: MyService,
private val cache: MyLocalCache
) : PagedList.BoundaryCallback<Concert>() {
override fun onZeroItemsLoaded() {
requestAndSaveData(query)
}
override fun onItemAtEndLoaded(itemAtEnd: Concert) {
requestAndSaveData(query)
}
}
バックグランドジョブ管理ライブラリ
これまであったバックグラウンドジョブ
JobScheduler
Firebase Jobdispatcher
AlarmManager
柔軟なジョブ管理ができる
制限の設定
定期的な実行
重複時の挙動設定
class CompressWorker : Worker() {
override fun doWork(): WorkerResult {
myCompress()
return WorkerResult.SUCCESS
}
}
val compressionWork = OneTimeWorkRequestBuilder<CompressWorker>().build()
WorkManager.getInstance().enqueue(compressionWork)
Worker
WorkManager への登録
val myConstraints = Constraints.Builder()
.setRequiresDeviceIdle(true)
.setRequiresCharging(true)
// Many other constraints are available, see the
// Constraints.Builder reference
.build()
val compressionWork = OneTimeWorkRequestBuilder<CompressWorker>()
.setConstraints(myConstraints)
.build()
Work を開始する条件を設定できる
WorkManager.getInstance()
.beginWith(workA)
// Note: WorkManager.beginWith() returns a
// WorkContinuation object; the following calls are
// to WorkContinuation methods
.then(workB) // FYI, then() returns a new WorkContinuation instance
.then(workC)
.enqueue()
Worker をつなげることができる
Google Search や Google Assistants の表示に、自作アプリの情報を出す仕組み
まだユーザは使えないが実装は可能
確認には slice viewer を使用する
例えば右のような表示を"trip"で検索した時に表示するようなことができる
<application
...
<!-- To provide slices you must define a slice provider -->
<provider
android:authorities="com.android.example.slicecodelab"
android:name=".MySliceProvider"
android:exported="true">
</provider>
...
</application>
AndroidManifest.xml
public class MySliceProvider extends SliceProvider {
@Override
public boolean onCreateSliceProvider() {
return true;
}
public Slice onBindSlice(Uri sliceUri) {
switch(sliceUri.getPath()) {
case "/temperature":
return createTemperatureSlice(sliceUri);
}
return null;
}
@Nullable
private Slice createTemperatureSlice(Uri sliceUri) {
// ...
}
}
SliceProvider
private Slice createTemperatureSlice(Uri sliceUri) {
ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY);
// Construct the builder for the row
ListBuilder.RowBuilder temperatureRow = new ListBuilder.RowBuilder(listBuilder);
// Set title
temperatureRow.setTitle(MainActivity.getTemperatureString(getContext()));
// Add the row to the parent builder
listBuilder.addRow(temperatureRow);
// Build the slice
return listBuilder.build();
}
Sliceの生成
Kotlin らしく Android アプリを作成するためのライブラリ
より Kotlin らしい API
fragment-ktx -> fragment
collection-ktx -> collection
// In an Activity, on API 23+
val notification = getSystemService(NotificationManager::class.java)
// or all API level
val notification = ContextCompat.getSystemService(this,
NotificationManager::class.java)
val notification = systemService<NotificationManager>()
KTX を使うと次のようにかける
KTX Principles
👍 既存の機能に合わせて、上流の機能にリダイレクトする
👍 サイズ、アロケーションで問題にならない限り inline にする
👍 Kotlin 特有の機能を活用する
👎 コードゴルフ API は避ける
👎 単一 and/or 特定の利用法のための最適化は避ける
Kotlin フレンドリーな Java ライブラリを作る場合
class TextUtil {
@ExtensionFunction
@ktName("isDigitsOnly")
public static boolean isDisigtsOnlyString(@NonNull CharSequence str) {
// ...
}
}
val onlyDigits = phoneNumber.isDigitsOnly()
Java
Kotlin
Android App Bundle/Dynamic Feature Module
Android Jetpack
開発環境は大きく変わりそう
Support Library としては 28.0.0 が最後なので注意
すぐに使えそうなものも多い印象
TypeSafeArugment とか...
Kotlin 結構使われている様子
現時点で Google Play にあるアプリの 35 % が Kotlin 採用
Google I/O のサンプルコードでもかなり Kotlin が使われてた
Codelabs での学習はおすすめできる
TensorFlow
TensorFLow Hub
TensorFlow Serving
TensorFlow Extended
TensorFlow.js
ML Kit
AIY
TensorFlow dev summit が
4 月にあったばかりなので、初出の情報はあまりない
TensorFlow の再利用可能なモジュールのリポジトリ
学習済みのものを使えば学習コストが安く済む場合がある(転移学習)
利用可能なモジュールは
Image Module
Text Module (日本語が対象のものもある)
など
$ pip install "tensorflow>=1.7.0"
$ pip install tensorflow-hub
import tensorflow as tf
import tensorflow_hub as hub
# ...
# Download and use NASNet feature vector module.
module = hub.Module
"https://tfhub.dev/google/imagenet/nasnet_large/feature_vector/1")
# 62,000+ GPU hours!
features = module(my_images)
logits = tf.layers.dense(features, NUM_CLASSES)
probabilities = tf.nn.softmax(logits)
Hub にあるモジュールはそのまま使うことができる
import tensorflow as tf
import tensorflow_hub as hub
# ...
# Download and use NASNet feature vector module.
module = hub.Module
"https://tfhub.dev/google/imagenet/nasnet_large/feature_vector/1",
trainable=True, tags={"train"})
features = module(my_images)
logits = tf.layers.dense(features, NUM_CLASSES)
probabilities = tf.nn.softmax(logits)
転移学習することも可能
TensorFlow を製品レベルで運用するためのサーバとAPI
モデルサーバ
モデルの管理を行う
複数モデルを同時に扱える
モデルの動的ロード/アンロード
推論 API
gRPC
REST API
TensorFlow-base の汎用かつスケーラブルな
機械学習プラットフォーム
引用:TFX: A TensorFlow-Based Production-Scale Machine Learning Platform
TensorFlow の JavaScript 版
なぜ Javascript か?
インストールなしで使える
ブラウザで使えると、大抵の場合カメラやセンサーが使える→機械学習が活かしやすい
パフォーマンスはよい
node.js でネイティブの TensorFlow に匹敵するくらいの性能は出てた
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
// Prepare the model for training: Specify the loss and the optimizer.
model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
// Generate some synthetic data for training.
const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
// Train the model using the data.
model.fit(xs, ys).then(() => {
// Use the model to do inference on a data point the model hasn't seen before:
// Open the browser devtools to see the output
model.predict(tf.tensor2d([5], [1, 1])).print();
});
$ tensorflowjs_converter \
--input_format=tf_hub \
'https://tfhub.dev/google/imagenet/mobilenet_v1_100_224/classification/1' \
/mobilenet/web_model
TensorFlow.js 用のモデルは Hub からも取得可能
ローカルで作ったモデルもインポート出来る
$ tensorflowjs_converter --input_format keras \
path/to/my_model.h5 \
path/to/tfjs_target_dir
import tensorflowjs as tfjs
def train(...):
model = keras.models.Sequential() # for example
...
model.compile(...)
model.fit(...)
tfjs.converters.save_keras_model(model, tfjs_target_dir)
Google の ML Sdk
for iOS/Android
ベータ
Firebase 必須
モバイルフレンドリー
オンデバイスとクラウドAPI 利用の両方をサポート
オフラインでも精度が落ちるが使用はできる
Base API
すぐに使える API
機械学習に詳しくない人向け
Image labeling
Text recognition(OCR)
Face detection
Barcode scanning
Landmark detection
Smart reply (coming soon)
Custom Model
機械学習エキスパート向け
TensorFlow Lite モデル
Firebase にアップロード
アプリ側でモデルをダウンロード
ML Kit はこの API レイヤ
FirebaseVisionImage image = FirebaseVisionImage.fromBitmap(mSelectedImage);
FirebaseVisionTextDetector detector = FirebaseVision.getInstance().getVisionTextDetector();
mButton.setEnabled(false);
detector.detectInImage(image)
.addOnSuccessListener(
// ...
)
.addOnFailureListener(
// ...
);
ML Kit の Text Recognition 利用例
←ローカル版
クラウド版→
AI + DIY
教育目的のデバイス
ダンボール+RasberryPi+他の部品
Voice Kit と Vision Kit
Target に買いに行ったら売切れてた
「TensorFlow and deep learning, without a PhD」
これから始める人にはおすすめ
Google の機械学習に対する本気度が見える
キーノートの Google Duplex ・医療分野での AI 活用など
セッションetc からもTensorFlow や機械学習etc の API をどんどん使わせようとしている印象
将来的に Google 税を払って機械学習を利用するような世界になるのかも
PWA/AMP
セキュリティ関連
reCAPTURE v3
Web Authentication API
モダンな developertools
PWA
日経新聞のサイトが紹介されていた
PWA を利用して高速化に成功
PWA 版 Google Map
AMP
厳密なルールに従うことで高速化
新しく Web packaging
reCAPTURE v3 public beta
認証のチャレンジも必要なくなった
ユーザの行動からスコアリングしてロボットかどうか判断
Web Authentication API
fido aliance
生体認証の規格
将来的には指紋認証
現在は2段階認証
Workbox
Lighthouse
Polymer
lit-html
puppeteer
Chrome UX box
資料を作るにあたって見なおした動画リスト
Keynote
Developer Keynote
What's New in Android
Modern Android development: Android Jetpack, Kotlin, and more
TensorFlow for JavaScript
Android Jetpack: what’s new in Android Support Library
TensorFlow in production: TF Extended, TF Hub, and TF Serving
Android Jetpack: manage UI navigation with Navigation Controller
What's new with sign up and sign in on the web
参考にしたページ
https://codelabs.developers.google.com/
https://developer.android.com/
https://www.tensorflow.org/get_started/
https://noti.st/jakewharton/ZvuDxC/present