カテゴリー別アーカイブ: ソフトウェア

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だそうです。うーん、これは重要でもないですかね。

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ベースで処理することも出来るそうですが、教師あり学習なのできちんとしたデータセットを作る必要があります。そこにたどり着くまでのところを、教師なし学習との組み合わせでなんとか実現したいところです。

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さん作なので書きませんでした。というかあのスクリプトはそこそこ問題なく動いている感じなので公開してもらえたらなあ、と思っています。

 

2016年4月FSIJ月例会 BBG-SWD

先日FSIJ月例会がありました。タイトルは「SWDプログラマの決定版 BBG-SWD」です。

一口でまとめると、ARMによるSWD(Serial Wire Debug)をBeagleBone Green上で使えるようにしたという話でした。

そもそもの背景には、gniibeさんが販売しているハードウェアFST-01FSM-55の製造過程があります。実際にハードウェアの製造を行うSeeed Studioでは、ファームウェアの書き込みにST-Link/V2というJTAGデバッガを、Windows上で動作するST Micro提供のソフトウェアで使っているという問題があります。ファームウェア書き込み部分も自由ソフトウェア、ハードウェアで置き換えることを目的としているそうです。これによって、”Respects Your Freedom Hardware product“の認証を取得する資格が得られるようです。ST Microのプロプライエタリなソフトウェアを介さないので、その部分でマルウェアを仕込まれるような可能性も低減できます。

ソフトウェアのリポジトリはhttp://git.gniibe.org/gitweb/?p=bbg-swd.gitにあります。この中には、BeagleBone Greenのbone-kernelと呼ばれる種類のLinux kernelに含まれるPRUSS(Programmable Realtime Unit SubSystem)のドライバ(uio_pruss)を介して動作するプログラムと、それをOpenOCDで利用可能にするためのOpenOCDへのパッチから構成されています。

gniibeさんはこの成果をhackster.ioのIoTコンテストに応募したそうですが、ファイナリストまでは選出されたものの受賞には至らなかったとのことでした。

Raspberry PIを筆頭としたワンチップマイコンは広く流行っていますが、こういった低レイヤーまで自由なコンピューティング環境を提供しているものはなかなか無いようです。

有志によるリバースエンジニアリングの成果でそれなりに自由なOrange PIシリーズは、熱に弱いという問題があるそうです。自分も購入したのにここ数ヶ月使っていなかったので知りませんでした…

今の時期暖かくなってきましたが、そんな環境でも動作するというgniibeさんのおすすめはWandboardだそうです。

自由なデータの重要性

先日、NEologd Casual Talksというイベントに参加してきました。mecab-ipadicに新しいエントリーを追加するmecab-ipadic-neologdに関するイベントでした(Togetterまとめ)。

その中で改めて感じたのは、自由なデータの重要性です。イベントでは「言語資源」という観点でのデータの重要性が語られていました。形態素解析器の辞書として、継続的に更新・リリースがなされているのはNEologd以外ほとんどないという指摘がありました。

自分も2012年にSoftware Freedom Dayの国内イベントで「自由なデータ」という題で発表をしました。

今になって改めてこの資料を見ると、現在は若干状況が変化している部分もあります。NEologdの出現は、まさしくその一つです。

また、日本語の文章チェッカーとしてtextlintという実装の日本語ルールを作成・公開している人がいます。これまでLanguageToolに若干のルールをコミットしてきましたが、textlintのほうがかなり充実している感じです。

最近は機械学習をやってみたりしているのですが、これもまさにデータの質がかなり重要な領域です。変なデータを元に学習すると、そもそも学習が収束しなかったり、期待しない結果を返すモデルができてしまったりします。この領域でも、チュートリアルに使われる定番のデータセットが公開されています(MNIST, CIFAR-10等)。

最近、自分も画像分類タスクのテストのために作ったデータセットはあるので、なんとか公開できる形にできないかと考えています。実データはInstagramにあるもので、個々の画像のライセンスを確認しないまま集めて分類したのですが、画像URLの一覧という形なら問題なく配布できると思います。オライリー「実践 機械学習システム」でも感情分析用のツイートデータを人力で分類したもののID一覧から実データを取得する、という方法が取られていました。

 

実際に自分でデータの分類をやってみると、「どこまでをこの分類に含めるべきか」という根源的な問題を実感できます。実際、単純に検索しただけだと「明らかにおかしい」というものから「これはどうなんだろう」というものも出てきます。

この点について、先日の発表の中で印象的だったのが片山さんの「ファッションが大好きなので無限に洋服の文字列データを眺めるのが楽しかった」という部分でした。特定のドメインのテキストでも、きっと同じような感覚があるのだろうとなんとなく感じています。

ともあれ、公開できる形になったら、改めて告知したいと思います。

sshの設定をホスト名prefixで分ける

一時期、「最強のSSH踏み台設定」という記事が話題になりました。.ssh/configのHost設定でスラッシュを区切り文字とすることで、動的な踏み段設定ができるというものです。

この手法を応用して、基本的にProxyCommandが必要な環境下で動的に変わるIP相手に対し、アドレスにprefixを付けることで常にあるProxyCommandを実行させるような設定を行ってみました。


Host aws-u_*
  User ubuntu
  IdentityFile /path/to/key.pem
  ProxyCommand socat - PROXY:proxy.host.name:$(echo %h|cut -f 2 -d _):%p,proxyport=8080

ssh aws-u_xxx.yyy.zzz.wwwとすれば常に特定のユーザー、鍵、Proxy経由で接続するようになります。区切り文字にアンダースコアを使っているのは、スラッシュを使った場合にscpでホスト名と判断されない場合があったからです。ssh, sftpコマンドではスラッシュでも特に問題ありません。

rep2の更新

周りにある大半のDebian環境をwheezyからjessieにアップグレードしたのですが、先日ようやく自宅のPCルーターマシンもアップグレードしました。

合わせていろいろなものが更新されたのですが、phpの変更が大きかったようで、それまで使っていたrep2exがきちんと動作しなくなりました。もともと使っていたのは相当前のコードベースであり、いまどきはgithubで管理されているコード(https://github.com/2ch774/p2-php)があるので、この機会にそちらに移行しました。

基本的にはまっさらな状態でセットアップを行い、一部のデータをコピーすることで、未読情報や画像DBも含めて移行できました。やったことは以下の通りです。

  • old-rep2/data/2channel ->p2-php/data/dat/2hcannel へコピー
  • old-rep2/data/db -> p2-php/data/db
  • ic2のdsnをp2-php/conf/conf_ic2_inc.phpに記述

幸いic2のデータはMySQLに保存していたので、特に移行上の問題はありませんでした。未読情報もdata/dbにあるSQLite3のデータをコピーするだけでいけました。

ユーザーの設定に関しては新規にやりました。これも頑張れば移行できたのでしょうが、ちょっと面倒に感じたのと設定すべき項目がそれほどないことからやりませんでした。

ユーザー設定の中に、「データ転送量を抑えるためにカタカナを半角にする」というオプションが標準でONなあたり、このソフトウェアの歴史を感じます。思い返せばWillcomの京ポン2あたりから使っていました。

iPhoneが出たぐらいの頃にスマホ用のUIも整備されたので、今使っても悪くありません。

Orange PI PC

g新部さんが強くプッシュしているOrange PI PCを購入しました。実際に購入したのは先月ぐらいだったのですが、最近ようやくまともに使いだしたところです。

Orange PIシリーズは複数あるRaspberry PIのフォロワーの一つです。私は以前秋月電子で同じような”Banana PI”というのを見かけたことがあるのですが、気が付くと手に入らなくなっていました。

g新部さんが最も良しとしている点は、ハードウェアメーカー(Allwinner)が情報開示に積極的にであることだそうです。Raspberry PIはその点で確かに厳しいようです。

そのあたりの話が11月のFSIJ月例会でありました。その時の発表内容をTogetterでまとめたので、興味のある方はご覧ください。月例会のページにもいくつか情報があります。

私の興味はH.264のハードウェアエンコーディングにあります。g新部さんからお勧めされた時に、Allwinner H3のスペック的にハードウェアエンコーダーを持っていることを確認して購入しました。しかしまだそこを動かすには至っていません。情報はそこそこあるようなので、なんとかしたいところです。

LanguageToolで長音記号チェック

漢字変換ミスで、たまに長音記号がかな文字以外の後に置かれる事例を見かけたので、それをLanguageToolのルールにして取り込んでもらいました

現状ある日本語のルールをざっと見たのですが、うまい具合に表現する方法が思い浮かばなかったので、思い切ってメーリングリストで聞いてみました。

メイン開発者のDanielさんは親切で反応も早い方で、「正規表現でUnicodeの範囲を使えばできる」という方法を示してくれました。また、過去にも日本語のルールを書いているSilvanさんからは、JavaにおけるUnicodeのクラス表現(\p{IsXxx})を紹介してくれました。

これらを踏まえ、以下のようなルールをpull requestとして書き、無事masterにマージしてもらえました。

                <rule id="SINGLE-MARKON" name="長音">
                  <pattern case_sensitive="no">
                    <token regexp="yes">[^\p{IsKatakana}\p{IsHiragana}]+</token>
                    <token >ー</token>
                  </pattern>
                  <message>不適切な長音符</message>
                  <example><marker>リンカー</marker></example>
                  <example correction=""><marker>隣家ー</marker></example>
                </rule>

カタカナとひらがな以外が長音記号の前にあるとき、LanguageToolは警告を出します。

$ echo "隣家ー" |java -jar languagetool-commandline.jar -l ja-JP -c UTF-8
Expected text language: Japanese (no spell checking active, specify a language variant like 'en-GB' if available)
Working on STDIN...
1.) Line 1, column 1, Rule ID: SINGLE-MARKON[1]
Message: 不適切な長音符
隣家ー
^^^
Time: 529ms for 1 sentences (1.9 sentences/sec)

この機会に、Doc-ja Wikiの”LanguageTool使い方メモ“も若干修正しました。自前のgrammar.xmlを指定して起動する方法と、ソースコード上で変更をしたときにルールのテストをする方法について新た説明を加えています。

LanguageToolのリリースバージョンは現在2.9ですが、次期バージョン3.0ではgrammar.xmlの書式も変わっているため、いずれWiki内の説明もそちらに合わせて修正したいところです。