knok のすべての投稿

knok について

I am a Debian Developer and a board member of Free Software Initiative (FSIJ).

gnu.org日本語翻訳ミーティング参加

先日、「www.gnu.orgの日本語訳について」のミーティングに参加してきました。最近のFSIJ月例会はMumbleを用いたリモート開催を増やしているので、リアルミーティングは久しぶりです。

当日の配布資料はhttp://git.savannah.gnu.org/cgit/www-ja.git/tree/doc/meeting-2017-01.txtにあります。そちらにもgnu.org翻訳作業への参加方法が書かれていますが、興味のある方はSavannahwww-jaプロジェクトのメーリングリスト(閲覧は要登録)や、gitリポジトリの参照(こちらはanonymous clone可能 git://git.savannah.gnu.org/www-ja.git)も見てみてください。

個人的な活動 – 機械翻訳

私はこの1年ろくな活動ができていなくて申し訳なかったのですが、以前から考えていた「www-jaをコーパスとして機械学習による翻訳モデルを構築する」という活動に手をつけ始めました。TensorFlowのseq2seqサンプルを若干修正してWMTの代わりに任意のテキストファイルを与えられるようにしたコードは以前作成した(https://github.com/knok/tf-seq2seq-mod)ので、あとはデータセットを作成するだけです。

まずは以下のようなPython scriptを作ってみました。Python2, polib, natto-pyで動きます。

# -*- coding: utf-8 -*-
#

import polib
import os, sys
import re

target_dir = "./www-ja"
pos = []

for root, dirs, files in os.walk(target_dir):
    for file in files:
        if file.endswith(".ja.po"):
            po = polib.pofile(os.path.join(root, file))
            pos.append(po)
#
#import pdb; pdb.set_trace()

pair = {}
for po in pos:
    for p in po:
        msgid = p.msgid
        msgstr = p.msgstr
        pair[msgid] = msgstr
#

from natto import MeCab
m = MeCab("-Owakati")

fname_in = "input.txt"
fname_out = "output.txt"

with open(fname_in, "w") as fi, open(fname_out, "w") as fo:
    for key in pair.keys():
        val = pair[key]
        p_key = m.parse(key.encode('utf-8'))
        p_text = m.parse(val.encode('utf-8'))
        if re.match(r"^[0x00-0x7f]*$", p_text):
            continue
        fi.write(p_key)
        fi.write("\n")
        fo.write(p_text)
        fo.write("\n")

以下のような感じで実行しています。

$ python translate.py --data_dir /path/to/text \
 --train_dir /path/to/save-data --size 400 \
 --en_vocab_size 30000 --fr_vocab_size 30000 \
 --num_layers 1 --batch_size 5
Creating 1 layers of 400 units. Created model with fresh parameters.
Reading training data (limit: 0).
global step 200 learning rate 0.5000 step-time 2.50 perplexity 3205.53
 trg = FSF セミナー : GPL と LGPL の 詳細 の 研究 と 分析
 hyp = 0000 0000 0000 > > > > > > > > > > > > > > > > > > > > > >
(中略)
global step 10000 learning rate 0.4950 step-time 2.37 perplexity 1.79
 trg = < a href = " / fun / jokes / quayle . html " > クエール 氏 </ a >
 hyp = < a href = " / fun / jokes / vi . html " > ネットワーク さ </ a >

残念ながら利用可能なGPUを持っていないので、CPU演算のみで処理しています。今のところDebianで深層学習フレームワークがtesting(stretch)入りしているのはCaffe, Theanoの2つだけで、TensorFlowや自分がよく使っているChainerは入っていません。まあこのあたりはupstreamの更新も頻繁なので、あえてパッケージを使わなくともvirtualenv+pipで適時入れるほうが良い気もします。

とはいえ、GPUを使って深層学習を行うということは、ほとんどの場合プロプライエタリなソフトウェアに依存することと等価なので、「gnu.orgの翻訳」ということに限ればむしろCPUのみでの処理の方が望ましいのかもしれません。

自由なコンピューティング

実際、ミーティング当日も自由なコンピューティング環境がより一層損なわれているという話がありました。gniibeさんはChromebookにLibrebootを苦労して入れているようです。

自分もここ数日いろいろとひどい目にあいました。Xbox 360のSmartGlassを使ってみようとしたのですが、Windows 8.1の場合Xbox 360で利用しているLiveアカウントとの関連付けをWindows自身のログインアカウントと紐付けないと利用できないのです。Windows 8以降、Microsoftは極力Liveアカウントでのログインをさせるよう誘導しているのですが、8.1(とおそらく8)でそれが強制されるというのは厳しく、利用を諦めました。ただ、Windows 10ではこの点は改善されているようで、SmartGlassを含むストアアプリはアプリ単位で個別に利用するLiveアカウントを設定したり、そもそもLiveアカウントの必要ないアプリは普通にローカルアカウントのまま利用できるようになっていました。なので、Windows 10マシンでSmartGlassを利用しています。

iPhone, Android端末なども実質iCloud, googleアカウントが必須に近い状態ですが、Windowsも同様の仕組みに倒しているわけで、自由からより通い方向に進んでいるなあと痛感しました。

 メンテナ不在問題

現在メンテナが不在なGNU Projectのソフトウェアについていくつか名前が挙げられました。

一つはGNU bisonです。これは割と致命的な気がしたのですが、GCCは4以降独自パーサ(gniibeさんによると、そもそもC++が自由文脈文法でないため)を採用しているとのことなので、案外問題は少ないのかもしれません。メジャーな言語処理系でもbison(yacc)必須なものがぱっと浮かびませんし。

もうひとつはGNUbikだそうです。うーん、これは重要でもないですかね。

GPD Winを購入

ゲーム向け小型PCという触れ込みのGPD Winを購入しました。実際には昨年末頃に届いていたのですが、あまり設定が完了していません。この手の小型PCを購入するのは、VAIO Type U以来です。

今回購入するにあたり、Amazon, AliExpressなど選択肢は複数あったのですが、geekbyingを利用しました。Amazonよりは安かったことと、実際にgeekbyingで購入した人のblog記事を見かけたのが選択の理由です。

購入時の入力フォームが日本語だったため、「住所も日本語で書いたほうがいいのかな?」と思い日本語で一通り書いてフォームを送信したところ、数日してgeekbyingから「英語での住所を教えてくれ」というメールがきました。幸いにしてSPF, DKIMが適切だったので、フィッシングではなかろうという判断をして返信を行い、最終的には無事製品が届きました。タイムラインは以下のような感じです。

  • 2016/11/29 webからオーダーを実施
  • 2016/11/29 $329.00 USDの決済がPayPalで発生
  • 2016/11/30 住所の英語表記を求めるメール受信
  • 2016/12/01 メールの返信
  • 2016/12/10 発送の連絡メール受信 (到着に15~30営業日必要と記載)
  • 2016/12/24 自宅に不在連絡票が届く
  • 2016/12/27 再配達の手配をし受領

現状Windows10のまま使っていますが、USBメモリにDebianを入れてそちらからも起動できるようにしようと思っています。少なくともmulti-arch(i386/amd64) stretch alpha8の起動はできたのでインストールも問題はないと思われます。個々のデバイス認識に関しては調査が必要そうですが。

ゲーム機としての利用を考えていたので、Steamクライアントもインストールした状態です。少なくとも、以下のゲームは普通にプレイできています。

  • DoDonPachi Resurrection (怒首領蜂 大復活)
  • DARIUSBURST Chronicle Saviours
  • Skyrim (Special Editionではない方)

Skyrim Special Editionは実行バイナリが64bit化された点と、GPU用のメモリをメインメモリ4GBから割り当てる点が厳しいようで、自分の手元では正常に動作しませんでした。

Native Debianを動かした時にどれぐらいのパフォーマンスが出るのかは気になるところなので、その環境の整備を進めたいと思っています。

Mini Debian Conference Japan 2016参加

2016/12/10に開催されたMini Debian Conference Japan 2016に参加してきました。場所は日本橋のサイボウズオフィス内で、LibreOffice Kaigi 2016と同時開催でした。自分も一応両方に参加するつもりで申し込みも両方にしたのですが、結果としてDebian側の話ばかり聞いていました。

その時の様子はハッシュタグ#debianjpでツイッターを検索するとある程度様子が伺えると思います。自分が参加しているセッションについてはある程度ツイートしています。せっかくなのでMomentsを使ってみようかと思ったのですが、全部のツイートが出てこない上に時系列に並んでいない、並び替えはすべて手動という使い勝手の悪いインターフェースで断念しました。

個人的には音響モデルを含めて自由ソフトウェア実装として作ったバーチャルシンガー徵音梅林(ちおんメイリン)に最もインパクトを受けました。発表は台湾の張正一(Chou Shouichi)さんでした。

発表資料の中でも触れられていましたが、クリプトン・フィーチャーの商用ソフトウェアであるVOCALOIDは作成できる内容に制限があります。初音ミクのEULA(PDF)にありますが、公序良俗に反するなどの歌詞を含めることを禁止しています。現実にはそういった内容のものが作成、公開されているのですが、規約レベルではアウトです。張さんは、ギターを燃やすパフォーマンスの写真などを交えて「音楽活動は自由であるべきだ」と主張されていました。これには強く同意します。

ソフトウェアのベースはWORLD(修正BSDライセンス)というパテントフリーなものを使っているとのことでした。音響モデルもマスコットキャラクターもCC-BY 3.0で配布しています。

残念ながら、まだフロントエンドについては実装がこなれていないようです。デモではWineでVOCALOIDのエディタを利用されていました。まだ日本で利用している例はほとんどなさそうですが、頑張って欲しいと思います。

自作辞書のブートストラップを考える

かな漢字変換や形態素解析といった処理を行うにあたって、辞書は必要不可欠な存在です。これを一から自作することを考えています。

  1. 適切な単語のリストの作成
  2. 単語に対する読み、品詞の追加
  3. 単語に対するコスト値の算出
  4. データソースはWikipediaを使う

こんな感じでおそらくはできるでしょう。時間はかかると思うので、ゆっくり考えていくつもりです。

今はまず教師なし機械学習による単語分割を使って、単語リストを作ることを試みています。これについては階層Pitman-Yor過程に基づく可変長n-gram言語モデル(VPYLM)の実装が複数あり、それを使うことである程度下処理ができます。

Wikipediaの記事はhttps://dumps.wikimedia.org/jawiki/からダウンロードできます。本文のダンプはjawiki-latest-pages-articles.xml.bz2というファイル名です。これをWikipedia ExtractorというPythonスクリプトでプレーンテキストに変換できます。変換時に警告が出ますが、それはたいてい自己参照に関するものなので、放っておいても大丈夫そうです。

さしあたって、展開ディレクトリ/AA/wiki_00を対象にlatticelmをデフォルトパラメータで実施したところ、以下のような感じになりました。


$ head -10 data/AA/wiki_00
< doc i d=" 1 "u rl ="h t tps:/ / ja. wik iped ia. o rg/wi ki?cur id= 1 " ti tl e=" W i kip edi a : アッ プ ロー ドロ グ2 004 年 4 月 ">
W i kip edi a : アッ プ ロー ドロ グ2 004 年 4 月
< u l >
< /d oc >
< doc i d=" 2 " url =" htt ps :// ja. wik iped ia. o rg/wi ki?cur id= 2 " ti tl e=" W i kip edi a : 削 除 記 録 / 過 去 ログ 2 00 2 年 12 月 ">
W i kip edi a : 削 除 記 録 / 過 去 ログ 2 00 2 年 12 月
B e l o w i s a l i s t o f t h e m o s t r e c e n t d e l e t io n s .
A l l t i m e s s h o w n a r eser v er ( U . S . P a ci fi c ) t i m e .
< /d oc >
< doc i d=" 5 " url =" htt ps :// ja. wik iped ia. o rg/wi ki ?c urid= 5 " ti tle =" ア ン パサ ンド ">

ちょっと分割されすぎですね…ハイパーパラメータはいろいろとあるので、チューニングはいろいろと必要そうではあります。他に試された人の解説によると、初期状態がすべて分割されている点が大きいとのことです。

以前の記事で紹介した「続・わかりやすいパターン認識 教師なし学習入門」には通常のPitman-Yor過程までは解説されており、VPYMLに関してはなんとなくでしか理解出来ていません。もう少し自分の理解も深めたいところです。

単語分割自体は系列ラベル問題とみなしてRecurrent Neural Networkベースで処理することも出来るそうですが、教師あり学習なのできちんとしたデータセットを作る必要があります。そこにたどり着くまでのところを、教師なし学習との組み合わせでなんとか実現したいところです。

IIJmioファミリーシェアプランに追加する形でDoCoMo SIMから転入

個人的にIIJmioタイプDファミリーシェアプランを一人で使っていたのですが、音声用に長年DoCoMoの契約を続けていました。ちょうど更新月に入ったのでこの機会にMNP転出することにしました。ファミリーシェアプランが追加のSIMを頼めるようになっていたので、MNPの転出先としてそちらを選んでみました。この時どのメニューから選択すると正しく申し込めるのかが分かりづらかったので記録しておきます。

  •  会員専用ページ(https://www.iijmio.jp/member/)の「SIMカード追加」(https://www.iijmio.jp/service/setup/hdd/addsim/confirm.do)を選択
  • 遷移したページでサービスコードがファミリーシェアプランになっていることを確認
  • SIMカードの追加を選択
    • 機能から「音声通話機能つき」を選択
    • 「MNP転入」という項目が選べるようになるので選択
    • MNP転入に必要な情報を入力

会員トップページの「ご購入お申し込み」から選択してしまうと新規プラン追加になってしまうので、気をつける必要がありました。

今後MNPする機会はそうそう無いとは思いますが、忘れないよう記録しておきます。

そもそもDoCoMo FOMA以前はNTTパーソナルのPHSをずっと使っていたのですが、2004年あたりで「端末料金3万円OFF」と引き換えに乗り換えを行いました。当時5万円程度したモトローラM1000を2万円程度で購入できたのですが、電話番号を変える作業は結構大変でした。今思えば、もっと粘ればPHSからのMNPができたのでそのほうが楽だったかもしれません。

seq2seq用日本語対話データセット生成スクリプト

以前、Instagramの画像から食べ物の画像のデータセットを作成という記事を書きましたが、その中で「次はseq2seq用の対話データセットをどうにかしたい」とこぼしていました。なんとかそれを形にできました。

元データはDFSG準拠のライセンスでない点に注意してください。このツールによって生成したデータも同様の制限を受けます。

画像データセットに関しては複数種類があって、以前作った画像データセットの方にあまり需要はなかったようですが、今回はそれなりに参考にされていそうです。

できればDFSG互換なライセンスで公開できる形のデータセットが作りたいのですが、さすがに対話を一人でやるのはなかなか無理がありそうです。オープンなslackやIRCチャンネルを立てて、そういうデータを作るための雑談をしよう、という提案をしたら参加してくれる人はいますかね…?

 

2016年9〜10月の活動

ここ2ヶ月ぐらいの活動を記録しておきます。

Debian関係

  • Namazuのbuild-arch/build-arch-indep対応
  • ChaSen symbolsの主要arch対応
    • qemu-debootstrapの利用
    • porterboxの利用

ChaSenに関しては前回の投稿とも関係があるのですが、とりあえずは主要(公式リリース)アーキテクチャのみ、一通りlibchasen2.symbolsの更新を行いました。

恥ずかしながら今回はじめてporterboxを使いました。これまでporterboxにログインしたことはあっても結局使い方がよくわからなくて諦めたりしていたのですが、たまたまログインしたホストのmotd(ログイン時に表示されるメッセージ)にschrootの使い方へのリンクhttps://dsa.debian.org/doc/schroot/が掲載されていて、それではじめて使い方を理解した次第です。

しかし、qemu-debootstrapでどうにかなる範囲についてはそちらで対応しました。

第12回 カーネル/VM探検隊参加

qemu-debootstrapについてそれなりに理解を深めたので、その紹介という形で発表をしてきました。

 

Qiitaへの投稿

写経に関する記事のストック数が多いのが以外です。

FSIJ月例会(予定)

今月10月の28日に、いつもの場所(東京体育館)、いつもの時間(18:30〜19:30)で勉強会が開催予定です。

GnuPG 2.1のお話だそうで、期待できます。今の時点でのDebian stable(8.x/Jessie)ではまだ標準のGnuPGが1.4系なのですが、次のリリースには2.1が標準になる予定なので、大いに参考になることでしょう。

C++ template instanceのシンボルを隠す

ここ数日、C++がらみで苦労しています。自分がC++を覚えたのが学生の頃、20年以上前になるので、今時のC++についていけていません。

ChaSenのライブラリをビルドしていると、基本的にABIとしてはC言語の範囲でしか定義していないのに、一部のC++シンボルがexportされてしまいます。ざっと調べてみたところ、どうやらtemplateのインスタンスを定義した場合には有無をいわさず外部参照できてしまうようです。

GCC拡張であればvisibilityの制御でこの挙動を変えられるようなので、pragmaを使ってdartsのインスタンスシンボルを隠すことはできるようになりました(参考: Visibility – GCC Wiki)。

#include <string>
#include <vector>
#include <map>
#include <iostream>
#pragma GCC visibility push(hidden)
#include <darts.h>
#pragma GCC visibility pop
extern "C" {
#include <stdlib.h>
#include <stdio.h>
#include "dartsdic.h"
#include "chalib.h"
}

typedef Darts::DoubleArrayImpl<char, unsigned char, long, unsigned long>
DoubleArrayL;

そもそもなぜこんなことをする必要があるかいうと、Debian packageのsymbolsの仕組みに引っかかるからです。C++のsymbol name mangling ruleはgccのメジャーバージョンが上がると微妙に変わることがあって、現在stable標準のgcc 5.xとunstable標準のgcc 6.xでまさにこれが影響しています。これまでビルドしていたライブラリのシンボル情報をdebian/<package-name>.symbols.<arch>という名前で保存していて、ビルド結果のバイナリーに含まれるシンボルがこのファイルと異なった場合、ビルドエラーとなるようになっています。これはABI互換性が壊れないことを保証するための仕組みです。

そもそも内部で使っているだけのC++シンボルが見えてしまっているのを回避して、この問題を根本から対応したかったのでした。

しかしまだ一部の標準ライブラリのC++ template instance symbol(std::ctype<char>とか)が残ってしまっているので、それをどうしたものかと苦慮しているところです。

 

GNU screen tips

普段使っているGNU screenのtips」という記事をQiitaに投稿しました。簡単にまとめると

  • multi attach (-xオプション)
  • fit コマンドによる画面のリサイズ
  • -Xオプションの応用
  • C-a ” (windowlist -b)カーソルキーでのウィンドウ選択
  • number コマンドでウィンドウ番号入れ替え
  • title, setenv

という感じです。

これ以外に、screen上のすべてのウィンドウでgpg-agentにパスワードをキャッシュさせるpinentry-cursesを特定のウィンドウで待機させる、ということをやっているのですが、使っているスクリプトがgniibeさん作なので書きませんでした。というかあのスクリプトはそこそこ問題なく動いている感じなので公開してもらえたらなあ、と思っています。

 

Baum-Welchアルゴリズムの実装

機械学習についての理解を進めてゆこうとする過程で、ニューラルネットワーク以外の手法の重要性に改めて気づき、「続・わかりやすいパターン認識 教師なし学習入門」を読み進めています。

途中で困ったのが、Baum-Welchアルゴリズムの実装です。その手前のViterbiアルゴリズムは書籍の記述をそのままコード化すれば同じ結果が得られたのですが、Baum-Welchについては解説が少なく、思ったように動作しませんでした。

いろいろとネットを探しまわった結果、コロラド州立大学のCS教材のページがかなりナイーブな実装で参考になりました。ただし、完全にナイーブではなくスケーリングが施してあります。これがないと、条件によっては値が小さくなりすぎてNaNになってしまうような状況が発生します。

より複雑な実装としては、hmmlearnがありました。元はscikit-learnの一部だったようですが、独立したモジュールになったようです。その他、Wikipediaの記事朱鷺の杜Wikiの記事が参考になりました。