学習プログラムを動かす際に, パラメータ設定その他が後で
わからなくなってしまうことがあるので(注: 自然言語処理はデータ量が多いので,
学習は通常数時間から数10時間かかる),
それら+αの記録のために, logging というクラスを定義しておくことを
思いついた。
*1
class logging {
logging (char *argv[], char *file);
~logging ();
};
のようなクラスを定義しておくと, mainで
#include "log.h"
int main (int argc, char *argv[])
{
while ((c = getopt(argc, argv, opts)) != -1)
何とか..
logging start (argv, model);
学習本体;
}
のようにするだけで, model.log にコンストラクタでargv,起動時刻,ホスト名
*2
などの情報が
書き込まれ, デストラクタで終了時刻が自動的に記録される。以下のような感じ。
init : ./spylm -n 1 -e 1e-8 -a 4 -b 1 -N 2 ../data/genji.txt genji.model
host : samurai5.cslab.kecl.ntt.co.jp
start : Mon Dec 29 00:06:56 2008
--------
iter[0] char height = 9
iter[0] char height = 9
--------
finish : Mon Dec 29 00:10:39 2008
start というのはただの名前ですが, こうやって使うといかにも記録をスタート
したかのように見えると思います。
logging.cpp の中身は大体こんな感じ。
#include <cstdio>
#include <cstdlib>
#include <cstdarg>
#include <unistd.h>
#include <ctime>
static FILE *lp = NULL;
logging::logging (char *argv[], char *file)
{
char *s, hostname[BUFSIZ];
time_t timer;
if ((lp = fopen (strconcat(file, ".log"), "w")) == NULL)
{
perror("fopen");
exit(1);
}
time(&timer);
gethostname(hostname, BUFSIZ);
fprintf(lp, "init :");
while (s = *argv++) fprintf(lp, " %s", s);
fprintf(lp, "\n");
fprintf(lp, "host : %s\n", hostname);
fprintf(lp, "start : %s", ctime(&timer));
fprintf(lp, "--------\n");
fflush(lp);
}
logging::~logging ()
{
time_t timer;
time(&timer);
fprintf(lp, "--------\n");
fprintf(lp, "finish : %s", ctime(&timer));
fclose(lp);
}
void
init_log ()
{
if ((lp = fopen (DEFAULT_LOG_FILE, "w")) == NULL)
{
perror("fopen");
exit(1);
}
}
int
lprintf (const char *fmt, ...)
{
int n;
va_list ap;
if (lp == NULL) init_log ();
va_start(ap, fmt);
n = vfprintf(lp, fmt, ap);
va_end(ap);
fflush(lp);
return n;
}
中で lprintf() という関数を定義してあるので,
これを使うと他の情報もログファイルに自動的に書き込める。
学習の途中で尤度等を記録しておくのによさげです。
もしかするとこういうテクは既に知られているのかも知れないですが,
lprintf()みたいなものを絡めたものは多分ないと思うので, 書いてみました。
*1: 調べると似たようなものはあるようですが, ここでは最小限のもの,
という感じです。
*2: 計算が長いと, この計算をどのサーバで行っているのかわからなくなったりします。
これまではノートや, テキストファイルに書いておくというローテクなことをして
いました。;