Itsukaraの日記

最新IT技術を勉強・実践中。最近はDeep Learningに注力。

DL使った線画自動着色が凄すぎる!

下記の記事が、「はてなブックマーク」で第1位になっていたので、お試しサイトで試そうと思ったら、アクセスが非常に多いらしく、なかなか結果が出ないので、自分のPCにgit cloneして試してみました。

qiita.com


ただ、残念ながら、当方のPCではGPUメモリが足りずエラーとなり、小さな絵しか出ないため、ソースのhtmlコードを少し弄って1.5倍に拡大して表示しました。素材は、ネット上のフリー素材と自作画を使いました。

イチゴケーキ

ヒント無

ヒント無しだと、色使いが暗く、金属っぽいケーキになってしまいました。
f:id:Itsukara:20170129044238p:plain

ヒント有

白い部分を少しだけ色付けしてヒントを与えたら、結構それらしくなりました。ちなみに、白い部分も、白で塗ってヒントを与えています。左側の線画をよ~く見ると、少しだけ色がついている部分があることが分かると思います。たったこれだけのヒントを与えただけで、それらしい絵になりました。皿の縁は、特に何もしていませんが、それらしい色になっています。
f:id:Itsukara:20170129044521p:plain

カレー

ヒント無

ヒント無しだと、色使いが暗く、やはり今一つですね。
f:id:Itsukara:20170129044958p:plain

ヒント有

これも、少しだけヒントを与えると、カレーっぽくなりました。こちらは、白い部分を結構沢山白く塗ってます。
f:id:Itsukara:20170129045156p:plain

ハンバーガー

ヒント無

やはり、ヒント無しだと、色使いが暗くなってしまいますね。
f:id:Itsukara:20170129045312p:plain

ヒント有

これも、ちょっとヒントを与えただけで、それらしくなりました。
f:id:Itsukara:20170129045423p:plain

吉野山(奈良)

女の人が2人、着物を着て山里を歩いているようですが、特にヒント無しで、それらしい絵になりました。
f:id:Itsukara:20170129052557p:plain

へのへのもへじ

下手な絵を描いて試してみましたが、なんか、それらしくなりました。顔っぽい形があると、肌色に塗られるようです。
f:id:Itsukara:20170129050914p:plain

「初日の出」っぽい下手な絵

ヒント無

なぜか、丸い部分は太陽っぽい色になっていますね。
f:id:Itsukara:20170129051329p:plain

ヒント有

5点塗っただけで、結構変わりました。ただ、よく考えたら、山の前面は、太陽の陰になっていて暗いはずなので、ヒント無しの方が正解ですね...
f:id:Itsukara:20170129051759p:plain

蛍狩り

次の記事に記載のように、CPUのみで動作可能になるようソースコードを修正し、大きな絵が表示されるようになりましたので、参考までに載せておきます。
f:id:Itsukara:20170129133505p:plain

実験用素材

今回の塗り絵素材は、Webで無料と書かれたものを使いました。その中で、下記サイトは、「MY介護の広場」の文字を削らずにご使用すれば無料とのことであり、良さそうなる理恵素材が多数あるので、ちょっと試すのには良さそうです。ただ、論文などで多数の絵を使うようでしたら、サイト運用会社と一度会話しておいた方が良いと思います。明治安田生命グループ提供されている「MY介護の広場 」様、ありがとうございました。
www.my-kaigo.com

ちなみに、上記に載っているのはPDFファイルです。これをダウンロードし、PDF-Viewerで表示し、PNGでエクスポートすれば、paintschainerで読み込めます。あるいは、Acrobatで表示し、Snipping Toolでキャプチャーし、ファイルに保管するのも良いと思います。



最近、PowerShellで遊んでます

会社でPowerShellを使う機会があり少し勉強しました。ちょっとWebを探しただけで結構いろいろな記事が見つかるので、本は購入せずに使うことができました。

最初の一歩

当面必要な目的に合わせ最初に読んだのが下記です。

正規表現を使ったファイル名変更が1行で書け、とても便利と感じました。

Get-ChildItem <対象ファイル> | Rename-Item -NewName { $_.Name -replace '旧文字列','新文字列' }

言語仕様などの基本理解

次に読んだのは下記で、PowerShellの基本を理解することができました。

最初は、PowerShellの文法にかなり違和感を感じました。
例えば、関数呼び出しを「()」や「,」無しで書いたり:

function f($p, $a) {
  return "$p -- $a"
}

f "pen" "apple"
# f("pen", "apple")は、fの第1引数の値が("pen", "apple")になる。
# f "pen", "apple" も、fの第1引数の値が("pen", "apple")になる。

比較演算子を「-eq」「-ne」などと書いたり:

if ($p -eq "pen") {
  echo "apple"
}

などです。しかし、PowerShellがコマンド実行系と考えると、コマンド引数は空白で区切るのが基本であり、「-eq」はコマンドに対するオプションと考えられ、「if ($p -eq "pen")」といった記述が自然に感じられるようになりました。

また、PowerShellのパイプでは文字列ではなくオブジェクトが渡されることも、便利と感じました。つまり、上でファイル名変更スクリプトを記載しましたが、対象ファイルとして「C:\TEMP\WORK」といったパスを指定しても、「Rename-Item」に渡されるのはオブジェクトで、「$_.name」は渡されたオブジェクトのファイル名(フルパスではない)を示すので、ファイルパスの文字列にパターンにマッチした文字列があっても、何の問題も起きません。

また、渡ってきたオブジェクトから、ファイル名以外にも色々な情報を取り出せます。例えば、下記のように書けば、"this"と"pen"と"apple"を含む全てのファイルに対して、その名前、長さ(バイト数)、フルパスを表示することができます。

PS C:\TEMP> Get-ChildItem . | Where-Object {$_.name -match ".*this.*pen.*.apple" } | Select-Object -Property name,length,fullname

Name                                  Length FullName                                              
----                                  ------ --------                                              
this-is-a-pen-apple.txt                   25 C:\TEMP\this-is-a-pen-apple.txt              
this-is-a-pen-pineapple-apple-pen.txt     39 C:\TEMP\this-is-a-pen-pineapple-apple-pen.txt
this-is-a-pen-pineapple-apple.txt         33 C:\TEMP\this-is-a-pen-pineapple-apple.txt    

開発環境がインストール済み

PowerShellの実行環境および開発環境は、殆どのWindowsには初めからこれがインストールされています。仕事上では、これが一番ありがたい点だったりします。下記(Wikipedia)を見ると、Windows XPWindows Server 2003などのレガシーでも使えるようです。ただ、PowerShellのバージョンは、Windowsのバージョンによって異なり、古いPowerShellでは使えない機能があったりするので、要注意ですね。

開発環境は、PowerShell ISE (Integrated Scripting Environment)というものがあり、PowerShellやISEで検索すると、すぐに見つかると思います。開発環境では、コマンドやオプションを途中まで入力してTABキーを押すと、コンプリーションしてくれたり候補を表示してくれたりするので、コマンド名やオプション名をうろ覚えでも簡単にプログラムを開発できます。デバッガもついており、Breakpointも設定できます。

GUIも使える

実は、GUIも使えるようで、試しにプログラムを作ってみました。参考にしたサイトは下記です。ちなみに、PowerShellからGUIを使うには各コンポーネントの座標位置までゴリゴリ細かく記述する方法(下記1つ目)と、HTMLのように構造を記述しレイアウトはコンテナに任せるやり方(下記2つ目)とあり、2つ目の方が良いと感じました。


下記は、$src_dirにあるファイルのうち、特定のパターンにマッチするファイルを、$dst_dirにコピーするスクリプトです。GUIでは、パターン中の2つの部分をlistboxで選択するようになっています。これらを選択したうえで、"Copy Files"ボタンを押すと、ファイルがコピーされます。

$ErrorActionPreference = "stop"
Set-PSDebug -Strict
$src_dir = "C:\TEMP\src"
$dst_dir = "C:\TEMP\dst"
Add-Type -AssemblyName PresentationFramework

[xml]$xaml = @'
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="xaml test #1"
    Width="300" Height="250">
  <StackPanel>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
      <StackPanel>
        <Label Content="AAAAAAAAA" />
        <ListBox x:Name="listboxA" />
      </StackPanel>
      <Label Content="  " />
      <StackPanel>
        <Label Content="BBBBBBBBB" />
        <ListBox x:Name="listboxB" />
      </StackPanel>
    </StackPanel>
    <Label Content="  " />
    <Button x:Name="btn" Content="Copy Files" />
  </StackPanel>
</Window>
'@

$reader = New-Object System.Xml.XmlNodeReader $xaml
$frm = [System.Windows.Markup.XamlReader]::Load($reader)
$AAA = "090 080 070 050 020".split(" ")
$listboxA = $frm.FindName("listboxA")
foreach ($a in $AAA) {
  [void]$listBoxA.Items.Add($a)
}
$listboxA.SelectedIndex = 0

$BBB = "107 110 116 117 119".split(" ")
$listboxB = $frm.FindName("listboxB")
foreach ($b in $BBB) {
  [void]$listBoxB.Items.Add($B)
}
$listboxB.SelectedIndex = 0

Remove-Item log.txt -ErrorAction:Ignore
function clicked {
    # delete files in $dst_dir before copy
    del $dst_dir\*.*

    $a = $listBoxA.SelectedItems
    $b = $listBoxB.SelectedItems
    $date = date
    echo "[$date] Selected: $a $b" >> log.txt
    $rexp = "^$a-(\d\d\d)-$b.txt$"
    $count = 0
    Get-ChildItem $src_dir | ?{$_.name -match $rexp} | %{$count += 1; echo "Copy $($_.name)" >> log.txt; copy $_.FullName $dst_dir\$($_.name) }
    $msg = New-Object -ComObject wscript.Shell
    $result = $msg.popup("$count files copied")
}

$btn = $frm.FindName("btn")
$btn.Add_Click({clicked})
$result = $frm.ShowDialog()

画面は、下記のような感じです。
f:id:Itsukara:20170128234046p:plain

コピーが完了すると、コピーファイル数を示すメッセージがポップアップします。
f:id:Itsukara:20170128204726p:plain

ちなみに、テストデータを作成するスクリプトも、一応載せておきます。

$AAA = "090 080 070 050 020".split(" ")
$BBB = "107 110 116 117 119".split(" ")
$src_dir = "C:\TEMP\src"
foreach ($i in 1..200) {
    $a  = $AAA[$(Get-Random $AAA.Length)]
    $b  = $BBB[$(Get-Random $BBB.Length)]
    $m  = "{0:D3}" -f (Get-Random 1000)
    $fname = "$a-$m-$b.txt"
    Set-Content $src_dir\$fname "Test Test"
}

追記(2/18追記)

PowerShell ISEでは、そのまま動きますが、PowerShellでは、下記で起動しないとエラーになることがあります。詳細は別記事参照のこと。

今後

今のところ、PowerShellは面白いと感じており、下記のサイトを中心に、もう少し勉強してみる予定です。

また、GUIも、もう少し試したいので、下記で勉強予定です。
www.atmarkit.co.jp

ちなみに、PowerShellは、Windowsだけでなく、他のプラットフォームでも使えるようです。HTML的な感じでGUIが簡単に書けることを考えると、bashよりも良いかもしれません。

マウスコンピュータに電源が入らず困っている方多数!

当ブログの今月のアクセス数が3700くらいなのですが、一番参照されている記事を確認してみたところ、下記でした。
itsukara.hateblo.jp

全アクセス数の76%がgoogleからで、そのうち、12%が上記記事の参照なので、340弱が上記記事のアクセスでした。マウスコンピュータに電源が入らず困っている方が、相当沢山いるようです。

ちなみに、上記記事のフォローアップとして、下記記事もありますので、上記記事を読んだ方は、下記も読んだ方がよいと思います。
itsukara.hateblo.jp

それにしても、1日に数回電源を投入・切断した程度で、3年ぐらいで壊れるスイッチを電源スイッチに使うとは、品質が悪すぎます。また、この電源スイッチ(おそらく原価100円以下)の交換で25,000円も請求するとは、簡単な修理で利益を上げようとする意図を感じます。

アメリカだったらば、困っている人が集まって、集団訴訟を起こしていてもおかしくないと思います。少なくとも「リコールして修理」してほしいですね。

ひさ~~しぶりに人工知能関連のイベントに参加

2015/10~2016/9の充電期間を経て、2016/10に再就職できたのは良いのですが、非常に忙しい職場で、定時で帰ることは難しく、人工知能関連のイベントには殆ど参加できませんでした*1

本日は代休(代替休暇)だったので、ひさ~~しぶりに人工知能関連のイベントに参加し、非常に楽しいひと時を過ごすことができました。
peatix.com

元々、書店で何回か開催したイベントらしいのですが、結構人気だったので、朝日新聞メディアラボ渋谷分室が場所を提供し別途開催したものです。
shimirubon.jp

スクウェア・エニックスのテクノロジー推進部リードAIリサーチャーである三宅陽一郎さんと、作家の海猫沢めろんさんが、対談形式で「『人工』知能と知能を考えるための61冊」の本を題材に、色々と対談しました。以前に、海猫沢めろんさんの本(「明日、機械がヒトになる ルポ最新科学」:下記)を買って読んだことがあり、面白かったので参加しました。

イベントでは、知能とは何か、人間とは何かを中心テーマとして対談が進み、これに関連した本が紹介されました。本で読むのと異なり、対談の内容が耳から入ってくると、結構脳が活性化されて色々なアイデアが浮かび、面白かったです。また、対談後に30分ほどの質疑応答と、1時間ほどの懇親会もあり、ただ聞くだけの講演会と比べて、とても参加し甲斐がありました。
f:id:Itsukara:20170128085219j:plain

質疑応答では、対談で話が出た「現在の人工知能は体を持たずに開発されているが、体を持つべき」とのテーマに関して、「持つとしたら、どのような体が考えれるか」を伺いたく、質問させていただきました。講演者お二人の意見は結構異なり、めろんさんは「人工知能の体はGantzのような球体でも良いのでは?」とのご意見、これに対し三宅氏は「体への外界からの刺激に対し、それを基に判断し、行動することが知能の基本であり、体の性質によって知能は異なった特性を持つ」とのご意見でした。

私としては、めろんさんの本に書かれていた「石黒先生の人型ロボット」や「矢野先生の人体センサー」から収集される多数の人間のデータに加え、センサーの種類を増やして多数の人間の身体状態や感情などの集団データ、SNSなどによる多数の人間との会話データ(「りんな」のようなインターフェースで多数の人間との会話から得たデータ)など、個体としての体を離れた集団としての感覚器を持った人工知能というものも考えられると思いました。そういえば、そんな海外ドラマもありましたね(世界中にばらまかれたUFOの破片の影響を受けて生まれた子供が、UFOの破片から作られたスーパーAIと通信できる器官を生まれながらに持っている話。ドラマの名前を忘れましたが...)。

イベント参加者は30~40名で、結構学生も多く、博士課程の学生の方も来ていました。博士課程の方は、論文で成果を上げる必要があり大変のようですが、専門分野から少し離れた視点で知見を広げようとされているところに好感を感じました。

また、別の方は人工知能美学芸術研究会(AI美芸研)というNPOを主催されており、1/29に第5回AI美芸研があるとのことで、お誘いを受けました。twitterを拝見したら、フォロワーが3900人もいるので、有名な方のようです。色々な方が人工知能に関わっていると感じました。講演者(3名)を拝見したら、以前にWBAオフ会でお会いした山川さん(ドワンゴ人工知能研究所所長)も講演されるらしく、世の中狭いものだなと感じました。

懇親会会場では、もっと沢山の方と話をすれば、更に色々と聞けたかもしれないと思い、少し残念です。三宅さんやめろんさんとももっと話をすればよかったです。

そういえば、名刺のようなものを一応作ったのですが、交換するのを忘れており、最後に2名の方にしかお配りできませんでした。これも残念です。
f:id:Itsukara:20170128091306j:plain]

ちなみに、現在の所属は派遣会社(スタッフサービスエンジニアリング)ですが、会社の名刺はありません。派遣先の名刺も無いので、色々と不便です。

次の人工知能関連イベントとしては、2月19日のシンギュラリティサロンに参加予定であり、楽しみにしています。
peatix.com

*1:参加できたのは、土曜日に開催していた人工知能関連輪講会ぐらい。

【DRL,Montezuma】ROOM#7訪問とROOM#1 killの関係

2つ前の記事で、ROOM#7の訪問が増えることで、ROOM#1の学習状態に影響を与えるようだと書きましたが、現在行っている学習でも、同じようなことが起こっているようなので、ご報告します。正確な理由は不明ですが、なぜか、これらの間には相関が大きいように見えます。つまり、ROOM#7の訪問回数が増えた後で(実際は、増えて、その後に減った後で)、ROOM#1のkillが増えているように見えます。正確には、もっと実験して、統計的な分析が必要とは思いますが...

ROOM#7の訪問増加

f:id:Itsukara:20170108211014p:plain

ROOM#1でのkill増加

f:id:Itsukara:20170108211022p:plain

【DRL,Montezuma】学習状況確認のためのツール

Montezuma's Revengeの強化学習において、平均スコアだけでは、学習状況が良くわからないので、各種状況を表示するツールを追加しました(plot2.pyとall-plot)。これらを用い、下記のような感じで学習状況をモニタしながら実験を進めています。ご参考まで。
f:id:Itsukara:20170108204146p:plain

各グラフの説明は下記です。なお、説明順は、左端から上下にグラフを辿ったものです。

  • *.r: 全てのScore(実reward)の分布と、その平均の推移
  • *.R: 凡例に示した番号の部屋(Room)の訪問頻度
  • *.RO: 凡例に示した番号の部屋(Room)でのOHL頻度
  • *.k: 凡例に示した部屋でのkill頻度
  • *.tes: 凡例に示したScoreを取得でのOHL学習長(Train-Episode-Steps)
  • *.lives: 凡例に示したScoreを取得した際の残りライフ数(lives)
  • *.s: 凡例に示したScoreを取得するまでのstep数
  • *.pr: 各ステップでのpseudo-rewardの分布とその平均値の推移
  • *.v: 各ステップでのvの値の分布とその平均値の推移

【DRL,Montezuma】Scoreが0になり回復しない原因の分析

Montezua's Revengeの強化学習で、下記のように、Scoreが0になり回復しない場合がありましたが、原因を少し分析してみました。

Scoreが0になり回復しない状況調査

http://54.238.214.79/OpenAIGym/montezuma-x1/log.gcp10.montezuma-x-yaml-pscm-ff-fs2.r.png

Scoreが0になった後は、ROOM#1でPanama Joeが死にまくるのかと思っていましたが、これは誤っていることが分かりました。下記は、どの部屋でkillが起きているか(kill頻度:一定stepあたりのkill回数)を図示したものです。なお、凡例に書かれた数字が部屋の番号です。
f:id:Itsukara:20170108190907p:plain

Scoreが0になる直前で(約28 Mstep)、ROOM#1のkill頻度が高まっていますが、28 Mstep以降は、kill頻度がほぼ0なのがわかります。ほぼ0の部分を拡大したものが下記です。
f:id:Itsukara:20170108191507p:plain

ほぼ0ではあるものの、完全に0ではなく、多少のkillが発生していることが分かります。つまり、あまりkillされない範囲で、微妙に移動しているようです。(この部分の動画を撮っておけば、もっとハッキリしたのですが...*1 )

ちなみに、先頭から2つめの図を見ると、Scoreが0になる直前では、ROOM#2のkill頻度だけでなく、ROOM#2、ROOM#7のkill頻度も増えています。

下記は、各部屋の訪問頻度を図示したものです。Scoreが0になる直前で、ROOM#7の訪問回数が増えていることが分かります。
f:id:Itsukara:20170108195825p:plain

原因分析/推測

これらから、下記のような現象が起きているのではないかと推測しています。

  • ROOM#7や他の部屋での学習の副作用として、ROOM#1でkeyを入手できなくなる(NNの値が、そのように変化するということ)。
  • これにより、ROOM#1から脱出できなくなり、Scoreは100点以下になる。
  • また、実rewardが0になるので、各地点(実際はstatus)でのVが順次減少する。
  • 更に、ROOM#1内の地点(実際はstatus)は通過頻度が高く、pseudo-rerawdはほぼ0。これにより、Vを増加させるものが全く無い状態となる。
  • そのため、ROOM#1内で、僅かなpseudo-rewardだけに基づいて学習が起こり、killが起きない程度の僅かな動きだけになる。
  • 上記全体の結果として、Scoreを取得する上で重要なルートほど、通過回数が非常に多いので、pseudo-rewardは0に近く、一度Vが0に近くなると回復することはない。

上記推測が正しいとすると、pseudo-rewardだけに基づいた学習では、実rewardを取れる所まで辿り着けるようになるものの、その地点へのルートの学習が一度失われると、回復しないということとなります。そのために、学習が非常に不安定になるのだと思います。

上記は、A3Cで学習ですが、Double DQNでは、一度学習したパスを覚えておき、後で利用するので、一度Scoreが0になっても、過去に学習したパスでのVに基づいて再学習が行われ、安定な学習に寄与できるのだと思います。

対策案 (Replay Memoryの導入/活用)

逆に、A3Cでも、一度学習したパスをReplay Memoryに覚えておき、後で利用するようにすれば、学習が安定すると思われます。ただ、メモリ量も限られるので、どのパスを覚えておくのが良いか、判断が難しいですね。Scoreは高いほうが良い、Score取得時のLivesは多いほうが良い、点数を取得するまでのsteps数は少ないほうが良い、などの判断基準が考えられますが、これらに対して、どのように重み付けするのが良いか、難しそうです。1つの案としては、重み付けも学習すれば良いかもしれませんが...

対策案のためのメモリ量削減

なお、記憶するパス数や長さを制限する以外に、直接メモリ量を減らすことも可能です。以前に実験した結果として、pythonlzmaでパスを圧縮すると、メモリ量が約1/40になり、学習速度(steps/h)への影響は16%程度で済むことが分かっています。

実際、現在でも、High Score取得動画や、新しいROOM訪問動画を出力するために、全てのthreadの全ての学習で、GAME OVER直前までのパスを覚えています。実は、パスの圧縮を行う前は、学習途中でメモリ量が16GBを超え、メモリ不足になることもあったのですが、パスの圧縮を行うことにより、現状のメモリ量は4GB程度で済んでいます。

別の対策案 (Mile Stone)

ちなみに、Replay Memory以外にもメモリ量が非常に少ない方法がありそうと思っています。Replayするパスを覚えるのではなく、学習に有効なパスの幾つかの場所(status)をMile Stoneとして覚えておき、そのMile Stoneでは、擬似rewardとしてMile Stoneポイントを与えることが考えられます。ただ、この場合も、どれをMile Stoneにするか、どのようにMile Stoneを更新するかなど、課題が色々ある気がします。

今後の進め方

最近、ウィークディは仕事が忙しく、土日も私用で忙しく、なかなかDeep Learningで遊べなくなってきていますが、できるだけ時間を作って、Replay Memoryの導入・利用処理や、Mile Stoneを実装していこうと思います。

実は、他にも色々とアイデアがあるのですが、実装の手間・時間、その効果を確認するために必要なITリソースや時間などが、膨大に必要なため、なかなか難しい状況です。

*1:別の学習で同様の現象が発生した際の動画が取れたので一応載せておきます。何のモチベーションもないため、何しもしない怠惰なPanama Joeに戻ってました。youtu.be