周りにある大半の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も整備されたので、今使っても悪くありません。
Category: 開発
Orange PI PCで動画のハードウェアエンコードはできるのか
これはLinux Advent Calendar 2015 18日目の記事です。 ARMベースの小型PCとしてRaspberry PIシリーズが人気です。ハードウェアによる動画(H.264)エンコード支援がついていて、それが目的で使っている人もいるようです。 しかし私はRaspberry PI 2の代わりにOrange PI PCを購入しました。機能的には持っているようなので、できればなんとか使いたいところです。 参考にするため、そもそもRasPiではどうやっているのかをちょっと調べてみました。Googleで検索すると、gstreamerでomxh264encを使うという方法が紹介されています。 これはgst-omxというコンポーネントのようで、OpenMaxというコーデックの取り扱いを抽象化したAPIのようです。さらに調べてみると、RasPiではlibopenmaxil.soという共有ライブラリが呼び出されているようです。 ではこいつのソースコードはどこだと探してみましたが、ファームウェアの一部という扱いでバイナリーのみが配布されているという残念な状況でした。RasPi側からの調査はここが限界です。 ではOrange PIではどうか。Orange PIとAllwinnerのチップの情報に関しては、linux-sunxi.orgが総本山のようです。ここにいろいろと情報がありました。 Orange PI PC用カーネルにはcedar-veというモジュールが追加されており、これがハードウェアコーデック用のデバイスドライバとなっています。/dev/cedar_devというスペシャルデバイスを介してioctlで直接ハードウェアを操作する機能を提供しています。残念ながらメインラインにはマージされていないようです。 そしてそれを使うよう改造されたffmpegが公開されています。これを動かすことを目標としていろいろ試してみました。リポジトリにはdeb化されたバイナリーもありますが、どうもwheezy向けのようです。しかもパッケージングの作法もよろしくなく、既存のdebianパッケージとファイル単位でいろいろ衝突を起こすので、これを利用するのはお勧めしません。 そこで手動でのビルドを行いましたが、ライブラリ周りで苦労しました。最終的には以下のような手順でビルドできると思います。 ビルドしたバイナリを実行してみます。/dev/cedar_devへのrwアクセスができる状態でffmpegを実行します。 残念ながらうまく動きませんでした。gdbで追いかけてみると、ve_open()で/dev/cedar_devをオープンしてioctl IOCTL_GET_ENV_INFOで構造体ve_infoの値を取得していますが、これ自体は失敗しないものの、各種メンバの値reserved_mem, reserved_mem_size, registersがすべて0になっています。これによりve_mallocが失敗して6行目のエラーメッセージが表示されます。ドライバ側のコードを読むと、「このインターフェースは使うな」というコメントがあり、実際に0を返していました。きっと古いcedar_devで動くコードだったのでしょう… http://linux-sunxi.org/CedarX/Encoderの記述によると、現在あるコード以外にもsunxi_memドライバという物理メモリにアクセスするドライバ(/dev/sunxi_mem)と併用して動くCedarXというライブラリが別にあるようです。ハードウェアエンコーダのサンプルコードもあるのですが、やはりバイナリでしか存在しないライブラリ群に依存しています。 それでもいいからなんとか動かせないかと、sunxi_memドライバを追加した勝手カーネルをビルドしようとしたのですが、mach/includes.hという存在しないヘッダファイルを必要としてビルドできませんでした。ここはまだ調査不足です。 現状の結論として、Orange PI PCでH.264のハードウェアエンコードは「できそうな雰囲気」という煮え切れない結論となってしまいました。linux-sunxi MLの購読を始めたので、今後はこのあたりどうなっているかを尋ねてみたいと思っています。
Orange PI PC
g新部さんが強くプッシュしているOrange PI PCを購入しました。実際に購入したのは先月ぐらいだったのですが、最近ようやくまともに使いだしたところです。 Orange PIシリーズは複数あるRaspberry PIのフォロワーの一つです。私は以前秋月電子で同じような”Banana PI”というのを見かけたことがあるのですが、気が付くと手に入らなくなっていました。 g新部さんが最も良しとしている点は、ハードウェアメーカー(Allwinner)が情報開示に積極的にであることだそうです。Raspberry PIはその点で確かに厳しいようです。 そのあたりの話が11月のFSIJ月例会でありました。その時の発表内容をTogetterでまとめたので、興味のある方はご覧ください。月例会のページにもいくつか情報があります。 2015年11月 #FSIJ 月例技術講座 Orange PI PCを使ってみる 私の興味はH.264のハードウェアエンコーディングにあります。g新部さんからお勧めされた時に、Allwinner H3のスペック的にハードウェアエンコーダーを持っていることを確認して購入しました。しかしまだそこを動かすには至っていません。情報はそこそこあるようなので、なんとかしたいところです。
機械学習/TensorFlow初心者の雑感
いろいろあって、不慣れながらTensorFlowを使ってみたのですがいまいちわかってなくていろいろはまったので、記録に残しておこうと思います。 画像認識タスク チュートリアルには手書き数字のデータセットThe MNIST Dataを機械学習で認識できるモデルを作る、というものがあります。画像認識の世界では非常にポピュラーなものだそうです。 これ自体はチュートリアルの通りに実行すればごく普通に動きます。ナイーブな実装でも90%程度の認識率のモデルができます。これを、任意の別の画像に応用させようと考えました。対象はカラー画像で、単純に1種類の物体の区別をさせようとしました。 TensorFlowには画像を読み込む機能が用意されています。tf.image.decode_jpegでjpeg形式を読み込んで、横x縦x3(RGB)のint32型3次元行列を返します。さらに、これをリサイズする関数tf.image.resize_imagesもあります。指定した縦横のサイズにリサイズされ、値もfloat型に正規化されます。 ではこれを単純にロジスティック回帰にいれようと、tf.matmulで行列の積を求めようとしたらtf.matmulでエラーになりました。コードは以下のような感じです。 いろいろ試した挙句、この関数は入力が2次元行列以外を受け付けないことがわかりました。よくよく見るとドキュメントにもそう書かれていました。 他の人はどうしているか探してみると、画像をOpenCVで読み込ませてなおかつ単純に平坦化(flatten)した1次元行列として扱っていました。結局自分もそれに習って実装しなおしました。その結果、動くコードは以下のように修正されました。 扱うデータが1次元なのにinput_xが2次元なのは、input_xが受け付けるデータは訓練データの配列だからです。ミニバッチ処理のためにそのような作りになっているようです。訓練データが1つだけの配列にすればもちろん1つのデータに対しても動きます。 一応、tf.reshape(vec, [-1])とすれば平坦化できるようなのですが、今のところ確かめていません。 セッションと値の評価 とりあえず自分で用意したデータを使って訓練をさせてみたのですが、思うような結果が得られません。というか全然学習している気配がありません。 結論から言えば、単純に訓練データが圧倒的に不足していたようなのですが、そもそも学習できていないということを把握するのにちょっと苦労しました。 個々の重みはweightに入っているはずなのですが、この値の中をどうやって参照するかではまりました。単純にprint(weight)などとしても__str__によって変換された結果(オブジェクトのクラス名等)しか出てきません。 正しく値を取得するには、TensorFlowのセッション上での値の評価が必要です。 この結果、すべての値が0.0のままだったので「これ、学習できてない!」とようやく理解できました。TensorFlowとの格闘はまだまだつづきそうです。 参考 TensorFlowでアニメゆるゆりの制作会社を識別する – kivantium活動日記 Python – TensorFlowを算数で理解する – Qiita
Debian上でmecab-ipadicをベースに単語を追加する
今時のMeCabには、新しく追加した単語だけコストを計算させる機能があるので、実際に動かしてみました。 参考となるURLはhttps://taku910.github.io/mecab/dic.htmlです。Web上には古いgoogle code上のページがまだ残っており、Googleで検索するとそちらが上位に引っかかるので注意が必要です。 前提として、mecab-utilsとmecab-ipadic(EUC-JP版、UTF-8は不可)がインストールされている必要があります。 次に、登録する単語のエントリーを用意します。諸事情により、EUC-JPで保存しておきます。以下は実際の例です。foo.csvという名前で保存しておきます。 次にモデルファイルを前述のページから取得します。リンク先はGoogle Driveのようです。この記事を書いている2015年10月の時点では、mecab-ipadic-2.7.0-20070801.modelというファイル名になっています。 必要なファイルが集まったら、以下を実行します。 すると、foo2.csvに単語のコストが記録された新しい結果が出力されます。 元のmecab-ipadicのソース(/var/lib/mecab/dic/ipadic/*.csv)とモデルmecab-ipadic-2.7.0-20070801.model)がEUC-JPであるため、新しい辞書の文字コードもEUC-JPに合わせる必要があります。
歌舞伎座.tech 番外編「C++11/14コア言語」出版記念 参加 #kbkz_tech
先日、書籍「C++11/14コア言語」が発売された記念のイベントに参加してきました。 当日の発表はニコニコ生放送でも中継されており、アカウントがあればタイムシフト視聴が可能です。また、内容をツイッター上でツイートしていたので、ハッシュタグ#kbkz_techで検索すればある程度情報を得ることができます。Togetterでも「歌舞伎座.tech 番外編「C++11/14コア言語」出版記念 #kbkz_tech ツイートまとめ」として記録してあります。 私個人のC++に対する理解はあまり深くありません。もっともよく使っていた時期でもLinux Zaurusを使っていた2004~2006年代ごろと10年近く前のことです。当時はgcc 2.95と3.xの移行期にぶつかっていて、ABI非互換の問題を抱えていたことをよく覚えています。Linux Zaurusで閉じた環境だったため、標準ライブラリはほとんど使わずQtのサブセットであるQtEmbeddedばかり使っていました。QtEmbedded自体は今でも電子書籍のKobo方面で利用され続けているようです。 会場では紙の書籍が値引きされて販売されていましたが、私は電子書籍の方を達人出版会で購入しました。紙よりも安価なうえにDRMのないPDFで個人的には満足しています。 書籍の内容はまだ読み始めたばかりですが、きちんと体形だったモダンな仕様を理解していない自分にとってはよさそうな書籍だなあという感触を得ています(メモリーモデルの項目を読みながら)。 この書籍はhttps://github.com/EzoeRyou/cpp-bookにて、CC-BY-SA 4.0で公開されている。誤植を見つけた時、githubのフローに従って指摘が可能なのも便利かもしれません。
Debian Jessie i386をamd64に無理やり移行させる
i386環境から再インストールをしないでamd64に移行させる作業をやってみました。なんとか実現できたものの、今のところは無理やり感が否めません。実際にやってみた感触を記録しておきます。 背景 Debianはメジャーリリース間のアップグレードが行えることを重要視しているディストリビューションであり、実際自分もbo(1.3)からwheezy(7.x)まで更新し続けているインスタンスを持っています。 しかしながら、当然そのような古くからのシステムはアーキテクチャがi386のままです。amd64が公式にサポートされたのはetch(4.0.x, 2007~)からです。途中でmultiarchという複数のアーキテクチャのパッケージを一つのシステムに導入する仕組みもできましたが、それはi386→amd64への移行に直接利用できるようなものではありません。 手法 i386→amd64化を試みた人はこれまでにもあり、いくつかはネット上の私的なドキュメントとして残されています。今回はDebian Wikiに書かれている方法をとってみました。 作業の流れ 大まかに実施する作業の流れを以下に示します。 amd64 kernelパッケージのインストール i386アーキテクチャでもlinux-image-*-amd64パッケージがあり、kernelだけ64bit化することはできる debootstrapで/chroot64 以下にamd64の最小環境を構築 あとで必要になるパッケージ群を追加で入れる(libc6-i386 file bzip2 openssh-client lftp) Live CD/USB等を使って起動し、/chroot64以下の実行ファイルを/にコピー /chroot64/etc/ld.so.cache も忘れずコピーする /chroo64/lib64は/lib64にコピーを行う Wikiではsymlinkを張る、と記述されているがコピーでないと正常に動作しなかった 動作するかどうかは実際にchroot /chroot64 /bin/sh 等を実行してみれば判断できる amd64 kernelでブートする この段階でパニックを起こした場合、/lib64等が適切に処理されておらずdll不足でinitが実行できなかった可能性が高い インストールされているパッケージをi386からamd64に入れ替える apt-get updateを実行 依存関係と戦いながらi386パッケージをamd64に置き換える インストールパッケージ数が多いほどここの作業は大変 何かあったら以下の手段を試す dpkg –remove –force-all [パッケージ名]:i386; apt-get install [パッケージ名] apt-get -f install cd /var/cache/apt/archives; dpkg -i –force-all [パッケージ名]*.deb… Continue reading Debian Jessie i386をamd64に無理やり移行させる
第一回 カーネル/VM探検隊@名古屋参加・発表
先週は盆休みで名古屋に帰省していたのですが、ちょうどそのタイミングで第一回 カーネル/VM探検隊@名古屋が開催されるということで、参加と発表をしてきました。 私の発表は「3DSにデータを自動送信したかった」というものです。 簡単に説明すると、Nintendo 3DS上で動作するBASIC処理系であるプチコン3号のソフトウェアキーボードを、USB制御できるBBガンを使って制御しようとしたけどダメだった、という内容です。 3DSのタッチパネルは単純な感圧式なので、BBガンで打ったら反応するだろうと思ってやってみたのですが…パネル面の接触時間が短すぎるせいか、まったく反応しなかったというオチでした。実現できればkernel/vmの名誉ある称号「ベストオブあたまおかしい」も狙えたと思っていたのですが残念です。 参考 カーネル/VM探検隊@名古屋 1回目 第一回 カーネル/VM探検隊@名古屋(前半) #kernelvm 第一回 カーネル/VM探検隊@名古屋(後半) #kernelvm
PetitModem 1.2.2をプチコン3号3.2.0で動かす
任天堂3DSで動くBASIC処理系プチコン3号というものがあります。 基本的にタッチパネルでのソフトウェアキーボードしか入力手段がないのですが、音声経由でデータをやりとりするPetitModemというソフトウェアをれいさんという方が公開されています。 しかし最近のプチコン3号のアップデート(3.2.0)で動かなくなってしまったので、暫定的な対応策を行いました。作者のれいさんには連絡済なので、いずれ修正版がリリースされるはずですが、取り急ぎ修正方法を記録しておきます。対象バージョンはPetitModem 1.2.2です。 771行目、DEF FILLをDEF FILL2等に変更する 1035行目、A=1/0となっている箇所をA=A/0に変更する 3.2.0になって、FILLという命令が新設されたため、DEF FILLは多重定義エラーになります。FILLはプログラム中で実際には使っていないようなので、適当な名前に変えるか消すかでこの問題は解決できます。 もう一つの変更点として、それまで実行時に演算していたと思われる定数の数式が、初回バイトコードコンパイル時に行われるように変わったようです。1035行目のコードは、エラー処理コードであり、わざと0除算を発生させて強制終了させるために書かれていたコードなのですが、これが新しい仕様では実行前に評価されてしまうため動かなくなっています。なので変数を0除算させるように書き換えることで対応できます。 いずれにせよ、公式な修正はそのうち出ると思われますが、今すぐどうにかしたいという方はこれで対処してみてください。
LanguageToolで長音記号チェック
漢字変換ミスで、たまに長音記号がかな文字以外の後に置かれる事例を見かけたので、それをLanguageToolのルールにして取り込んでもらいました。 現状ある日本語のルールをざっと見たのですが、うまい具合に表現する方法が思い浮かばなかったので、思い切ってメーリングリストで聞いてみました。 メイン開発者のDanielさんは親切で反応も早い方で、「正規表現でUnicodeの範囲を使えばできる」という方法を示してくれました。また、過去にも日本語のルールを書いているSilvanさんからは、JavaにおけるUnicodeのクラス表現(\p{IsXxx})を紹介してくれました。 これらを踏まえ、以下のようなルールをpull requestとして書き、無事masterにマージしてもらえました。 カタカナとひらがな以外が長音記号の前にあるとき、LanguageToolは警告を出します。 この機会に、Doc-ja Wikiの”LanguageTool使い方メモ“も若干修正しました。自前のgrammar.xmlを指定して起動する方法と、ソースコード上で変更をしたときにルールのテストをする方法について新た説明を加えています。 LanguageToolのリリースバージョンは現在2.9ですが、次期バージョン3.0ではgrammar.xmlの書式も変わっているため、いずれWiki内の説明もそちらに合わせて修正したいところです。