2008-03-24
■Evernoteβ 結構よいかも
- デスクトップアプリケーションが存在する
- Web←→デスクトップアプリケーションのシンクロ可能
- 複数台のマシンでもOK(そのうち、わざと衝突させてみようと思う)
- Mac OS X (Leopard)、Windows Mobile のアプリケーションもある(私は使ってない)
- UIはケレン味がなくスッキリ
- 日本語対応はまだまだ(サムネイルが駄目。入力できるがシンクロできない文字もある)
- GoogleDesktop にプラグインが入った。まだ試してない
- デスクトップアプリケーション自身もインデクシングできるみたいな感じだが試してない。確認してない
今はβ中なので、申し込んでから使えるようになるまで、何日かかかると思う。
■サニタイズ言うなキャンペーン発動中
「信頼できないデータ」という答えしかない。
サニタイズする項目一覧でわかりやすいのを探しています。
http://q.hatena.ne.jp/1206314825
質問の意図は判る。
うっかり忘れたりしないように"一般に信頼できないとされるデータが羅列されているリストがあったらいいなぁ"ということだ。
問題視するべきはそれを「サニタイズする項目一覧」の一言で片づけていること。
その一覧に載っていない項目は気にしなくていいわけではない。
サニタイズがなんなのかをどう捉えているかが判らない。
信頼できる/できないは、考え、決定するしかない。答えはない。
ある時まで信頼できるものであったものが、次の瞬間に信頼できないものになる、なんてセキュリティでは当たり前。
既存のリストに頼るという姿勢が、危険。
■少し変わった子あります 読了
軽い読み物、と思っていたらとんでもない。
ここ最近の森作品では最高の切れ味だった*1。
ストーリィが希薄。
森作品の特徴ではあるが、この本は極めてそれが色濃く出ている。
なぜそう感じるかというと、それに加えて人間関係までもが希薄だから。
ストーリィも人間関係もない。
言葉の力のみが圧倒的に、直截に迫ってくる。
最後の章に隠された、ほんのわずかな「差」が、読者の方に向けられた切っ先に思われて、少し震えた。
■影を作る時に回転してはいけません
先日も紹介した"Photoshop Disasters"から2つほど、同じ様な間違いをしている写真。
PSD: Photoshop Disasters: Readers Digest: Maybe It's A VampirePhone
PSD: Photoshop Disasters: Shimano: Righty Tighty Lefty Loosey
下の方に映り込みっぽい"影"を描くのにうっかり回転を使っちゃったということか。
(追記)2008/03/26
こういう"映り込み"が流行りなんだろうけど、逆にその辺りの標準的な手順が確立されてないのかも。
また似たようなエントリが上がっていた。
PSD: Photoshop Disasters: Apple: Huge Goof, Jobs, Entire Board To Resign
*1 注:最近はハードカヴァでは買っていないことを記しておく。
2008-03-23
■Perforce Merge を使ってみる
資料
EUC-JP のファイルが化けてしまって使えない。
選択肢の中に、Japanese(EUC-JP)があるのに……。
検索してみると、Release Note で"EUC-JP の扱いを直したよ"という表記が。
あれ? と思ったら、何のことはない。古いバージョンをインストールしていたのであった。
新しいのに入れ直したら解決するかな?
(追記)解決した
■今日もtDiary2.2.x 系へのアップデートできず
操作ミスなどもあってうまくマージできんかった……。
2008-03-22
■classという文 そして プライベートインスタンスメソッド
Rails' Wiki - Rails勉強会@東北第9回 で出た話題を復習した。
rubyはクラスを定義した時にクラスメソッドを実行することが出来て、
このin_place_edit_forはクラスメソッドなんですよ。
quintia:うわー!そうだったのかー。
2008-03-19 - 福島でRailsを使って仕事を頑張る計画
この quintia が私。
さて、「クラスを定義した時にクラスメソッドを実行することが出来て」は多分厳密には正しくないのではないかと思います。(追記)取り消して書き直しました
さて、「クラスを定義した時にクラスメソッドを実行することが出来て」の部分は当然ではあるのですが、けれどこの場合、in_place_edit_for がクラスメソッドだというのはちょっとピンときません。
レシーバが曖昧なのです。
以下復習したことをまとめてみましょう。
Rails の in_place_edit_for は敷居が高いので、
class Foo attr_accessor :foo attr_reader :bar attr_writer :baz end
の attr_accessor, attr_reader, attr_writer を考えましょう。
これは実はメソッドなのですね。(http://www.ruby-lang.org/ja/man/html/Module.html#attr_accessor 参照)
ところでRuby ではクラス定義も"文"の実行です。
class〜end でクラス定義"文"を作っているんです。
さて、クラス定義文の実行中の self、つまりメソッドの実行主体――Ruby では"レシーバ"と呼ばれますね――は何なのでしょう?
Fooクラスです。
といってもこれでは誤解を招くので噛み砕きます。
まず Foo というのは"定数"です。定数の形式を思いだしてください。"英大文字で始まること"でした。
Ruby で俗に"クラス名"と呼んでいるものの正体は、実は"定数"なのです(文法上は)。
定数Fooが指しているものは何でしょう?
Classというクラスがあります。
定数Fooは"Classクラスのインスタンス"になります。
class Foo p self.class.name # =>"Class" end
で確認できます。
(実行した時の結果を # => というコメントで表記するという慣例に従ってます)
attr_accessor は、Moduleクラスのプライベートインスタンスメソッドなのですが(先に提示したリンク先のページをよく見てください)、ClassクラスがModuleクラスを継承しているので、クラス定義式の中で使えます。
class Foo attr_accessor :foo end
を、省略されている色んなものを書き足すと、
class Foo self.attr_accessor(:foo) end
という感じになります(ただしプライベートインスタンスメソッドなので本当にこのようには書けません。"概念的にはこんな感じ"という比喩です)。
ここに書いた self は先に書いた様に定数Fooが指しているものにほかならず、それはClassクラスのインスタンスです。
だから、この場所から、プライベートインスタンスメソッドを呼び出せるのです。
そしてattr_accessor メソッドは、レシーバにシンボルと同じ名前の、最も単純な形での"呼び出しメソッド"と"代入メソッド"を作ります。
もう一度書きましょう。
attr_accessor メソッドは、"メソッドを作るメソッド"なのです。
それによって、
class Foo
def foo
@foo
end
def foo=(val)
@foo = val
end
end
と等価になるのです。
ここまで書けば、勘のいい人は気づくのでしょうが、メソッド定義である def も"文"であって、def〜end がメソッド定義"文"になりです。
メソッド定義文内の self (レシーバ)は、Fooクラスのインスタンスです。
これはまぁ、当たり前ですね。
class Foo
def foo
p self.class.name #=>"Foo"
end
end
あとは余談。
クラス定義文もメソッド定義文も、ちゃんと値を返してくれて、変数に代入することができたりします。
nilですけどね……。
a = class Bar end p a #=> nil
class Baz a = def baz end p a #=> nil end
もしくはグローバル変数を使うと
class Baz $a = def baz end end p $a #=> nil
てな感じです。
ずっと昔には理解できていたことなのかもしれませんが、すっかり忘れていました。
Rails はこういう仕組みをバンバン使ってますよ〜、ということでした。
復習終わり。
■仮面ライダーカブト GOD SPEED LOVE 見た
というか子どもたちに見せていたというか。
時間ものは難しい。色々と目をつぶらないといけないことはあるものの、面白かった。
番外編の様でいて、本編と重なっている。重なっているようで繋がらない。
そんな微妙さがいいさじ加減。
2008-03-21
■書きかえられたアトム
(BK1内容説明)
単行本化に際し、手塚治虫は何度も「鉄腕アトム」の原稿を描きかえている。どこがどう変わったのか、雑誌初出時の図版と比較し、オリジナルの持つ魅力をいま一度呼び起こす。
永遠のβ版? < 違う
■シンメトリーとモンスター
モンスターって何? と思った。
えーと……、
この辺りか。
むむむ。面白そうだけど、せめてガロア体やアーベル群ぐらいは(ある程度)理解したあとじゃないとなぁ。という気もする。
■CDをejectするショートカットの作り方
Create a Shortcut or Hotkey to Eject the CD/DVD Drive - How-To Geek
"MacintoshのCDの取り出し方"が、先日のRail勉強会@東北の懇親会でちょっと話に出てたなぁ……。
via
■日本のタクシーのライトが海外で紹介されている
しかも丁寧に、
- Shibuya, Tokyo
- Utsunomiya, Tochigi Prefecture
- Aizuwakamatsu, Fukushima
- Hiroshima City
- Fukuoka City
南東北から北九州まで。
英語が読めなくても、眺めているだけでも楽しめるかも。
via
■CNET iPhone UI と それを支えるライブラリ
という記事の様に見えるのだけど、ちゃんと読んでいない。
こっちが紹介記事。
Product reviews and prices, software downloads, and tech news - CNET
こっちが、Javascriptのライブラリ。
Product reviews and prices, software downloads, and tech news - CNET
mootoolsというライブラリとの関係が読めていない。mootools に依存しているのか、あるいは、mootools のサブセット+αなのか、そのどちらかだとは思うけど……。
■PS3 次のファームではDVD/BDにレジューム機能追加予定
素直に嬉しい。
Resume Play - begin playing a DVD or BD disc from the point where you previously stopped it,
PlayStation.Blog >> Firmware v2.20 bringing BD-Live to PS3
2008-03-20
■コミュニケーションのための「空間」
(BK1内容説明より)
研究開発の知的生産性向上に有効なダイレクトコミュニケーション。その活発化のために何が必要か、全体像を提示。また、知的生産性を直接引き上げる施策を「スキル」「マネジメント」「空間」という3つの切り口で紹介する。
「空間」大事。
そこをなんとかする権限をマネージャーが与えらないといけない、ということを会社が(というのはつまり上司とか上司の上司とかが)理解してないと……。
図書館に入らないかね。
■パーセプトロン……忘れたよ!
見た目上のパラメータ次元数が10×10の100あって、10クラスを分類しようとするのは確かに無理っぽいような気もするけど。
こういうのは数式とか見てるよりも実際にいじっている人じゃないと分からないんだろうなぁ。
1つだけ明確に直すべきだと判断できるのは、上下左右の空白部分を学習に入れてしまっているあたり。
g2.drawImage(img, 0, 0, mesh, mesh, this);
2008-03-18 - きしだのはてな
10×10のmeshに黒画素の濃度を入れて学習に使っているけど、数字の大きさや、書いた位置に左右されてしまう。
なので、上下左右の空白部分を除去した形で、meshを作りたい。
もっとも簡単な正規化を、もっとも頭悪いコードで実装してみる。
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class Perceptron extends JComponent implements ActionListener, MouseMotionListener{
// Image img = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
BufferedImage img = new BufferedImage(300, 300, BufferedImage.TYPE_INT_RGB);
Graphics bg = img.getGraphics();
Point pt;
final int mesh = 10;
double[][][] perc = new double[10][mesh][mesh];
double[] b = new double[10];
double k = 0.1;//学習係数
public static void main(String[] args){
JFrame f = new JFrame("パーセプトロン");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(320, 400);
//描画領域
Perceptron pc = new Perceptron();
pc.addMouseMotionListener(pc);
pc.clear();
f.add(pc);
//数字ボタン
JPanel p = new JPanel();
p.setLayout(new GridLayout(2, 5));
for(int i = 0; i < 10; ++i){
JButton b = new JButton(i +"");
p.add(b);
b.addActionListener(pc);
}
f.add(p, BorderLayout.SOUTH);
//判定ボタン
JButton b = new JButton("判定");
b.addActionListener(pc);
f.add(b, BorderLayout.NORTH);
//ウィンドウ表示
f.setVisible(true);
}
/** ボタンが押されたときの処理 */
public void actionPerformed(ActionEvent e) {
//手書き結果を学習メッシュに合わせる
BufferedImage bi = new BufferedImage(mesh, mesh, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) bi.getGraphics();
Rectangle destArea = noWhiteArea(img);
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
// g2.drawImage(img, 0, 0, mesh, mesh, this);
g2.drawImage(img, 0, 0, mesh, mesh,
destArea.x, destArea.y,
destArea.x + destArea.width,
destArea.y + destArea.height, this);
if("判定".equals(e.getActionCommand())){
//判定ボタンの処理
double mr = 0;
int ans = -1; //認識失敗???
for(int i = 0; i < 10; ++i){
double r = 0;
for(int x = 0; x < mesh; ++x){
for(int y = 0; y < mesh; ++y){
double d = (255 - bi.getRGB(x, y) & 255) / 255.;
r += d * perc[i][x][y];
}
}
r += b[i];
System.out.printf("%d:%.2f ", i, r);
if(mr < r){
mr = r;
ans = i;
}
}
System.out.println("\n答えは" + ans);
clear();
return;
}
//数字ボタンが押されたときの学習処理
int idx = Integer.parseInt(e.getActionCommand());
for(int i = 0; i < 10; ++i){
double yi = (i == idx) ? 1 : -1;
double in = 0;
for(int x = 0; x < mesh; ++x){
for(int y = 0; y < mesh; ++y){
double d = (255 - bi.getRGB(x, y) & 255) / 255.;
in += d * perc[i][x][y];
}
}
in = (in + b[i]) * yi;
System.out.printf("%d:% .2f ", i, in);
if(in <= 0){
//再学習
for(int x = 0; x < mesh; ++x){
for(int y = 0; y < mesh; ++y){
double d = (255 - bi.getRGB(x, y) & 255) / 255.;
perc[i][x][y] += d * k * yi;
b[i] += k * yi;
}
}
}
}
System.out.println();
clear();
}
/** マウスで描画 */
public void mouseDragged(MouseEvent e) {
Point old = pt;
pt = e.getPoint();
if(old != null){
bg.setColor(Color.BLACK);
((Graphics2D)bg).setStroke(new BasicStroke(25));
bg.drawLine(old.x, old.y, pt.x, pt.y);
repaint();
}
}
public void mouseMoved(MouseEvent e) {
pt = null;
}
//描画
@Override
protected void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, this);
}
private void clear(){
bg.setColor(Color.WHITE);
bg.fillRect(0, 0, 300, 300);
repaint();
}
public Rectangle noWhiteArea(BufferedImage img) {
Rectangle ret = new Rectangle();
Graphics2D g2 = (Graphics2D) img.getGraphics();
BREAKTOP:
for (int x=0; x<300; x++) {
for (int y = 0; y< 300; y++){
if ((img.getRGB(x,y) & 255)==0) {
ret.x = x;
break BREAKTOP;
}
}
}
BREAKLEFT:
for (int y=0; y<300; y++) {
for (int x = 0; x< 300; x++){
if ((img.getRGB(x,y) & 255)==0) {
ret.y = y;
break BREAKLEFT;
}
}
}
BREAKDOWN:
for (int x=299; x>=0; x--) {
for (int y = 299; y >= 0; y--){
if ((img.getRGB(x,y) & 255)==0) {
ret.width = x - ret.x;
break BREAKDOWN;
}
}
}
BREAKRIGHT:
for (int y=299; y>=0; y--) {
for (int x = 299; x>= 0; x--){
if ((img.getRGB(x,y) & 255)==0) {
ret.height = y - ret.y;
break BREAKRIGHT;
}
}
}
return ret;
}
}
最後のメソッドの追加と、mesh に drawImage する時にそこから範囲を指定しているところが大きな修正点。
Rectangle destArea = noWhiteArea(img);
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
// g2.drawImage(img, 0, 0, mesh, mesh, this);
g2.drawImage(img, 0, 0, mesh, mesh,
destArea.x, destArea.y,
destArea.x + destArea.width,
destArea.y + destArea.height, this);
黒画素が存在する矩形部分だけを、mesh に対して drawImage してみました、ということ。
あとは些末。
……マシになったような気もするけど、気のせいと言われればそんな気も。
データ集合を準備して、ちゃんと学習データと、認識用のデータを固定しないと、評価はできませんねぇ。
■音源調整の革命……かも
まずはムービーを見るべし。ダウンロードした方がいいかも。
これ、すごい!
すごい、と思うのは、フーリエ変換して周波数特性を見る、なんてことを大学の時にかじったからかもしれないけど、でもこれって、Photoshop (の様なソフト)がデジタルな写真加工に革命をもたらしたのと同じことが、音楽の世界でも起きるかもしれないってことでは?
ちょっとしたミスでもデジタルで調整すればいいや、みたいな。
いや、今でもある程度のことは出来るんだろうけど、それがさらに加速する、てなことを想像してる。
面白い。

