にせねこメモ

はてなダイアリーがUTF-8じゃないので移ってきました。

このブログについて

文字・フォント・プログラム・技術・趣味などについて、Twitterでは書きづらい長い内容などをまとめるためのブログです。基本的には自分用のメモとして書いている部分が多いです。

リンク等

Pixiv http://pixiv.me/nixeneko
Tumblr http://nixeneko.tumblr.com/ 絵。Pixivアカウント持ってなくても見れます
Pleroma @nixeneko@nixeneko.info Mastodonとかやってる人はフォローしてください
Twitter @nixeneko  
MediaMarker http://mediamarker.net/u/nixeneko/ 主に文字・言語関係の蔵書
GitHub https://github.com/nixeneko プログラム用、あまり使ってない
ナナシスID ZhRYMnA
デレステID 421820148

同人誌(無料公開)

http://nixeneko.hatenablog.com/entry/c88_russian_alphabethttp://nixeneko.hatenablog.com/entry/c90_greek_latin_cyrillichttp://nixeneko.hatenablog.com/entry/20170811_dentyu

タイ語におけるハイフネーションについて

タイ語組版でハイフネーションってあるの?…一応ある。
自分でもタイ語ではハイフネーションをしないものだとばっかり思っていたが、実際に用例がある。タイ語にもハイフネーションがあるとはっきり書いてあるサイトが見当たらなかったので、ここに書いておく。

ハイフネーション

英語やロシア語等の組版では、単語の途中で改行する場合に、行末にハイフンをつけて続きを次の行に送るハイフネーションと呼ばれる操作がある。特に、長い単語が含まれる場合に、行長を一定にするために使われる。
例:

We, therefore, the represen-
tatives of the United States
of America...

タイ語にハイフネーションはない?

タイ語でもハイフネーションはあるのだろうか?
モリサワの発行する英中韓組版ルールブックタイ語では、次のように書かれている。

行揃えは、「均等配置(最終行左揃え)」が基本ですが、デザインによっては「左揃え」や「センター揃え」が使われることもあります。
この際、注意したいのは単語の間では改行を行なわない、ということです。タイ語にはハイフネーションのような考え方がないので、単語の区切りや改行してもよい位置などを確認しながら作業をするとよいでしょう。

タイ語 英中韓組版ルールブック(PDF) (2019/10/22閲覧)

このように、大抵は文章は均等配置(ジャスティファイ)され、行末のハイフンを全く用いない本も多い。


しかし、「ハイフネーションのような考え方がない」というのは言いすぎではないかと思う。実際の印刷物に、ハイフネーションを行った例がみられる。

タイ語ハイフネーションの実例

手元の本から見つけた例を挙げる。

タイ語辞書の例。

f:id:nixeneko:20191117005729p:plain
สุทธิ ภิบาลแทนによるพจนานุกรมประจำตัวนักเรียน (学生向け辞書)。2007年出版。


f:id:nixeneko:20191117002026p:plain
p11. เครื่องตกแต่ง (装飾品)の途中で改行されている。


f:id:nixeneko:20191117000440p:plain
p13. กระเจอะกระเจิง (群から離れて), พรรณไม้ (木の種類)の途中で改行されている。


f:id:nixeneko:20191117003239p:plain
p291. บรรณาธิการ (編集者)の途中で改行されている。


f:id:nixeneko:20191117003652p:plain
พระมหาพิชัยมงกุฎ (プラマハーピチャイモンクット; 王冠の名前), เจ้าแผ่นดิน (国王), พระราชทาน (お下賜になる)の途中でそれぞれ改行されている。

タイ語組版では普通句読点は使われないが、辞書では分かりやすくするためにピリオド、コンマといった英語風の句読点を使うことがあるらしい。

文芸書の例「窓際のトットちゃん」

f:id:nixeneko:20191117010607p:plain
黒柳徹子『窓際のトットちゃん』のタイ語版。Butterfly Book House (สำนักพิมพ์ผีเสื้อ)によって1983年に出版されたもの。


f:id:nixeneko:20191117011753p:plain
p39. สนุกสนาน (面白い)の途中で改行されている。


f:id:nixeneko:20191117011838p:plain
p39. โต๊ะโตะจัง (トットちゃん)の途中で改行されている。


f:id:nixeneko:20191117185414p:plain
p43. โรงเรียน (学校)の途中で改行されている。


f:id:nixeneko:20191117185827p:plain
p101. ประกอบ (組み立てる)の途中で改行されている。


f:id:nixeneko:20191117190346p:plain
p141. คุณครูใหญ่ (校長先生)の途中で改行されている。


f:id:nixeneko:20191117190654p:plain
p157. คุณครูใหญ่ (校長先生)の途中で改行されている。


f:id:nixeneko:20191117191135p:plain
p199. เด็กหญิง (女の子)の途中で改行されている。

これらを見ると、この本では「学校」などといった基礎的な語(複合語)でもハイフネーションがされていることがわかる。

多言語組版研究会の報告から

第4回多言語組版研究会の発表資料(東南アジアの文書スタイルの現地調査結果)において、次のような報告がある。
タイ国内でもっとも広く読まれている新聞であるThairat社と、タイ語組版について2003年にディスカッションした内容として、次のように書かれている。

(1) ハイフン
タイ語起源の単語では、基本的にハイフンは使用しない。ハイフンが使用されるのは、1語が長くなる傾向があるパーリ語サンスクリット語起源の単語だけに適用するのが通例という。その際も、ハイフンを挿入するのは自動化されておらず、手動で入れる。
新聞という媒体の特色と思われるが、ハイフンは、1段記事の場合だけに使用し、2段以上の記事では使うこともあるができるだけ避けるのが通例であると説明された。

3.2 現地調査報告1(報告書3.3.3.2) (DOC) (2019/10/22閲覧)

これは2003年時点のことなので現在では異なっている可能性もあるし、また出版社・出版物等によってポリシーも異なってくるだろうと考えられる。

タイ王立協会による説明

タイの王立協会(Royal Society;旧Royal Institute)が約物(punctuation)の使用規則を定めている。ハイフンの使い方は次のページにある。

これによると、

  1. 音節または複合語が分かれて次の行に続く際に行末に書く(=ハイフネーション)
  2. 押韻構成に従って音節を区切る際に、語全体を示すために使う
  3. 読み方を示す場合に、音節の区切れに書く
  4. 語の前または後ろもしくは前後を一部とりのぞいたものを示すために使う
  5. 「~まで」の意味で、時間・数量・場所の幅を示す
  6. ISBNなどのコードの数字のまとまりを区切るのに使う
  7. 語にどの文字(子音・母音・声調記号)が使われているかを示すために文字・記号の間に挟んで広げるために使う

以上7つが挙げられている。

(1)のハイフネーションの例を引用すると

        คณะกรรมการกำหนดหลักเกณฑ์เกี่ยวกับการใช้ภาษาไทย มีการ
ประชุมทุกวันพฤหัสบดี เวลา ๑๐.๐๐ น. ณ ห้องนันทนาการราชบัณฑิตย-
สถาน ราชบัณฑิตยสถาน.

となっていて、王立協会“ราชบัณฑิตยสภา”の途中で改行されたためハイフンが挿入されているのがわかる。

他に王立協会の約物の使用方法を定めたのを見ると、タイ語では一般的に使われないピリオドやコンマなども解説されており、王立協会が定めているから一般に広く使われているとは言い難いかもしれない。

漫画の改行の例

改行の極端な例として、漫画が考えられる。特に日本漫画の翻訳など、縦に細長いフキダシに台詞を入れたものがあり、横幅が狭いので一行一語でほぼ縦書きのようになっていることもある。しかしながらハイフネーションがされているのは見ない。手元の本で見つけた例を挙げる。

ゆるめいつ」の例

saxyunゆるめいつ』3巻 タイ語版. Zenshu, 2014.

f:id:nixeneko:20191118220507p:plain
p32. ซาเอะ (サエ; 人名)が途中で改行されている。


f:id:nixeneko:20191118214710p:plain
p51. คริสต์มาส (クリスマス)が途中で改行されている。


f:id:nixeneko:20191118215711p:plain
p86. มายองเนส (マヨネーズ)が途中で改行されている。

ひめゴト」の例

佃煮のりおひめゴト』1巻 タイ語版. Boomtown, 2014.

f:id:nixeneko:20191118221352p:plain
p64. อุนโกะ (運子; 人名)が途中で改行されている。


f:id:nixeneko:20191118221936p:plain
p74. โอดะ มิตสึนากะ (織田光永; 人名)の光永の途中で改行されている。


以上を見るに、外来語や人名でもハイフンをつけずに途中改行が許されている。
漫画では(なるべく避けられるにしろ)あまり気にせず語中でも改行をしていて、ハイフンをつけないようだ。

まとめ

タイ語組版において、ハイフネーションは、使われる本もあれば使われない本もあるが、使わない方が多い。使用する場合でも、可能なら使用を避けるものであるようだ。

お願い

文章を組んだもので、語の途中で改行をしていてかつ行末ハイフンを書かない例を見つけたら教えてください。
また、拙いタイ語力で書いているので、間違い等あればご指摘いただければ幸いです。

ノートPCのCPU速度が0.38GHz固定状態になる問題

Windows 10の載ったノートPCを使っていたら、ある日突然動作が遅くなってしまった。リカバリすれば大丈夫かと思い、OSを「このPCを初期状態に戻す」により初期化してみたが治らなかった。

システム:

タスクマネージャを開いてみたところ、CPUの速度が0.38 GHzに張り付いて、使用率は14%のまま推移している。これはおかしい。

f:id:nixeneko:20190524220926p:plain
タスクマネージャー。CPUの速度が0.38 GHzになっている

また、Windows 10をセーフモードで起動してみたところ、CPUの速度が2.71 GHzとなり、正常に動いているようだった。


ネットを検索したところ、次のようなサイトがみつかった。
Solved: CPU frequency stuck at 0.38GHz on battery - HP Support Community - 6979093

これによると、解決法は次のようにするとよいらしい。

  1. 「デバイス マネージャー」を開く
  2. ファームウェア」→「システム ファームウェア」を右クリックし、「ドライバーの更新」を選択
  3. 「ドライバー ソフトウェアの最新版を自動検索」を選択

あとはウィザードに従い、再起動すると、正常に戻った。

f:id:nixeneko:20190524223848p:plain
治った時のデバイスマネージャー。速度が2.71 GHzとなっている

(2019-06-19追記)
一度は直ったものの、しばらく使っているとまた同じ現象に悩まされるようになった。システムファームウェアのドライバを元に戻したりするとまた復活したりするのだが、しばらくすると元に戻ってしまうようだ。

設定→システム→バッテリー→「バッテリー残量が次の数値を下回ったときにバッテリー節約機能を自動的にオンにする」をオフにして再起動したところ、2.71GHzの速度で動くようになった(気がする)。

(2019-06-28追記)
「バッテリー残量が次の数値を下回ったときにバッテリー節約機能を自動的にオンにする」をオフにしてても0.38 GHzになったので関係ない気がする…。

ハードリセットを行ったところ、速度が速くもどった。しばらく様子見する。
Windows OS 搭載のノートパソコンでのハードリセットを行う方法 | サポート 公式 | ASUS 日本

Twitterで旧字が化ける? CJK互換漢字という罠

概要

Twitterに投稿するとCJK互換漢字が対応する統合漢字に化けるので、投稿時に化けないStandard Variant形式と互換漢字とを相互変換するページを作成した: 互換漢字-異体字セレクタ コンバータ

はじめに

Twitterで「社」(U+FA4C)、「羽」(U+FA1E)などの一部の旧漢字を投稿しようとすると、「社」(U+793E)、「羽」(U+7FBD)に化ける。

Twitterに次の文字列を投稿すると

神(U+FA19)と神(U+795E)
福(U+FA1B)と福(U+798F)
羽(U+FA1E)と羽(U+7FBD)
既(U+FA42)と既(U+65E2)
梅(U+FA44)と梅(U+6885)
社(U+FA4C)と社(U+793E)
練(U+FA57)と練(U+7DF4)
者(U+FA5B)と者(U+8005)

こうなる:


左側の字が右側の字と同じになっている。


これは一体どういうことなのだろうか? 実は、Unicodeの問題である。

CJK互換漢字

これらの化ける文字は、UnicodeにおいてCJK互換漢字という領域に収録されている。互換漢字に対し、基本となる漢字はCJK統合漢字と呼ばれる。CJKはChina, Japan, Koreaの略で、各国で微妙に字体が違っても、同一とされた*1漢字は国に関わらず一つとし、原則として重複収録はしない方針となっている。
しかし、CJK互換漢字は名前の通り、互換性を保つために収録された漢字である。それまでの文字コード等との互換性を保つ関係*2で「同じ文字を重複して収録した」扱いであり、CJK統合漢字の中に対応する漢字をもつ。

Unicode正規化

ここで、Unicodeは検索等の利便性のために、「Unicode正規化(normalization)」という処理を提供している。これは、記号付きのアルファベットなど、二種類以上のコード列で表すことができる文字列を適切に比較したりするために重要な処理である。しかし、CJK互換漢字に対してUnicode正規化を行うと、対応するCJK統合漢字に「化けて」しまう*3

Twitter投稿時のUnicode正規化

Twitterは、2015年から投稿時にUnicode正規化を行うようになった*4。そのため、CJK互換漢字をTwitterに投稿すると対応するCJK統合漢字に置換されてしまい、CJK互換漢字を投稿することはできなくなった。

Standardized Variant

とはいっても、Unicode正規化によってCJK互換漢字が化けてしまうと困る。そういった場合のために、Unicode異体字セレクタという仕組みを使ってCJK互換漢字相当の漢字を表現できる枠組みが作られた(2013年9月制定のUnicode 6.3)。これによって表現されたものをStandardized Variantとよぶ。これは、Unicode Character DatabaseのStandardizedVariants.txtの後半に定義されている。
この仕組みを使うと、Unicode正規化を行っても化けないため、Twitter等にCJK互換漢字の字形の漢字を投稿することができる(ただし、正しい形で表示されるかは環境による)。

互換漢字↔Standardized Variant変換器

CJK互換漢字はともかく、Standardized Variant形式を入力することは不便なので、CJK互換漢字とStandardized Variant形式を相互に変換するページを作成した。

TwitterにCJK互換漢字に含まれる字形を投稿したい場合等に利用していただきたい。

Standardized Variantの実際の表示


Standardized Variantで表現されたものは、環境によるが互換漢字の字形で表示される。手元のWindows 10環境では、Firefoxでは互換漢字の字形で表示されたが、Chromeではそうはならなかった。
f:id:nixeneko:20190316185449p:plain
Firefoxで見たStandardized VariantによるTwitter投稿結果
(20190318追記)これを正しく互換漢字の字形で表示するためにはフォントが対応している必要がある*5Chrome等では対応フォント以外で表示すると互換漢字の形で表示できない。(6.0 Marshmallow以降の)Androidのデフォルトフォントである源ノ角ゴシックは対応しているので、Androidでは正しく互換漢字の字形で表示される。一方、Firefoxは独自に互換漢字の字形で表示するような実装をしている可能性があり、フォントによらず表示できるようだ。Standardized Variant (というより異体字セレクタ)を使った投稿をする場合は、このようにフォントやソフトウェアの対応が微妙であり、必ずしも狙った形で表示されないことに留意する必要がある。(追記終)

ちなみに、ちゃんと変換できているかなどは、

などのページで確認できる。

*1:細かい字体の違いを無視し同一とみなすことを包摂(unification)という。

*2:「ラウンドトリップ変換(round-trip conversion)の確保」といい、既存の文字コード(Shift_JISなど)からUnicodeに変換し、その後元の文字コードに再度変換したときに、内容(文字コード列)が同一になるように保証されている。

*3:Unicode正規化における等価性は正準等価と互換等価という2種類がある(Unicodeの等価性 - Wikipedia)のだが、CJK互換漢字については正準等価となっている。正準等価は見た目も機能としても同じものに対して適用されるべきものなので、互換漢字という見た目が異なるものに対して適用されているので問題となっている。Unicode正規化には種類があり、互換等価については対象としないものもあるが、正準等価は常に対象になる。

*4:厳密な時期はこちらで推定されている: TwitterにUnicode正規化が導入された時刻の推定 by zeeksphere - Togetter

*5:https://twitter.com/monokano/status/1106927404579061761

iPodのLast.fm scrobblingが死んだ

10年位前からLast.fmを利用している。Last.fmとは、再生した音楽を記録することができるサービスである。私のユーザーページはこちら。

さて、このLast.fmで再生した曲を投稿(scrobbleという)するには、専用のアプリを使う。
ところが、Windowsでは、iTunesが12.7.xになってから(たぶん)、古いLast.fm Desktop Appは使えなくなり、新しいLast.fm Desctop Scrobblerが用意された。これにより、古いAppでサポートされていたiPodのscrobblingは使えなくなった。


以前は、iPodをPCに接続するとダイアログが開き、新規に再生されたトラックをscrobbleすることができたが、これがなくなってしまった。

iPod Touch向けworkaround

現在利用しているのがiPod Touch (第 5 世代)で、iOSのバージョンは9.3.5である。なので、iOS向けのLast.fm Scrobbler iOS Appを入れて、曲を再生した後にアプリのScanを押すことによって再生した曲をscrobbleすることができる。
ただし、このAppによるscrobbleは、再生回数の変化を見ているらしく、PC上のiTunesで再生したものについても拾ってscrobbleしてしまう。iTunesでの再生時にもscrobbleしているので、二重にscrobbleされることになる。
そのため現在は、iTunesに接続する前に一度scanしてscrobbleし、iTunesに繋いで同期した後にもう一度scanをし、変更をdiscardすることで、二重でscrobbleしてしまうことを防いでいる。

面倒臭い…。

地方住みでもアニメがみたい―東京でなくてもアニメは放送してるというのは本当か

前にTwitterで、「別に東京でなくてもBSとかで放送あるからアニメ見れるよ」って感じの話を見たのだけど、しょぼいカレンダーを見ながら2018年7月開始の今期新アニメの中で、どれだけが長野県で視聴できるかを調べてみた。今期開始でない、長期に渡って放送している番組については扱わないので注意。
また、テレビ放送だけで、配信についてはここでは扱わない。

×→放送なし
○→放送あり(東京の地上波より放送が遅い)
◎→東京の地上波より放送が早いか同時

タイトル 地上波 BS無料 AT-X 備考
ISLAND ×
はねバド! × BS11AT-X・MX同時
バキ × × × 日テレ
千銃士 × ×
Back Street Girls -ゴクドルズ- × BS11・MX同時
中間管理録トネガワ × × × 日テレ
すのはら荘の管理人さん × AT-X最速
異世界魔王と召喚少女の奴隷魔術 × AT-X最速
夢王国と眠れる100人の王子様 × AT-X最速
BANANA FISH × × フジテレビ系
七星のスバル × × TBS
ちおちゃんの通学路 ×
殺戮の天使 × AT-X最速
音楽少女 × AT-X最速, BS11・MX同時
はるかなレシーブ × AT-X最速
ゾイドワイルド × × TBS系
はたらく細胞 × BS11・MX同時
百錬の覇王と聖約の戦乙女 × BS11・MX同時
スペースバグ × × × MX
あそびあそばせ × AT-X最速
プラネット・ウィズ ×
銀魂. (銀ノ魂篇 後半戦) × × × テレビ東京
悪偶 -天才人形- × × BS11・MX同時
邪神ちゃんドロップキック × BSフジ最速
Phantom in the Twilight × × BSフジ・MX同時
京都寺町三条のホームズ × テレビ東京
深夜!天才バカボン × × テレビ東京
オーバーロード × AT-X最速
アンゴルモア元寇合戦記 × ×
Free!-Dive to the Future- ×
天狼 Sirius the Jaeger × AT-X最速, BS11・MX同時
少女☆歌劇 レヴュースタァライト × × TBS系
ハイスコアガール × × BS11・MX同時
ロード オブ ヴァーミリオン 紅蓮の王 ×
ハッピーシュガーライフ × TBS系
ぐらんぶる × × TBS系
ゆらぎ荘の幽奈さん ×
つくもがみ貸します × × NHK総合
進撃の巨人 Season3 × × NHK総合
ヤマノススメ サードシーズン × 15分枠
おしえて魔法のペンデュラム~リルリルフェアリル × × × キッズステーション最速, アニマックス, MX. 15分枠
じょしおちっ!~2階から女の子が…降ってきた!?~ × × 5分枠
One Room セカンドシーズン × × 5分枠
アイドルマスター シンデレラガールズ劇場(第3期) × 5分枠
陰陽師・平安物語 × × × MX. 5分枠
働くお兄さん!の2! × MX. 5分枠
闇芝居(第6期) × × テレビ東京系. 5分枠
兄に付ける薬はない!2 -快把我哥帯走2- × × × MX. 5分枠
BanG Dream! ガルパ☆ピコ × × 5分枠

作品数: 49

最速または地上波同時 放送あり
地上波のみ 2作品(4.1%) 4作品(8.2%)
BS無料放送あり 14作品(28.6%) 38作品(77.6%)
AT-Xあり 21作品(42.9%) 42作品(85.7%)

東京の地上波と同時あるいは最速となると少なくなってしまうが、放送だけであればBSの無料放送で8割近くカバーできている。
BSで放送がないものについてはAT-Xで補完できるものもあるが、日テレ放送の番組(BSでの放送がある場合もあるが3ヶ月ラグがあくことも)やMXでしか放送されない作品などで補完できないものがある。その場合、見たければネット配信に頼るしかなさそう。
東京の地上波が最速である場合が多いので、実況がしたければ結局東京が強い。

それでも現代ではdアニメストアNetflix、プライムビデオといった配信サービスがあり、そこで配信している場合も多いため、実況とかしないなら配信サービス契約した方が快適な気がする。

Windows 10上のDarknetでYolo v3をトレーニングしOpenCVから使ってみる

DarknetはCで書かれたディープラーニングフレームワークである。物体検出のYOLOというネットワークの著者実装がDarknet上で行われている。
もともとはLinux等で動かすもののようだが、ありがたいことにWindowsコンパイルできるようにしたフォークが存在している:
github.com
これを利用してWindowsで動かしてみる。

環境

事前準備

Visual Studio 2017 Community

まずVisual Studio 2017 Communityをインストール。
プロジェクトがVisual Studio 2015のものなので、v140ツールセットも入れる。インストーラを起動し、「変更」を押し、右側のペインの「C++によるデスクトップ開発」の下のオプションから「デスクトップ用VC++ 2015.3 v14.00 (v140) ツールセット」にチェックを入れ、「変更」を押してインストール。

CUDA/cuDNNのインストール

次にCUDAとcuDNNをインストール。今回入れたバージョンは次の通り。リポジトリにはそれぞれ9.1, 7.0を使うように書かれていたが、最新版でも問題なさそうである。

  • CUDA 9.2
  • cuDNN 7.1

CUDAのインストールはインストーラに従えばよい。cuDNNはCUDAと同じディレクトリに突っ込んでおくと楽。

PathにC:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v9.2\binを追加しておく。

OpenCVのインストール

OpenCVをダウンロードしてきて展開する。最新はv3.4.2だが、リポジトリの注意書きにあるようにv3.4.0(またはそれ以前)を使う。
OpenCVのReleasesから3.4.0のWin packをダウンロードしてきて適当な場所(以下、C:\opencv340とする)に展開する。

OpenCVのdllが存在するディレクトリ(C:\opencv340\opencv\build\x64\vc14\bin)にPathを通しておく。

コンパイル

ここからソースコード一式をダウンロードしてくる。ReleasesからYolo_v3のタグがついたものをダウンロードしてきたが、git cloneしても問題ないはず。

ダウンロードしてきたものを展開し、build/darknet/darknet.slnをVisual Studio 2017 (Community)で開く。
開いた際にツールセットを変換するか聞かれたのだが変換しないようにした。(これはどうするのが最適なのか不明)

ソリューション構成・プラットフォームの変更

構成: Release, プラットフォーム: x64に変更。

カスタム ビルド ツールの指定

プロジェクト名(darknet)を右クリックして「ビルドの依存関係」→「ビルドのカスタマイズ」を開き、「CUDA 9.1」のチェックを外し、代りに「CUDA 9.2」をオンにする。

プロジェクトのプロパティの編集

プロジェクト名を右クリックして「プロパティ」を開き、

これらを編集して、実際にインストールしたOpenCVディレクトリに合わせる(C:\opencv_3.0\…C:\opencv340\…)。
また、
「リンカー」→「全般」→「追加のライブラリディレクトリ」の中の

  • $(CUDA_PATH)lib\$(PlatformName)$(CUDA_PATH)\lib\$(PlatformName)

が変な気がしたので\を足しておいた。

コンパイル

「ビルド」→「ソリューションのビルド」などでコンパイルする。

すると、build\darknet\x64以下にdarknet.exeが出来上がる。

試す

ちゃんと動くか確認する。
YOLOのページ(https://pjreddie.com/darknet/yolo/)からYOLOv3のweightsファイルをダウンロードしてきてbuild\darknet\x64以下に入れる。
コマンドプロンプトbuild\darknet\x64を開き、

darknet.exe detector test data/coco.data yolov3.cfg yolov3.weights -i 0 -thresh 0.25 dog.jpg

を実行する。これはdarknet_yolo_v3.cmdの中身でもある。認識がうまくいくと次のような認識結果が表示される。
f:id:nixeneko:20180803152630p:plain

トレーニング準備

トレーニングについては

に詳しく書いてある。
また、データセットの見本として、

のページの「The data set I composed for this article can be found here (19.4Mb).」と書かれているところからダウンロードできるデータを参考にできる。(これをそのまま使う場合、改行コードがWindows用\r\nになっているため変換が必要になるかもしれないらしい)

今回はイラストと顔の領域を指定したデータを用意し、イラストの顔検出をやってみる。

学習データを用意

アノテーションLabelImg等を使うと楽。形式が異なっている場合は適宜変換する。

学習データは、画像ファイル(.jpg)群*1と(拡張子以外)同名のテキストファイル(.txt)を用意する。画像ファイルとテキストファイルは同一のディレクトリに入れる。テキストファイルはアノテーションを定義する。
アノテーションの形式は、

<クラスNo.> <領域の中心のx座標> <領域の中心のy座標> <領域の幅> <領域の高さ>

である。クラスNo.は.namesファイルで定義したものに対応する番号である(0オリジン)。今回はクラスが1つだけの場合を考えるのでクラスNoは必ず0になる。
座標や幅・高さは左上を(0.0, 0.0), 右下を(1.0, 1.0)とする割合で示す。2,3番目の座標は領域の中心の座標であることに注意。一行に一つの領域をかき、領域が複数になる場合は同様の内容を複数行書くことになる。

一例をあげると

0 0.2 0.2 0.1 0.1

は0番目のクラス、領域の中心は画像の左から2/10、上から2/10の位置で、幅が画像の1/10、高さが画像の1/10となる。

画像ファイルのリスト

学習用(train.txt)とテスト用(test.txt)に、画像ファイルの一覧を書いたファイルを用意する。darknet.exeからの相対パスを一行一ファイルとして羅列したものとなる。画像ファイル群を適当な割合で分割して学習用とテスト用にする。今回は1000個弱の画像ファイルを学習:テスト=9:1に分けた。

画像ファイルは最終的にbuild\darknet\x64\data\obj以下に入れるとすると、train.txttest.txtは次のような内容になる。

data/obj/00001.jpg
data/obj/00002.jpg
data/obj/00003.jpg

これらをbuild\darknet\x64\data\obj\train.txt, build\darknet\x64\data\obj\test.txtに用意した。

クラス名の設定

.namesファイルがクラス名の設定である。一行に一つのクラスを書く。今回は一つのクラスだけにするので、obj.namesファイルを

face

とだけ書いて保存する。

.dataファイルの設定

classes= 1
train  = data/obj/train.txt
valid  = data/obj/test.txt
#difficult = data/difficult_2007_test.txt
names = data/obj.names
backup = backup/

クラス数を1に変更、trainvalidに先ほど用意したtrain.txt, test.txtを指定。
クラスの名前を書いたファイルをnamesに指定。backupはトレーニング結果の重みの出力先となる。

cfgファイルの設定

yolov3.cfgをコピーしてyolov3-obj.cfgとし、編集する。

max_batchesは何回繰り返すかを指定する。今回は10000とした(トレーニングに丸1日程度かかった)。

GPUのメモリが6GBと少ないのでsubdivisionを増やす。メモリが十分ある場合は小さい値(8や16)で問題ないが、メモリ関係のエラーで止まる場合は32, 64と値を増やすといいらしい。

  • subdivision=16subdivision=32

クラスの数に合わせて、3ヵ所について次の変更を施す。filtersはfilters=(クラス数+5)×3で計算し、クラスが1つの場合は18となる。

  • classes=80classes=1
  • filters=255filters=18

トレーニング

ネットワークの重みの初期値としてdarknet53.conv.74をダウンロードしてきて使う。

これをbuild\darknet\x64に入れる。

build\darknet\x64に移動して、次のコマンドを実行する。

darknet.exe detector train data/obj.data yolov3-obj.cfg darknet53.conv.74

lossが下がっていくのを眺めながら、トレーニングが終了するまで待つ(あるいは適当なところで終了する)。

トレーニング途中でdarknetが終了してしまう場合

darknet.exeと同じディレクトリにbad.listというファイルが生成され、問題となった画像ファイルが追記されるようだ。このファイルを用意したtrain.txttest.txtから取り除いてトレーニングし直すといいっぽい。これを学習が止まらなくなるまで繰り返す。

結果の確認

トレーニング結果は

darknet.exe detector test data/obj.data yolov3-obj.cfg backup/yolov3-obj_final.weghts -i 0

で確認できる。動画だと

darknet.exe detector test data/obj.data yolov3-obj.cfg backup/yolov3-obj_final.weghts moviefile.mp4 -i 0 -out_filename result.avi

とか。

OpenCV/Pythonで動かす

最新のOpenCVにはDNNモジュールがあり、darknetのネットワークも利用できる。
ただし、YOLOv3(内部で利用しているshortcutレイヤ)を使うためにはOpenCV 3.4.2より前のバージョンでは対応していないので、最新版をインストールする必要がある。Python版はpip install opencv-pythonなどで入れられる。


OpenCV公式のsamples/dnn/object_detection.pyにDNNモジュールによる物体検出のサンプルがあるので、これ改変して動くものをつくった。

コード

動作環境

gist.github.com

ダウンロード

weightsファイル等も含めて動かせるセットは次からダウンロードできる。Python 3向け。OpenCV 3.4.2より前のバージョンでは動かないので注意。

備考

入力に与えたい画像と、ネットワークの受け付ける入力の形が異なるので、cv2.dnn.blobFromImage関数を利用してデータの橋渡しをしてやる必要がある、ということのようだ。.cfgファイルがネットワークを定義しているので、入力画像の大きさについてもここに定義されている(今回は(416, 416))。
また、スケーリングを行い入力が0.0~1.0の範囲になるようにしているようだ。
OpenCVがBGRなので、(BGRでなく)RGB順を使うよう指定している。

動作画面

f:id:nixeneko:20180807170439p:plain
まあ動く。

*1:.jpg以外の形式も使えるかは確認してない。