覚えたら書く

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

KotlinでHello World

Kotlin流行ってますし、そろそろ勉強しようかなと思っている今日この頃。とりあえずHello Worldだけやってみました。

IntelliJ IDEAでKotlinのプロジェクトを作成して以下実行しています。


■サンプルコード

Kotlinのファイル(HelloWorld.kt)を新規作成して以下を記述。
(Javaに比べてかなりシンプルなコードになっています)

package sample.app

fun main(args: Array<String>) {
    println("Hello World!")
}


■実行結果

Hello World

というわけで、Kotlinで無事にHello Worldできました。


その他

IntelliJ IDEAが無しでも以下で試すこともできます

「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型のメッセージをハンドリングできました。



関連エントリ