覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

「Deep Learning×画像解析」ライトニングトークイベント

「Deep Learning×画像解析」ライトニングトークイベント by LP-tech に参加してきました。

以下自分用のメモです。


概要

画像解析技術に特化した情報を発信している専門サイトLP-techが主催する、Deep Learning×画像解析に関するLTイベント。

  • 日時: 2017/02/28 19:30~
  • 場所: 東京大学伊藤国際学術研究センターギャラリー1
  • 参加者: エンジニア8割


オープニングトーク「LP-techについて」

島原 佑基 氏 (エルピクセル株式会社)

  • LP-tech
    • 画像処理に関する分かりやすいメディアを作りたかったので作った
    • 現在の記事数は約150
  • ライフサイエンス×画像解析 を盛り上げたい


画像のクラスタリング問題におけるDeepLearningの活用

三好 裕之 氏 (LP-tech編集長, 東京大学計数工学科4年)

  • クラスタリング
    • 特徴量から項目ごとに分類する分類器を作成する手法
    • Traning ⇒ Test
  • クラスタリング応用
    • 音声認識
      • 入力音声特徴量からクラスへのクラス分類ととらえる
    • 顔認識
    • 医用画像判別
    • 細胞認識
  • DeepLearning×クラスタリング
    • 古典的なクラスタリング手法:SVM, K-means ・・・ 一種の特徴量の設定を行わなければならない
    • DeepLeaningによる手法 ・・・ 特徴量の設定必要なし
  • Kaggle competition
    • 多種多様なデータセットが用意されている
    • DICOM画像からどれが危険かを判別するような問題のデータセットも用意されている
  • LP-academy
    • 機械学習の基本について勉強会をやっている


DeepLearningの画像定量への応用 ヒトの目を介さずに画像を分類する

望月 優輝 氏 (LP-techライター, 九州大学理学部生物学科)
 「OpenCV画像解析入門」を運営してます

  • 細胞の種類をChainerで判別してみました
    • EpH4 と HEK293 を対象に判別
  • 薬剤を細胞にかけたら形状が変わったが、客観的な数値で示したい
  • 元画像を5×5=25の格子で分割して学習用データを水増しした(対象が細胞だからできる話)
  • Chainer
    • 層の定義と層の結合
  • もっとロバストな推定を行う場合はより多くの学習データは必須


実際の研究で使えるDeepLearning×画像解析技術の紹介

柏崎 広美 氏 (LP-techライター)

  • ライフサイエンスの研究でもDeppLearningが注目されている
    • 従来手法では、、、
      • データ解析に多大な時間がかかる
      • 解析者により解析結果が変わる
  • ライフサイエンス
    • 動物実験 (in vivo) と 免疫組織化学 (in vitro)
    • 画像データを解析することによって結果が得られる
  • 例1: DeepLearning×動物の行動実験
    • わずか1分間のマウスの行動を人が解析するのにかかる時間が行動実験の障害となっている
    • 行動試験で得られた画像データをDeepLearningにより分類⇒各行動が全体の何%観察されたかが分かる
  • 例2: DeepLearning×神経活動測定
    • 14種類の薬剤を添加後の脳の神経活動を測定
    • 副作用を起こす可能性をDeepLearningを用いて予測する
  • 例3: DeepLearning×免疫組織化学
    • 免疫染色した組織画像⇒組織における免疫細胞の画像からがんの診断を行う
    • DeepLearningで解析した結果と人が主導で解析した結果を比較⇒DeepLearningでの解析結果が人の手動解析の結果が一致した


最新R-CNNの動向について

@Deep Zeon 氏 (ナレッジワークス)

  • YOKOv2
    • 検出速度 64FPS
  • 最近のR-CNN
    • YOLO,SSD, ResNet, R-FCN
    • 動向
      • より高速に、より難しい識別へ、時系列解析との融合
    • 応用
      • リアルタイム検出
      • 軽量化、高速化


DeepLearning×画像生成について

鈴木 雅大 氏 (東京大学工学系研究科 松尾研究室博士2年)
 東大でDeepLearningの講義を担当している

  • 画像を「生成」するには?
    • 新しい「ネコ」の画像を生成したい
      • データの生成源をモデル化
      • 生成モデル
  • 生成モデルでできること
    • 欠損値補完
    • ノイズ除去
    • 異常値検出
  • DeepLearning+生成モデルの代表的アプローチ
    • VAE(変分AE)系
      • 推論分布(エンコーダ)と生成分布(デコーダ)を学習する
      • 画像がぼやける
    • GAN系
      • 生成器と識別器を敵対的に学習させる
      • はっきりした画像を生成できるが、学習のパラメータ調整が難しい
  • 画像から画像の生成
    • GANを使って、ある画像から同じピクセル数の別の画像を生成
    • image-to-image Demoが流行中
  • マルチモーダルな画像生成
    • 文章から画像の生成
    • 画像と属性の双方向の生成
      • 顔から属性、属性から顔が一つのモデルで生成できる
      • 属性を変化させることで、対応する様々な顔を生成できる


DeepMedicによる医療画像解析について

@argon 氏

  • DeepMedicとは何か
    • MRIデータのセグメンテーション用CNNモデル
    • 脳の病変を検出することが目的
  • DeepMedicの特徴
    • ボクセル単位の密なセグメンテーション
    • カーネルサイズを小さく
    • 畳み込み層のみで構成されるCNN
    • 多重解像度CNN
      • 低解像度入力に対するパスを追加
    • 多様なデータに対応
      • MICCAIの2つのコンペで良好な成績をおさめる
  • 実際に動かしてみる
    • 対象データ
      • 病変のサイズは大小様々
    • Residual Network構造



関連エントリ

JSUG勉強会 2017年その2 ~ 脱Spring Boot初心者 に行ってきました

JSUG勉強会に参加してきました

以下自分用のメモ


概要

  • 開催場所 : Pivotal Japan
  • 開催日時 : 2017-02-27(月)19:00 - 21:00


Spring for Spring Boot -Spring Bootユーザーが知るべきSpringの基礎知識-

多田 真敏氏 (株式会社カサレアル、Pivotal認定講師)

https://speakerdeck.com/masatoshitada/spring-for-spring-boot

Spring Bootから始めた人に知ってほしいSpringの基礎知識を解説

  • Spring Bootは何をしているの?
    • Spring vs Spring Boot
      • Spring Bootになった際に、Configがなくなっただけで後は基本的に同じ
    • Spring Bootの価値
      • デフォルトの設定を提供してくれる。本来のアプリ開発をすぐ始められる
    • Soringにおける設定 ≒ Bean定義
  • Spring の基本!Bean定義を理解しよう
    • Bean ・・・ SpringのDIコンテナで管理しているインスタンス
    • Bean定義=このクラスのインスタンスをBeanとして扱ってとDIコンテナに教えること
    • 各種定義方法
      • (1) アノテーション+コンポーネントスキャン
        • `Configuration + @ComponentScan
        • basePacages属性を指定しなかった場合、この@ComponentScan付与されているクラスが属しているパッケージがスキャン対象となる
      • (2) メソッドによるBean定義
        • Java Config内に@Beanを付与したメソッドを作成。⇒戻り値がBeanになる
    • Spring4.3以降では@Autowiredは省略可能(コンストラクタが1個だけであれば)
    • Java Configの合体
      • @ImportでJava Configを合体できる
      • アプリが大規模になった場合に活躍する。重要。
  • Spring MVC の仕組みを理解しよう
    • Dispatecherですべてのリクエストを受け付けて、Controllerに処理振り分け
    • ViewResolver
      • ビューの論理名からビューの物理名を解決する
      • 各View技術用のViewResolver実装クラスが存在する
        • Thymeleafの場合はThymeleafViewResolver
      • Java8TimeDialectをセットすることでDate and Time APIを解釈できるようになる
    • Spring MVCが動作するにViewResolver以外にも多くのBeanが必要
      • ⇒ @EnableWebMvc
        • 正体は@Import
    • 静的ファイルの扱い
      • WebMvcConfigurerを利用してルーティング設定を追加
        • 通常はWebMvcConfigurerAdaoterクラスを利用する
    • @Configurationの正体は@Component
    • 正体は@Componentなアノテーション
      • @Controller
      • @RestController
      • @Service
      • @Repository
      • etc
    • WebApplicationInitializerでDispatcherServletの設定を記述できる
  • Auto Configurationのソースを読んでSpring Bootを理解しよう
    • 設定の自動化の正体
      • 大量のJava Configクラスがあらかじめ用意されている
      • あるクラスがクラスパス上に存在するかどうかなどの条件で、各Java Condigクラスや各@Beanメソッドを有効化/無効化している
    • メッセージ
      • プロパティファイル名はデフォルトは「messages.properties」
    • 静的ファイル
      • クラスパス直下のstaticフォルダ等が指定されている
    • Bean定義カスタマイズ例
      • (1) application.properties
        • @COnfigurationProperiesなクラス⇒Bean定義で使われる
      • (2) 自分でBean定義する
      • (3) Customizerを利用する
        • XxxCustomizerをBean定義すれば、Auto ConfigurationクラスがDIコンテナから拾ってくれる
  • まとめ
    • 脱Spring Boot初心者となるには、Springの基礎知識が大事
      • Spring Bootを使わずにアプリを作り、Auto Configurationのソースを読みながらアプリをSpring Boot化していこう


実例で学ぶ、明日から使えるSpring Boot Tips

槙 俊明 (Pivotal)

  • Spring Boot is
    • Opinionated Framework on Spring Ecosystem
    • できるだけSpring Boot Wayに乗るべき(むりやり既存のやり方を持ち込むとひずみが生じる)
  • Error画面
    • 以下を用意するだけで良い
      • src/main/resources/static/error/403.html, 404.html, 40x.html, 500.html, 50x.html
    • 動的指定したい場合は以下
      • src/main/resources/templates/error/403., 404., 40x., 500., 50x.
    • application-default.properties
      • server.error.include-stacktrace=always を指定すると ${trace} にStackTraceが入る
    • @ControllerAdviceを指定して、@ExceptionHandlerを使うと全Controllerに適用される
  • profileの指定方法
    • アプリの引数
    • システムプロパティ
    • 環境変数
  • Spring Data RESTによるREST API
    • Repository -> REST API
    • 永続化層に対する操作に対するREST API(HTTP操作)を自動的に提供してくれる
    • Controllerすら書かなくてよくなる
    • コード量が大幅に減る
    • FooRepository#finadName -> /foos/search/findByName?name={name}
    • @RestResource(exported = false) <- 外部に公開したくないエンドポイントの場合
    • その他
      • PagingAndSortingRepository
    • RepositoryEventHandler
      • Repository操作に対するイベントハンドラ。業務ロジックなどを書くことができる
    • トランザクション境界
      • 普通のアプリではServiceでは、@Transactional
      • Spring Data RESTでは、AOPで強引にトランザクション境界を引き延ばせる。が、もしかしたらバッドノウハウかも。
  • CSRF対策
    • Spring Securityを導入するだけでCSRF対策される
    • Ajax / SPA の場合は?
      • CookieCsrdTokenRepositoryを使用する(デフォルトはHttpSessionCsrfTokenRepository)
      • AngularJS
      • Axios
        • PromiseベースのHTTPクライアント
        • X-XSRF-TOKENという名前のCookieが入っていたらHTTPリクエス
  • @EnableOAuth2Sso
    • token = Authoraization Code
    • PrincialExtractor
      • ユーザ情報の作り方などをカスタマイズできる
    • GitHub以外でもOK
      • Authoraization Server ・・・ @EnableAuthoraizationServer
      • アカウントを一元管理できる
  • @ConditionalOnProperty
    • 一つのinterfaceに対して複数の実装を使い分ける方法の一つ
    • 設定の内容に応じて実装が切り替えられる
  • @COnfigurationProperties
    • TypeSafeなプロパティ
    • ConfigurationProcessorを使ってメタ情報も吐くようにしたほうが良い
  • Spring Boot Acturator
    • 1.5からSpring Actuatorでデフォルトでセキュリティ認可が行われる(ROLE_ACTUATOR)



関連エントリ

MBassador - サブクラスのメッセージ受信時の動き

MBassadorを用いてメッセージのハンドリングを行う場合のメッセージのサブクラスに対する動きを確認します。


本エントリでは、MessageObj とその子クラスの SubMessageObj を定義しました。これらをEventBusにpublishします。

■メッセージクラスの定義

public class MessageObj {

    protected final String rawMsg;

    public MessageObj(String rawMsg) {
        this.rawMsg = rawMsg;
    }

    String message() {
        return "MessageObj -> " + rawMsg;
    }
}
public class SubMessageObj extends MessageObj {

    public SubMessageObj(String rawMsg) {
        super(rawMsg);
    }

    @Override
    public String message() {
        return "MessageImpl -> " + rawMsg;
    }
}


デフォルトでのサブクラスのメッセージ受信時の動き

■Handlerの定義

MessageObjを引数に取るhandle1とSubMessageObjを引数に取るhandle2を定義しました

import net.engio.mbassy.listener.Handler;

class MessageObjListener {

    @Handler
    public void handle1(MessageObj msg){
        System.out.println("handle [MessageObj]: " + msg.message());
    }

    @Handler
    public void handle2(SubMessageObj msg){
        System.out.println("handle [SubMessageObj]: " + msg.message());
    }
}


■EventBusを作成してメッセージ送信

EventBusに上で定義したハンドラをセットしてMessageObjSubMessageObjのインスタンスを送信し動きを確認します

import net.engio.mbassy.bus.MBassador;


public class Main {

    public static void main(String[] args) {
        MBassador<Object> bus = new MBassador<>();
        bus.subscribe(new MessageObjListener());

        bus.publishAsync(new MessageObj("Hello World! - 1"));
        bus.publishAsync(new MessageObj("Hello World! - 2"));
        bus.publishAsync(new SubMessageObj("Hello World! - 1000"));
        bus.publishAsync(new SubMessageObj("Hello World! - 2000"));

        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("\n>>> App end");
    }
}


■実行結果

handle [MessageObj]: MessageObj -> Hello World! - 1
handle [MessageObj]: MessageObj -> Hello World! - 2
handle [SubMessageObj]: SubMessageObj -> Hello World! - 1000
handle [MessageObj]: SubMessageObj -> Hello World! - 1000
handle [SubMessageObj]: SubMessageObj -> Hello World! - 2000
handle [MessageObj]: SubMessageObj -> Hello World! - 2000

>>> App end

MessageObjListener#handle1の引数はMessageObjですが、MessageObjおよびその子クラスのSubMessageObjも受け取っていることが分かります。


サブクラスのメッセージ受信しないようにする

場合によってはサブクラスのメッセージを受信したくない場合もあります。その場合は@HandlerアノテーションのrejectSubtypesパラメータを利用します

■Handlerの定義

ハンドラとして扱うメソッドに@Handlerを付与するとともにrejectSubtypesパラメータにtrueを指定します。これで引数のサブクラスのメッセージが受信しなくなります。

import net.engio.mbassy.listener.Handler;

class MessageObjListener {

    @Handler(rejectSubtypes = true)
    public void handle1(MessageObj msg){
        System.out.println("handle [MessageObj]: " + msg.message());
    }

    @Handler
    public void handle2(SubMessageObj msg){
        System.out.println("handle [SubMessageObj]: " + msg.message());
    }
}


■EventBusを作成してメッセージ送信

EventBusに上で定義したハンドラをセットしてMessageObjSubMessageObjのインスタンスを送信し動きを確認します

import net.engio.mbassy.bus.MBassador;


public class Main {

    public static void main(String[] args) {
        MBassador<Object> bus = new MBassador<>();
        bus.subscribe(new MessageObjListener());

        bus.publishAsync(new MessageObj("Hello World! - 1"));
        bus.publishAsync(new MessageObj("Hello World! - 2"));
        bus.publishAsync(new SubMessageObj("Hello World! - 1000"));
        bus.publishAsync(new SubMessageObj("Hello World! - 2000"));

        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("\n>>> App end");
    }
}


■実行結果

handle [MessageObj]: MessageObj -> Hello World! - 1
handle [MessageObj]: MessageObj -> Hello World! - 2
handle [SubMessageObj]: SubMessageObj -> Hello World! - 1000
handle [SubMessageObj]: SubMessageObj -> Hello World! - 2000

>>> App end

MessageObjListener#handle1MessageObjのメッセージだけ受け取り、その子クラスのSubMessageObjのメッセージを受信しなくなっていることが分かります。



関連エントリ

MBassador - 異なる型のメッセージを1つのHandlerでハンドリングする

MBassadorを用いてメッセージのハンドリングを行う場合、通常メッセージの型ごとにハンドラを用意することになりますが、
@Envelopedアノテーションを使用することで複数の異なる型のメッセージを1つのハンドラでハンドリグすることが可能となります。

以下実行サンプルです


■Handlerの定義

ハンドラとして扱うメソッドに@Handlerを付与するとともに、@Envelopedアノテーションを付与します。
そしてこの@Envelopedアノテーションのmessagesパラメータに、このハンドラで取り扱うメッセージの型を指定します。
さらにハンドラとするメソッドの引数の型をMessageEnvelopeにします。

import net.engio.mbassy.listener.Enveloped;
import net.engio.mbassy.listener.Handler;
import net.engio.mbassy.subscription.MessageEnvelope;

import java.time.LocalDate;

class SimpleMsgListener {

    @Handler
    @Enveloped(messages = {Integer.class, String.class, LocalDate.class})
    public void handle(MessageEnvelope envelope) {
        System.out.println("type = " + envelope.getMessage().getClass() + ", msg = " + envelope.getMessage());
    }
}


■EventBusを作成してメッセージ送信

EventBusに上で定義したハンドラをセットしてメッセージを送信し動きを確認します

import net.engio.mbassy.bus.MBassador;

import java.time.LocalDate;

public class SampleLauncher {

    public static void main(String[] args) {
        System.out.println(">>> App start");

        MBassador eventBus = new MBassador();
        SimpleMsgListener listener = new SimpleMsgListener();
        eventBus.subscribe(listener);    // ハンドラの登録

        // StringとintとLocalDateのメッセージ送信
        for (int i = 0; i < 3; i++) {
            eventBus.publishAsync(i);
            eventBus.publishAsync("Hello World" + i);
            eventBus.publishAsync(LocalDate.of(2017, 2, i + 10));
        }

        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("\n>>> App end");
    }
}

■実行結果

>>> App start
type = class java.lang.Integer, msg = 0
type = class java.lang.String, msg = Hello World0
type = class java.time.LocalDate, msg = 2017-02-10
type = class java.lang.Integer, msg = 1
type = class java.lang.String, msg = Hello World1
type = class java.time.LocalDate, msg = 2017-02-11
type = class java.lang.String, msg = Hello World2
type = class java.time.LocalDate, msg = 2017-02-12
type = class java.lang.Integer, msg = 2

>>> App end

無事に、一つのハンドラでString型、int型、LocalDate型のメッセージをハンドリングできました。



関連エントリ

TensorFlow User Group #3 行ってきたよ

TensorFlow User Group #3に行ってきました。

今回は開催回数が奇数回だったので、TensorFlowの利用事例の発表がメインでした。

以下自分用のメモです


概要

  • 場所: Google ジャパン
  • 日時: 2017/2/22 19:00~


Retty流 「2200万ユーザさんを支える機械学習基盤」の作り方

Retty株式会社 樽石将人 氏

https://speakerdeck.com/taru0216/tfug-number-3-rettyliu-2200mo-yuzasanwozhi-eruji-jie-xue-xi-ji-pan-falsezuo-rifang-dockerbian

  • Rettyのサービス
    • 「人から探せる」グルメサービスを運営
    • 「この人のおすすめは自分に合ってそう」というのが直感的にわかるユーザ体験を作っている
  • グルメ情報に関する信頼性等向上の取り組み
    • 実名・顔写真公開による投稿
    • 投稿内容をリアルな友達・知人に見てもらう
    • 二次著作の許諾
  • Rettyのデータの種類と規模
    • 口コミ
    • 画像
    • 人の行動・ソーシャルグラフ
    • 店舗情報
  • Retty機械学習マシン
    • GPU付自作PCを全自動ネットインストールでセットアップ
    • ブラウザでも開発できます
    • Kubernets(Docker) + juju + MAAS
    • すべてのDockerイメージはコアDocker(retty2-runtime-core)から継承
    • KubernetsのDaemon Setで全マシンにデプロイ
    • Kubernetsはjuju & MAASでネット自動インストール


DeepLearningの自然言語処理への応用事例 -文字単位CNNによる口コミ分類-

Retty株式会社 氏原淳志 氏

  • 日本語の自然言語の処理の大きな壁。単語の切れ目がさっぱりわからない
    • 分かち書き(形態素解析)
    • これには辞書が必要。未知の単語には対応できない。
  • 自然言語処理でのDeep Learning
    • 画像は1pixel単位でCNNにかけてる。なら文字列も単語単位ではなく文字単位にCNNにかける
    • 文章を文字単位分割⇒UNICODEに変換⇒それぞれの文字N次元ベクトル⇒CNN
  • デートに使える店の口コミ
    • 焼き鳥店の口コミでも内容によって分類結果が大きく異なった
  • 教師作りのソルジャーは必要


SENSYにおける深層学習活用事例とTensorFlowの悩み相談

カラフル・ボード株式会社 武部雄一 氏

  • SENSY
    • SENSY=パーソナルAI
    • SENSYの位置づけ=特化型人工知能
  • SENSYを応用したtoBソリューション
    • AI技術提供
      • toCサービスで語りにした成果物を応用して企業へ提供・導入
  • SENSYにおける機械学習/深層学習の活用事例
    • 画像に対するカテゴリや雰囲気のタグ付け
    • 画像背景の透過
    • コーディネートの自動作成
  • 事例
    • 広告CVR予測 with TensorFlow
      • マーチャントとパートナーの特徴量作成にオートエンコーダーを利用。RBFNを用いてCVRの予測回帰モデルを作成
      • 今回の対象ではシグモイド関数を利用
    • ファッションアイテムの推薦最適化
      • ヒートマップは、画像特徴量をt-SNEで2次元に落とし込み、各画像の推定スコアを色で表現
      • CNNはChainer
      • 可視化されていると顧客との共通認識を持ちやすい
      • 今後、分散化による速度向上を目的にTensorFlow / Cloud ML に変えていく予定
  • Chainerで作った既存プロジェクト、TensorFlowでもやってみたいとは思うが各フレームワークの設計思想が異なりモデルの変換は絶望的
  • Chainerは実装しながらモデルを創れるのでミスを発見しやすい。比べてTensorFlowはミスや想定外箇所を特定しづらい
  • TensorFLowは小一時間で基本構成要素を理解できる


NNで広告配信のユーザー最適化をやってみた

GMOインターネット次世代システム研究室 勝田隼一郎 氏

  • AkaNe
    • 広告配信のルール⇒学習Model
    • Model候補
      • オーディエンス拡張
        • 特徴量の空間でclickするUserに近いclusterを見つけ、拡張Userとして配信ターゲットにする
        • 今回はこれは不採用
      • MLP
        • 配信履歴よりclickしたUserしてないUserに分類
        • これを教師データとしてMLP(多層パーセプトロン)で学習を行う
    • Embedding
      • スパースなデータを圧縮(Embedding)する必要があった
      • 大量データを扱うため、Apache SparkのMLibのALSを用いた
  • 実配信によるABテストで従来に比べてCTRが2倍に向上したことを確認できた



関連エントリ