LSTMの文の理解能力

English

LSTMの文の理解能力について、個人的に面白いと思ったので紹介したいと思います。今回使用した学習済みモデルはこちらの記事で紹介しています。

以下の動画は2つの質問を学習済みモデルにしたものです。A(上の質問)は課金に関する質問で、B(下の質問)はアカウント消失に関する質問です。両方は2つのカテゴリー(“課金”と”アカウント”)が混在する質問で、前後のカテゴリーを入れ替えただけのテキストです。

Aの文

この前はアカウントの引き継ぎの問題解決ありがとうございました。今回の不具合はアイテムを購入したのに反映されません。このようなことが続くのは悲しいです。

Bの文

この前はアイテム購入の問題解決ありがとうございました。今回の不具合はアカウントの引き継ぎができない問題です。このようなことが続くのは悲しいです。

これらは先に説明した通り、前後のカテゴリーを入れ替えて意味が逆になるようにしています。このモデルでは両方の質問に対してカテゴリーの分類に成功しています。動画の下の”predictions”の部分が各カテゴリーのスコア(確信度と呼ぶことにします)になっていて、この値が高いカテゴリーほどそのカテゴリーであるということを確信していることになります。

確信度は0はじまりのカンマ区切りで、1列は”その他”、2列目は”アカウント”、3列目は”課金”のカテゴリーであることを表しています。Aのテキストの確信度は以下の通りです。3列目が一番高い確信度になっていることがわかります。つまり課金のカテゴリーに分類していることがわかります。

Aの文

predictions
etc, other, account, payment
0.0038606818, 0.036638796, 0.04247639, 0.46222764

Bのテキストの確信度は以下の通りです。こちらは2列が一番高い確信度が高いことからアカウントのカテゴリーに分類していることがわかります。

Bの文

predictions
etc, other, account, payment
0.0007114554, 0.04938373, 0.72704375, 0.0038164733

これらの一番確信度が高いカテゴリーは、他の確信度より大きな差をつけています。この結果から、LSTMが単純に単語からカテゴリーを分類するのではなく、文からカテゴリーを分類できているのではないかと思います。

今後検証したいこと

  • サンプル数を増やす
  • LSTMの代わりに1-D convolutional networkを使う
  • 学習済みのword embeddingを使う

CoreMLを使ったGenerative Adversarial NetworkのiOS Appを作る

English page

iOS上でCoreMLを使って手書き文字を生成するアプリを作成しました

手書き文字の生成からアプリの公開までをまとめておきたいと思います。

使ったソフトウェア

  • Xcode 9.2 (9C40b)
  • Docker 17.09.1-ce
  • TensorFlow docker imagesha256:1bb38d61d261e5c9230a1e60b5d200088eb03014fdb35a91859fa55ea0d2c4d5, https://hub.docker.com/r/tensorflow/tensorflow
  • TensorFlow 1.2.1
  • Keras 2.0.6
  • coremltools 0.7

手書き文字画像の生成からiOS appのリリースまで

図1は手書き文字画像の生成からiOS appのリリースまでの手順を表しています。

the flow of distributing an app
図1. iOS appリリースまでの手順

DockerのインストールしてTensorFlowとKerasが動作するJupyter Notebookを用意する

Kerasモデルを作成するためにDockerをインストールします。

以下のコマンドを実行します。

$ docker run -d --name notebook tensorflow/tensorflow:latest

KerasとCoreML converterをインストールする

$ docker exec -it notebook /bin/bash
$ pip install -U keras
$ pip install -U coremltools

Jupyter Notebookにアクセスできることを確認する

Jupyter NotebookにアクセスするためのURLを取得します。

$ docker logs notebook
# 以下のようなトークンがついたURLが表示されると思います
#
#    Copy/paste this URL into your browser when you connect for the first time,
#    to login with a token:
#        http://localhost:8888/?token=ecf1a2471670eb6863195ab530d6ac1d5cc27511faca0afe

上記のURLをブラウザで開くとアクセスできると思います。
これでKerasのコードを書けるようになります。

Kerasモデルを作成する

Jupyter Notebookに新しいノートを追加してGANモデルのコードを書きます。GANのコードはこちらを参考にしました。このコードをコピーしてcellに貼り付けます。モデルをディレクトリにセーブするために以下のようにコードを追加します。

if __name__ == '__main__':
    gan = GAN()
    gan.train(epochs=30000, batch_size=32, save_interval=200)
    gan.discriminator.save('./discriminator.h5') // discriminatorモデルを保存するディレクトリを指定します
    gan.generator.save('./generator.h5') // generatorモデルを保存するディレクトリを指定します

あとはcellを実行します。MacBook Pro 2016で実行した感じだと25分ほどかかりました。

このcellを実行すると学習済みモデルが指定のディレクトリに”.h5″のファイルが保存されます。

KerasモデルをCoreMLモデルに変換する

$ coremlconverter --srcModelPath ./keras_model.h5 --dstModelPath ./coreml_model.mlmodel --inputNames gunInput --outputNames ganOutput

このコマンドでKerasのモデルをCoreMLのモデルにコンバートします。コンバートが完了すると”.mlmodel”のCoreMLモデルファイルが生成されます。

手書き文字画像を生成するアプリを作成する

手書き文字画像を表示するにはWeb application、iOS、Androidや単純にJupyter Notebookを使う方法がありますが、iOSを触ってみたかったのでiOSにしました。

アプリを作成する

作成したアプリのソースコードはこちらで公開しています。

図2はアプリのスクリーンショットを示しています。


図2. アプリ (GANs generator)のスクリーンショット

このアプリはCoreMLを使用してKerasのモデルから28 x 28の手書き文字画像を生成します。手書き文字画像はUIKitを使用して表示します。また、手書き文字画像を再生成するボタンがあります。

手書き文字画像を生成する

最初にKerasモデルからコンバートしたCoreMLモデルをXcodeのプロジェクトにインポートします。図3のようになっていると思います。


図3. CoreMLモデルのプロパティ

Xcodeにモデルをインポートすると、モデルのクラスが自動的に生成されます。このクラスは手書き文字画像を生成するpredictionメソッドが実装されています。そして、predictionメソッドの第1引数にKerasモデルのinputが指定されます。第1引数のラベルにはCoreML converterの--inputNamesで指定した値が使用されます。この場合だとクラスのpredictionメソッドの第一引数のラベルをganInput、出力された手書き文字画像をganOutputとして定義しています。この定義は図3のように”.mlmodel”ファイルのModel Evaluation ParametersInputsOutputsで確認することができます。

// Create a gan instance
var model = gan()
// Generate a handwritten image
var output = model.prediction()

// render hand-written image
let HIGHT = 27
let WIDTH = 27

for i in 0...HIGHT {
  for j in 0...WIDTH {
    //create the path
    let plusPath = UIBezierPath()

    //set the path's line width to the height of the stroke
    plusPath.lineWidth = Constants.plusLineWidth

    //move the initial point of the path
    //to the start of the horizontal stroke
    plusPath.move(to: CGPoint(
      x: CGFloat(j * 10),
      y: CGFloat(i * 10) + Constants.plusLineWidth / 2
    ))

    //add a point to the path at the end of the stroke
    plusPath.addLine(to: CGPoint(
      x: CGFloat((j * 10) + 10),
      y: CGFloat(i * 10) + Constants.plusLineWidth / 2
    ))

    //set the stroke color
    let index: [NSNumber] = [0 as NSNumber, i as NSNumber, j as NSNumber]
    UIColor(white: CGFloat(truncating: out.gan_out[index]), alpha: CGFloat(1)).setStroke()

    //draw the stroke
    plusPath.stroke()
  }
}

このプロジェクトをXcodeで開いてシミュレーターで確認することができます。

Apple Developer Programに登録する

アプリの動作を確認したら、App Storeにこのアプリを公開します。もし、Apple Developer Programに登録してなけらば、こちらで登録を済ませます。アプリをApp Storeに公開するにはApple Developer Programの登録が必要です。

App Storeに登録する

詳しくは公式ドキュメントを参照してください。

  1. Archiving
    Product > Archive

  2. Validating
    archivingが完了するとArchive organizerValidateができるようになるのでApp Storeにアップロードする前に実行して、アプリに問題がないかチェックしておきます。

  3. App Storeにアプリをアップロードする
    Upload to App Storeをクリックします

アプリを公開する

詳しくは公式ドキュメントを参照してください。

  1. アプリをiTunes connectに登録する
  2. アプリのアイコンとプレビュー、スクリーンショットを追加する
  3. App Reviewに出す
  4. アプリをリリースする

Create a Generative Adversarial Network iOS App with CoreML

I created the app that generates a handwritten image with CoreML on iOS.

I’m going to explain the process to release this app from beginning to end.

The software versions

  • Xcode 9.2 (9C40b)
  • Docker 17.09.1-ce
  • TensorFlow docker imagesha256:1bb38d61d261e5c9230a1e60b5d200088eb03014fdb35a91859fa55ea0d2c4d5, https://hub.docker.com/r/tensorflow/tensorflow
  • TensorFlow 1.2.1
  • Keras 2.0.6
  • coremltools 0.7

The process to make handwritten image generator app on iOS and submit it to the App Store

As shown in figure 1, it illustrates the path of distributing this app through App Store.

  1. Create a GAN (Generative Adversarial Network) model on Keras
  2. Convert a Keras GAN model to CoreML model
  3. Create an app to show handwritten images generated by the CoreML model
  4. Distribute the app

the flow of distributing an app
Figure 1. The path of distributing this app through App Store

Install Docker and run Jupyter Notebook that includes TensorFlow and Keras

At first, To create a Keras model, we have to install Docker.

Install Docker

On Mac, get it in this page at the Stable channel and just install it.

Run Jupiter Notebook with TensorFlow

Fortunately, there is the Docker image that includes TensorFlow.

Just type this command:

$ docker run -d --name notebook tensorflow/tensorflow:latest

Install Keras and CoreML converter

$ docker exec -it notebook /bin/bash
$ pip install -U keras
$ pip install -U coremltools

Check that you can access the Jupyter Notebook

Before access it, you need to get an access token.

$ docker logs notebook
# You will find an access token like this:
#
#    Copy/paste this URL into your browser when you connect for the first time,
#    to login with a token:
#        http://localhost:8888/?token=ecf1a2471670eb6863195ab530d6ac1d5cc27511faca0afe

Copy the URL with an access token and access on your browser.

Now it’s done! You come can execute Keras code!

Make a Keras model

Add a new note to Jupyter Notebook and write a GAN model. I referred to this source code. Copy this code and paste to your Jupyter Notebook’s cell and add the code below. It will save a model in a directory.

if __name__ == '__main__':
    gan = GAN()
    gan.train(epochs=30000, batch_size=32, save_interval=200)
    gan.discriminator.save('./discriminator.h5') // Specify the directory saved the discriminator model
    gan.generator.save('./generator.h5') // Specify the directory saved the generator model

Then just run the cell. It took time about for 25 minutes on my MacBook Pro 2016 to training this model.

Keras create a learned model in the directory where executed the cell. It is followed by “.h5”.

Convert a Keras model to CoreML model

$ coremlconverter --srcModelPath ./keras_model.h5 --dstModelPath ./coreml_model.mlmodel --inputNames gunInput --outputNames ganOutput

This command uses TensorFlow in the background and converts to a CoreML model. After the converting, it makes a CoreML model is followed by .mlmodel in the specified directory. This file is a CoreML converted model from Keras model.

Create an app to show handwritten images

There are some ways to create an app that draws a handwritten image. For instance, as a web application or mobile application. This time, I created an app for iOS.

Create the app

Here is the source code for the app:
https://github.com/yanak/gangen/blob/master/Gangen/HandwrittenImage.swift

figure 2 is the app’s screenshot.


Figure 2. The GANs generator app’s screenshot

This app generates a 28 x 28 handwritten image using the CoreML model converted from Keras, and that renders the image by UIKit. There is the regenerate button that regenerates a handwritten image.

Generate a handwritten image

First, import the CoreML model converted from the Keras model to Xcode project directory. It shows like figure 3:


Figure 3. the CoreML model properties

After Xcode imports, a model, the class of a model is automatically generated by Xcode. this class has the prediction method and it specifies Keras model’s input as the first argument. The first argument’s label uses the name of the CoreML converter’s --inputName option value. In this case, The class defines the label of prediction as ganInput and a generated handwritten image’s shape as ganOutput. You can see its definitions in the Model Evaluation Parameters in the CoreML model(see figure 3.)

// Create a gan instance
var model = gan()
// Generate a handwritten image
var output = model.prediction()

// render hand-written image
let HIGHT = 27
let WIDTH = 27

for i in 0...HIGHT {
  for j in 0...WIDTH {
    //create the path
    let plusPath = UIBezierPath()

    //set the path's line width to the height of the stroke
    plusPath.lineWidth = Constants.plusLineWidth

    //move the initial point of the path
    //to the start of the horizontal stroke
    plusPath.move(to: CGPoint(
      x: CGFloat(j * 10),
      y: CGFloat(i * 10) + Constants.plusLineWidth / 2
    ))

    //add a point to the path at the end of the stroke
    plusPath.addLine(to: CGPoint(
      x: CGFloat((j * 10) + 10),
      y: CGFloat(i * 10) + Constants.plusLineWidth / 2
    ))

    //set the stroke color
    let index: [NSNumber] = [0 as NSNumber, i as NSNumber, j as NSNumber]
    UIColor(white: CGFloat(truncating: out.gan_out[index]), alpha: CGFloat(1)).setStroke()

    //draw the stroke
    plusPath.stroke()
  }
}

Open this project, you can check to run it in a simulator like this:

Enroll Apple Developer Program

After check running the app, submit it to the App Store! If you don’t enroll Apple Developer Program yet, you need to do it in here because it needs to submit the app to the App Store.

Submit to the App Store

In detail, see Submitting Your Apps

  1. Archiving
    To archive, on Xcode, Product > Archive

  2. Validating
    Xcode shows the archived app in the Archives organizer. Validate an archived app before uploading to App Store.

  3. Upload to iTunes connect
    Click Upload to App Store

Publish app

In detail, see iTunes Connect Developer Help page.

  1. Add an app in iTunes Connect
  2. Add app icon, app previews and screenshots.
  3. Submit an app to App Review
  4. Release an app
    

I implemented GANs

I implemented GANs(Generative Adversarial Networks) because I want to learn about GANs with TensorFlow.

I referred to here.

And this is my code implemented GANs. This code almost same what I referred.

My GANs repeatedly learn with MNIST handwritten image 100k times.

These are the learned images 0, 1k, 50k, 100k steps.

0 step


The 0 step image is just noise.

1k steps


The 1k steps image is just noise yet.

5k steps


The 5k steps image look like a handwritten image, but it is a little bit noisy.

50k and 100k steps


50k steps


100k steps

The 50k and 100k steps image pretty look like a handwritten image.

Above implementation is the vanilla GAN. So by using extended GAN like DCGAN would be able to increase the precision of generated handwritten image. And I’ll try to use some other training data.

However, I am going to implement GAN on iOS with CoreML before I use DCGAN and other training images.