mots quotidiens.
Daichi Mochihashi (持橋大地) daichi <at> ism.ac.jp by hns, version 2.10-pl1.

先月 2008年12月 来月
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

2008年12月28日() [n年日記]

#1 logging

学習プログラムを動かす際に, パラメータ設定その他が後で わからなくなってしまうことがあるので(注: 自然言語処理はデータ量が多いので, 学習は通常数時間から数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: 計算が長いと, この計算をどのサーバで行っているのかわからなくなったりします。 これまではノートや, テキストファイルに書いておくというローテクなことをして いました。;

1 days displayed.
タイトル一覧
カテゴリ分類
 なかのひと
Powered by hns-2.10-pl1, HyperNikkiSystem Project