学習中のPrintReportの出力を増やす方法

2,293 views
Skip to first unread message

s.h.

unread,
Jun 13, 2017, 1:39:04 PM6/13/17
to Chainer Japanese User Group
初投稿でいきなり申し訳ありません。
学習中にF値などを画面に出力したいと考えています。
そこで、Classifierの__call__部分を以下のように書き換えました。

    def __call__(self, x, t):
        y = self.predictor(x)
        loss = F.softmax_cross_entropy(y, t)
        accuracy = F.accuracy(y, t)
        summary = F.classification_summary(y, t, beta = 1.0)
        precision = summary[0]
        recall = summary[1]
        f_value = summary[2]
        report({'loss': loss,
                'accuracy': accuracy, 
                'precision': precision,
                'recall': recall,
                'f_value': f_value}, self)
        return loss


また、trainer.extendを以下のようにしました。(recallやprecisionはまだ追加していません)

trainer.extend(extensions.PrintReport( ['epoch', 
                                                 'main/loss',
                                                              'validation/main/loss',
                                                              'main/accuracy', 
                                                              'validation/main/accuracy',
                                                              'main/f_value']))

しかし、学習の画面ではmain/f_valueには何も出力されません。
trainerやLogReportなどをいまいち理解できておりません。どのようにすれば表示が可能になりますか。
ご教授ください。よろしくお願いします。

Kenta Oono

unread,
Jun 13, 2017, 7:55:08 PM6/13/17
to Chainer Japanese User Group
大野です

PrintReportはLogReportが溜めたロスなどの値を標準出力に出力しています。
TrainerとLogReportの設定がデフォルトならば、LogReportの出力結果はresultディレクトリ内のlogというファイルに出力されています。
ここにmain/f_valueのキーが存在しなかったら、Reporterを用いたレポート部分、もしくはLogReportによる結果の書き込みが正しく行われていないと思われます

2017年6月14日水曜日 2時39分04秒 UTC+9 s.h.:

s.h.

unread,
Jun 14, 2017, 11:40:31 AM6/14/17
to Chainer Japanese User Group
resultディレクトリ内のlogファイル内にはf_valueの出力が行われておりませんでした。
ご指摘の通り、LogReportによる書き込みが正しく行われていないということだと思います。
以下が、Mnistに用いたコードの全容なのですが、具体的にどのように書き込めば良いかサンプルなどの提示はお願いできますでしょうか。

## module import

import chainer
import chainer.functions as F
import chainer.links as L
from chainer import training, Reporter, report, report_scope
from chainer.training import extensions
from numpy import *
from scipy import *
from scipy.io import loadmat
import numpy as np
from chainer import datasets

## define networks
class MYNN(chainer.Chain):
    def __init__(self):
        super(MYNN,self).__init__()
        with self.init_scope():
            self.bn0 = L.BatchNormalization(784)
            self.h0 = L.Highway(784)
            self.l1 = L.Linear(100)
            self.h1 = L.Highway(100)
            self.bn1 = L.BatchNormalization(100)
            self.bn2 = L.BatchNormalization(100)            
            self.l2 = L.Linear(10)
            self.bn3 = L.BatchNormalization(10)

    def __call__(self,x):
         h = self.bn0(x)
         h = self.h0(h)
         h = F.dropout(h, ratio=0.2)
         
         h = F.relu(self.bn1(self.l1(h)))
         h = F.dropout(h, ratio=0.2)
         
         h = self.h1(h)
         h = self.bn2(h)
         h = F.dropout(h, ratio=0.2)
         
         h = self.bn3(self.l2(h))
         return h

class Classifier(chainer.Chain):
    def __init__(self, predictor):
        super(Classifier, self).__init__()
        with self.init_scope():
            self.predictor = predictor
        
    def __call__(self, x, t):
        y = self.predictor(x)
        loss = F.softmax_cross_entropy(y, t)
        accuracy = F.accuracy(y, t)
        summary = F.classification_summary(y, t, beta = 1.0)
        precision = summary[0]
        recall = summary[1]
        f_value = summary[2]
        reporter = Reporter()
        observer = object()
        reporter.add_observer('f_value:', observer)
        observation={}    
        with reporter.scope(observation):
            reporter.report({'x':f_value},observer)    
        report({'loss': loss,
                'accuracy': accuracy, 
                'precision': precision,
                'recall': recall,
                'f_value': f_value}, self)
        return loss

model = Classifier(MYNN())
optimizer = chainer.optimizers.Adam()
optimizer.setup(model)
optimizer.add_hook(chainer.optimizer.WeightDecay(0.01))
#optimizer.add_hook(chainer.optimizer.Lasso(0.1))
#optimizer.add_hook(chainer.optimizer.GradientNoise(0.01))

## data import
train, test = datasets.get_mnist()
train_iter = chainer.iterators.SerialIterator(train, batch_size=100, shuffle=True)
test_iter = chainer.iterators.SerialIterator(test, batch_size=100, repeat=False, shuffle=False)


## training
updater = training.StandardUpdater(train_iter, optimizer, device=-1)
trainer = training.Trainer(updater, (100, 'epoch'), out="result")
trainer.extend(extensions.ExponentialShift('alpha',rate = 0.9999999))
trainer.extend(extensions.LogReport())        ←ここの部分に書き込みが必要ということでしょうか?
trainer.extend(extensions.PrintReport( ['epoch', 
                                        'main/loss',
                                        'validation/main/loss',
                                        'main/accuracy', 
                                        'validation/main/accuracy',
                                        'main/f_value']))
trainer.extend(extensions.ProgressBar())
trainer.extend(extensions.Evaluator(test_iter,model,device = -1))
trainer.run()



Kenta Oono

unread,
Jun 15, 2017, 3:38:05 AM6/15/17
to Chainer Japanese User Group
大野です。

現状reportメソッドで記録できる値はスカラー値(np.isscalarがFalseである)のみで、
それ以外のものをレポートしようとすると無視します。
f_valueは配列を保持したVariableであるため、f_valueは記録されていませんでした。

現状だと、配列をレポートする場合には、要素を1つ1つレポートする必要があります:
report(dict(('f_value_%d' % i, val) for i, val in enumerate(f_value)}, self)


2017年6月15日木曜日 0時40分31秒 UTC+9 s.h.:

s.h.

unread,
Jun 15, 2017, 8:54:31 AM6/15/17
to Chainer Japanese User Group
返答ありがとうございます。
Trainerを使い始めて日が浅く、まだ十分に理解できていない点もありましたが、丁寧な回答が頂けたので解決できました。
ありがとうございます。
Reply all
Reply to author
Forward
0 new messages