Hatena::ブログ(Diary)

お前の血は何色だ!! 4 このページをアンテナに追加 RSSフィード Twitter

2017-01-15

ナノ秒単位の高性能な時刻がほしい時

beagleboneやraspberry piで、ナノ秒単位の正確な時間がほしい時について。

通常のtime関数とかでは遅すぎて困るときは、以下のようにすると、ナノ秒単位で時刻が取れます。

値は、CPUとかの動作クロックの影響をうけるので注意してください。

ボードメモリ位置バイト長
beaglebone0x4804003C4バイト
raspberry pi 2-30x3F0030044バイト

このメモリ位置は常にカウントアップされていきます。

値はunsigned int値で、オーバーフローすると0に戻ります。

ここを読みだすことでとても正確な時間を取得することができます。

今何時?という用途にはまったく使えませんが、処理時間の間隔を正確に測るとかの用途に向いています。


カーネルランドで読みだす場合は、 ioremapが便利だと思う。

//ナノ秒単位の高性能な時刻がほしい時。
//kernel land
void *g_timer = ioremap(0x4804003C,4); //beaglebone
void *g_timer = ioremap(0x3F003004,4); //raspberry pi 2-3

//一番オーバーヘッドを生まないであろうマクロ展開で読みだす.
#define dmtimer_get()  ((unsigned int)ioread32(g_timer))

printk(KERN_ALERT "timer: %u\n", dmtimer_get() );

iounmap(g_timer);

ユーザランドで読みだす場合は、 mmapするよろし。

//ナノ秒単位の高性能な時刻がほしい時。
//userland
int g_fd = open("/dev/mem", O_RDWR | O_SYNC);
if (g_fd < 0)
{
	printf("Could not open /dev/mem fd\n");
	return -1;
}

//mmap確保
//0x3F003004 とかを直接mmapすると落ちるので、ちょい手前から 0x100ぐらい適当に確保する.
//void* g_mmap = ( unsigned int*) mmap(NULL, 0x100, PROT_READ,MAP_SHARED,g_fd, 0x48040000); //beaglebone
unsigned int* g_mmap = ( unsigned int*) mmap(NULL, 0x100, PROT_READ,MAP_SHARED,g_fd, 0x3F003000); //raspberry pi 2-3
if (g_mmap == MAP_FAILED) {
	printf("Could not mmap %d\n",g_mmap);
	close(g_fd);
	g_fd=0;
	return -2;
}
//unsigned int* g_timer = &g_mmap[0x3C/sizeof(int)]; //0x4804003C
unsigned int* g_timer = &g_mmap[0x4/sizeof(int)]; //0x3F003004

//一番オーバーヘッドを生まないであろうマクロ展開で読みだす.
#define dmtimer_get()  (*g_timer)

for(int i = 0 ; i < 10 ;i++)
{
	printf("timer: %u\n", dmtimer_get() );
	sleep(1);
}

//unmap(g_mmap)を呼び出さなくてもプロセス終了時には自動解放される 
close(g_fd);

この高性能タイマー機能の名前がよくわからないのだが、dmtimer とか、high level timer とか、いろいろ名前があるらしい。

検索しにくいから統一させてほしいものである。

2017-01-13

最初にコンピュータに仕事を奪われた人たち

AIの発達で、コンピュータが仕事を奪うという人達がいる。

確かに、近年のAIの進化は素晴らしく、幾つかの分野で人間を超える成績を出すものがある。

だが、忘れてはいけない。はるか昔にコンピュータに仕事を奪われた人がいたことを。

はるか昔に、コンピュータに仕事を奪われた人たち、それはコンピュータだ。

何言っているんだお前と思うかもしれないが、weikipediaにもちゃんと載っている。

https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF

英語の 「computer(コンピューター)」は算術演算(数値計算)を行う人を指す言葉だった。

computer というのは、もともとは計算をする人をさす言葉だった。

それが機械の方のコンピュータが発達して、驚異的な演算能力があったためだろうか、いつしかコンピュータは機械の方のコンピュータをさす言葉になってしまった。

そして、もともとコンピュータというのが職業だったというのも忘れ去られようとしている。


コンピュータに最初に仕事を奪われた人たちは、コンピュータだった。

私たちにできることと言えば、コンピュータが仕事を奪うと言うが、最初にコンピュータに仕事を奪われた人たちって、コンピュータだよねみたいな、このことを知らないと意味不明な文章を言って遊ぶことぐらいだろうか。

2017-01-06

keras_iris_test

python初心者が kerasを使って、定番のiris分類をやった。

前回chainer使って作ってみたので、次はkerasでやってみようということで。

#
#とりあえず動くところまで作った iris分類.
#
import argparse
import numpy
import keras
from keras.layers.core import Dense, Dropout, Activation, Flatten
#from keras.layers.convolutional import Convolution2D, MaxPooling2D
numpy.random.seed(1192)  # for reproducibility

#分類した結果が文字列なので [0,1,2] という数字に変換する
def iris_name_to_index(s):
    if s == b'setosa':
        return 0   #正解データは0からスタートしないとダメ
    elif s == b'virginica':
        return 1
    elif s == b'versicolor':
        return 2
    else:
        print("Unknown Data:{}".format(s))
        raise()

#逆に、数字から、setosa/virginica/versicolor に変換する.
def iris_index_to_name(i):
    if i == 0:
        return 'setosa'
    elif i == 1:
        return 'virginica'
    elif i == 2:
        return 'versicolor'
    else:
        print("Unknown Label:{}".format(i))
        raise()


# 引数の処理
parser = argparse.ArgumentParser()
parser.add_argument('--mode',      type=str,   default='all') #train:学習だけ pred:分類だけ all:両方
parser.add_argument('--epoch',     type=int,   default=500) #何回学習を繰り返すか
parser.add_argument('--trainstart',type=int,   default=0)   #全データ150件のうち、何件から学習に使うか
parser.add_argument('--trainsize', type=int,   default=50)  #全データ150件のうち、何件を学習に使うか ディフォルト(150件中 0件から50件までを学習に使う)
parser.add_argument('--trainbatch',type=int,   default=50)  #学習するミニバッチに一度にかけるデータの個数
args = parser.parse_args()

#csv読込
#最初の4つが学習データ 最後の5番目が正解データ
csv = numpy.loadtxt("iris.csv",
    delimiter=",",                    #csvなので  , で、データは区切られている
    skiprows=1,                       #ヘッダーを読み飛ばす
    converters={4:iris_name_to_index} #4カラム目は分類がテキストでかかれているので 0から始まる数字ラベルに置き換える
    )

#学習データの定義
#学習データは float32の2次元配列
#例: [ [1,2,3,4],[5,6,7,8],[1,2,3,4],[5,6,7,8],[1,2,3,4] ].astype(numpy.float32)
data = csv[:,0:4].astype(numpy.float32)

#正解データの定義
#正解データは 0から始まる int32の1次元配列
#例: [ 0,1,2,1,0 ].astype(numpy.int32)
label= csv[:,4].astype(numpy.int32)

#学習
if args.mode in ['all','train']:

    model = keras.models.Sequential()
    model.add(Dense(100,input_dim=4))
    model.add(Activation('relu'))
    model.add(Dense(100))
    model.add(Activation('relu'))
    model.add(Dense(3))
    model.add(Activation('softmax'))

    model.compile(loss='sparse_categorical_crossentropy',
                  optimizer='adam',
                  metrics=['accuracy'])

    x = data[args.trainstart:args.trainstart+args.trainsize]
    y = label[args.trainstart:args.trainstart+args.trainsize]

    model.fit(x, y ,batch_size=args.trainbatch,nb_epoch=args.epoch,verbose=1)

    #学習結果を保存.
    model.save("model.dat")

#分類
if args.mode in ['all','pred']:

    #学習結果を読み込む
    model = keras.models.load_model("model.dat")

    #すべてのデータに対して、1件ずつ、分類を答えさせて、正しいか採点する.

    #keras組み込みの evaluateメソッドで一発なんだけど、 表示をこりたいので、forを回すよ.
    #score = model.evaluate(data, label, verbose=1)
    #print(score)

    ok_count = 0
    for i in range(len(data)):
        x = data[i:i+1]        #このデータについて調べたい.

        y = model.predict(x, batch_size=1, verbose=0) #分類の結果を取得

        pred = numpy.argmax(y)    #3つの分類のうち、どれの確率が一番高いのかを返す
        if label[i] == pred:
           ok_count = ok_count + 1
           #print("OK i:{} pred:{}({}) data:{}".format(i,iris_index_to_name(pred),iris_index_to_name(label[i]),data[i:i+1] ))
        else:
           print("NG i:{} pred:{}({}) data:{}".format(i,iris_index_to_name(pred),iris_index_to_name(label[i]),data[i:i+1] ))

    print("total:{} OK:{} NG:{} rate:{}".format(len(data),ok_count,len(data)-ok_count,ok_count/len(data)) )

ソースコードgithubにある https://github.com/rti7743/keras_iris_test

chainer_iris_testを改変してkeras版を作ったのでデータに対してはそれほど苦労としていない。

また、kerasは Tensorflowとかのラッパーであり、Tensorflowwindowsインストール方法の解説が公式サイトに書いてあり、それが chainerのGPU対応ビルドと方法がほとんど同じなので、これも苦労しなかった。


Using TensorFlow backend.
Traceback (most recent call last):
  File "test.py", line 85, in <module>
    model.fit(x, y ,batch_size=args.trainbatch,nb_epoch=args.epoch,verbose=1)
  File "keras\models.py", line 664, in
fit
    sample_weight=sample_weight)
  File "keras\engine\training.py", line
 1068, in fit
    batch_size=batch_size)
  File "keras\engine\training.py", line
 985, in _standardize_user_data
    exception_prefix='model target')
  File "keras\engine\training.py", line
 113, in standardize_input_data
    str(array.shape))
ValueError: Error when checking model target: expected activation_3 to have shap
e (None, 3) but got array with shape (50, 1)

しかし、罠がなかったわけではない。

model.compile時に loss='categorical_crossentropy'を使うと上記エラーが発生して動かなかった。

いろいろ調べてみると、loss='categorical_crossentropy' なのがだめらしい。

sparse_categorical_crossentropyにするとうまく動作する。

#NG
#model.compile(loss='categorical_crossentropy',
#              optimizer='adam',
#              metrics=['accuracy'])

#OK
model.compile(loss='sparse_categorical_crossentropy',
              optimizer='adam',
              metrics=['accuracy'])

たぶん、正解データの形式の問題かな・・・?

keras.np_utils.to_categoricalとかで用意すれば いいのかも。

まあ、どちらにせよ、loss='sparse_categorical_crossentropy'で動いたので気にしない方向で。


GPU利用については、バックエンドのTensorflowがなんかいい感じにしてくれるので、コードには何も書いていない。

何もしなくていいのは楽でいいと思った。

chainer_iris_test

python初心者が chainerを使って、定番のiris分類をやった。

人の作ったモデルを改変してばかりでは理解がすすまないので、iris分類を最初から作ってみた。

知りたかったのは、次の4つ。

1.モデルの定義方法と利用方法

2.csvの読込と、そのデータの活用方法

3.学習した分類データの保存

4.保存したデータの読み込みと、それを使って分類する方法

家に帰るまでが遠足ですので、分類と学習したモデルの保存、保存したモデルの活用法までわからないと意味ないじゃないかということで、一通りのことをやりたかった。

それと、trainerを使った書き方よりも、自分でforループを回す方が、より理解しやすいと思う。

これを作るにはいろいろと罠にはまって絶望しまくった。

その記録はこちらにある。 http://d.hatena.ne.jp/rti7743/20170105/1483602327

#
#とりあえず動くところまで作った iris分類.
#
import argparse
import numpy
import chainer
import chainer.functions as F
import chainer.links as L
import chainer.cuda as cuda

#irisを分類するモデル.
class IrisModel(chainer.Chain):
    def __init__(self):
        super(IrisModel, self).__init__(
            l1=L.Linear(4, 100),     #4つの素性を受け取り
            l2=L.Linear(100, 100),
            l3=L.Linear(100, 3),     #3つの分類のどれに近いかを返す.
        )

    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        y = self.l3(h2)

        return y

#分類した結果が文字列なので [0,1,2] という数字に変換する
def iris_name_to_index(s):
    if s == b'setosa':
        return 0   #正解データは0からスタートしないとダメ
    elif s == b'virginica':
        return 1
    elif s == b'versicolor':
        return 2
    else:
        print("Unknown Data:{}".format(s))
        raise()

#逆に、数字から、setosa/virginica/versicolor に変換する.
def iris_index_to_name(i):
    if i == 0:
        return 'setosa'
    elif i == 1:
        return 'virginica'
    elif i == 2:
        return 'versicolor'
    else:
        print("Unknown Label:{}".format(i))
        raise()


# 引数の処理
parser = argparse.ArgumentParser()
parser.add_argument('--mode',      type=str,   default='all') #train:学習だけ pred:分類だけ all:両方
parser.add_argument('--gpu',       type=int,   default=0)   #GPUを使うかどうか
parser.add_argument('--epoch',     type=int,   default=500) #何回学習を繰り返すか
parser.add_argument('--trainstart',type=int,   default=0)   #全データ150件のうち、何件から学習に使うか
parser.add_argument('--trainsize', type=int,   default=50)  #全データ150件のうち、何件を学習に使うか ディフォルト(150件中 0件から50件までを学習に使う)
parser.add_argument('--trainbatch',type=int,   default=50)  #学習するミニバッチに一度にかけるデータの個数
args = parser.parse_args()

#cudaを使うなら初期化する.
if args.gpu > 0:
    cuda.init()

#csv読込
#最初の4つが学習データ 最後の5番目が正解データ
csv = numpy.loadtxt("iris.csv",
    delimiter=",",                    #csvなので  , で、データは区切られている
    skiprows=1,                       #ヘッダーを読み飛ばす
    converters={4:iris_name_to_index} #4カラム目は分類がテキストでかかれているので 0から始まる数字ラベルに置き換える
    )

#学習データの定義
#学習データは float32の2次元配列
#例: [ [1,2,3,4],[5,6,7,8],[1,2,3,4],[5,6,7,8],[1,2,3,4] ].astype(numpy.float32)
data = csv[:,0:4].astype(numpy.float32)

#正解データの定義
#正解データは 0から始まる int32の1次元配列
#例: [ 0,1,2,1,0 ].astype(numpy.int32)
label= csv[:,4].astype(numpy.int32)

#学習
if args.mode in ['all','train']:
    #分類機の用意
    model = L.Classifier(IrisModel())
    if args.gpu > 0:
        model.to_gpu()

    #最適化アルゴリズムの設定
    optimizer = chainer.optimizers.Adam()
    optimizer.setup(model)

    for epoch in range(args.epoch):
        print('epoch', epoch)

        #perm = numpy.random.permutation(args.trainsize)
        #サンプルとかを見ると perm[i:i+args.trainbatch] しているが、これを使う意味がよくわからんので外している.

        #学習を開始する.
        #学習に使うデータの範囲を args.trainbatchサイズに分けて学習器に投げ込む
        for i in range(args.trainstart, args.trainsize, args.trainbatch):
            x = data[i:i + args.trainbatch]
            y = label[i:i + args.trainbatch]
            if args.gpu > 0:
                x = cuda.to_gpu(x)
                y = cuda.to_gpu(y)

            x = chainer.Variable(x)
            y = chainer.Variable(y)

            optimizer.update(model, x, y)

    #学習結果を保存.
    chainer.serializers.save_npz("model.dat", model)

#分類
if args.mode in ['all','pred']:

    #学習結果を読み込む
    model = L.Classifier(IrisModel())
    chainer.serializers.load_npz("model.dat",model)
    if args.gpu > 0:
        model.to_gpu()
    else:
        model.to_cpu()

    #すべてのデータに対して、1件ずつ、分類を答えさせて、正しいか採点する.
    ok_count = 0
    for i in range(len(data)):
        x = data[i:i+1]        #このデータについて調べたい.
        if args.gpu > 0:
            x = cuda.to_gpu(x)

        x = chainer.Variable(x)

        y = model.predictor(x) #分類の結果を取得

        y = y.data             #chainer.Variableからデータの取出し
        if args.gpu > 0:
            y = cuda.to_cpu(y)

        pred = numpy.argmax(y)    #3つの分類のうち、どれの確率が一番高いのかを返す
        if label[i] == pred:
           ok_count = ok_count + 1
           #print("OK i:{} pred:{}({}) data:{}".format(i,iris_index_to_name(pred),iris_index_to_name(label[i]),data[i:i+1] ))
        else:
           print("NG i:{} pred:{}({}) data:{}".format(i,iris_index_to_name(pred),iris_index_to_name(label[i]),data[i:i+1] ))

    print("total:{} OK:{} NG:{} rate:{}".format(len(data),ok_count,len(data)-ok_count,ok_count/len(data)) )

コードとデータ一式はgithubにある。

https://github.com/rti7743/chainer_iris_test

git cloneしたあとで、python test.py とかやると、iris.csvを読み込んで先頭50件を使って学習し、学習した結果をもとに全150件の分類を答えます。

サンプルとかを見ると perm[i:i+args.trainbatch] しているが、これを使う意味がよくわからんので外している.

なんで、これを使わないといけないの知っている人は教えてほしい。

#perm = numpy.random.permutation(args.trainsize)

先にも書いたが、ディフォルトだと、とりあえず、 iris.csvを読み込んで、 先頭50件を使って学習します。

その後、学習したモデルをファイルに書きだします。

で、そのあとで、その保存したモデルを使って、 iris.csvの全データ150件のテスト分類をします。

だいたい正解率 96%-99%ぐらいです。

よくわからないが、実行する度に結果が変わる。numpy.random.permutationを排除しているから、乱数はないはずなんだけどライブラリの中で乱数使っているのかな・・・?初心者なのでよくわからない。

オプションpython test.py --gpu 1 とかすると、 GPUを使って計算します。

総数150件程度なので、この程度の規模だと、GPUはあってもなくてもあんまり変わらないみたいですが、とりあえず。

オプションpython test.py --mode train と、すると、学習だけやります。

オプションpython test.py --mode pred と、すると、分類だけやります。

ディフォルトは、 all となっており、両方やります。学習したあとで分類を実行して結果を返します。

python初心者が書いたコードなので間違っているかもしれないが、間違っていたら、クスリと笑った後で、なぜそれが間違っていてどうすればいいと思うかを教えてください。

2017-01-05

苦労と試行

python初心者が chainerのエラーに遭遇して、ひたすら苦労しながら解決していった記録。

無慈悲エラーメッセージと、それがどういう意味で、何を言いたくて、どうしなければいけないのかを記録していきたいと思う。

エラーなんて原因がわかってしまえばなんてことはないんだけど、わかるまでが大変。。。

windowsでcudaを利用する場合インストール

windowsでcudaを利用する場合に、

pip install chainer でインストールすると、以下のエラーが出る場合がある。

cupy\cuda\cudnn.cpp(3662) : error C3861: 'cudnnAddTensor_v3'

githubにある新しいバージョンで修正されている。2016/12/31にpipで入れようとしたら、このバグ修正がまだpip版に反映されていなくてとても苦労した。

github版では修正されているので、githubからソースコードを持ってきてインストールするとOK。

https://github.com/pfnet/chainer/pull/2031


git clone https://github.com/pfnet/chainer
cd chainer
python setup.py install


正解データは0からの整数で出力数とあっていないといけないらしい。

Traceback (most recent call last):
  File "test.py", line 54, in <module>
    trainer.run()
  File "chainer\training\trainer.py", line 289, in run
    update()
  File "chainer\training\updater.py", line 170, in update
    self.update_core()
  File "chainer\training\updater.py", line 182, in update_core
    optimizer.update(loss_func, *in_vars)
  File "chainer\optimizer.py", line 390, in update
    loss = lossfun(*args, **kwds)
  File "chainer\links\model\classifier.py", line 68, in __call__
    self.loss = self.lossfun(self.y, t)
  File "chainer\functions\loss\softmax_cross_entropy.py", line 223, in softmax_cross_entropy
    use_cudnn, normalize, cache_score, class_weight)(x, t)
  File "chainer\function.py", line 199, in __call__
    outputs = self.forward(in_data)
  File "chainer\function.py", line 319, in forward
    return self.forward_cpu(inputs)
  File "chainer\functions\loss\softmax_cross_entropy.py", line 68, in forward_cpu
    log_p = log_yd[numpy.maximum(t.ravel(), 0), numpy.arange(t.size)]
IndexError: index 3 is out of bounds for axis 0 with size 3

データ(主に正解データ)を0からスタートしていないときや、

出力個数があっていない時にでるらしい。


たとえば、以下のようなモデルがあった場合、正解データは0-3のいづれかでないとダメらしい。

class IrisModel(Chain):
    def __init__(self):
        super(IrisModel, self).__init__(
            l1=L.Linear(4, 100),
            l2=L.Linear(100, 100),
            l3=L.Linear(100, 3),  #正解データ
        )

    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        y = self.l3(h2)

        return y

l3=L.Linear(100, 正解データの個数)

正解データの個数 = 3 だった場合

正解データは、 [0,1,2] で合計 3つにならないといけないらしい。

それを間違えて、 [1,2,3] で合計 3つにすると、このエラーが発生する。

正解データは、 [0,1,2] で3つにしないといけないらしい。

学習データは、2次元のfloat32データ
np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32)
正解データは、1次元のint32データで0から開始する
np.array([0,1,2]).astype(np.int32)

正解データは、一次元配列でなければならないっぽい

Traceback (most recent call last):
  File "test.py", line 54, in <module>
    trainer.run()
  File "chainer\training\trainer.py", line 289, in run
    update()
  File "chainer\training\updater.py", line 170, in update
    self.update_core()
  File "chainer\training\updater.py", line 182, in update_core
    optimizer.update(loss_func, *in_vars)
  File "chainer\optimizer.py", line 390, in update
    loss = lossfun(*args, **kwds)
  File "chainer\links\model\classifier.py", line 68, in __call__
    self.loss = self.lossfun(self.y, t)
  File "chainer\functions\loss\softmax_cross_entropy.py", line 223, in softmax_cross_entropy
    use_cudnn, normalize, cache_score, class_weight)(x, t)
  File "chainer\function.py", line 189, in __call__
    self._check_data_type_forward(in_data)
  File "chainer\function.py", line 280, in _check_data_type_forward
    type_check.InvalidType(e.expect, e.actual, msg=msg), None)
  File "<string>", line 2, in raise_from
chainer.utils.type_check.InvalidType:
Invalid operation is performed in: SoftmaxCrossEntropy (Forward)

Expect: in_types[1].ndim == in_types[0].ndim - 1
Actual: 2 != 1

正解データを、一次元配列にしていない時に出る。

入力データは、 [0,1,2] みたいに、2次元配列でなければいけないらしい。

(そしてデータは0から始まるnumpy.int32型でないといけないっぽい)

学習データは、2次元のfloat32データ
np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32)
正解データは、1次元のint32データで0から開始する
np.array([0,1,2]).astype(np.int32)

正解データが numpy.int32の配列になっていないとき

Traceback (most recent call last):
  File "test.py", line 54, in <module>
    trainer.run()
  File "chainer\training\trainer.py", line 289, in run
    update()
  File "chainer\training\updater.py", line 170, in update
    self.update_core()
  File "chainer\training\updater.py", line 182, in update_core
    optimizer.update(loss_func, *in_vars)
  File "chainer\optimizer.py", line 390, in update
    loss = lossfun(*args, **kwds)
  File "chainer\links\model\classifier.py", line 68, in __call__
    self.loss = self.lossfun(self.y, t)
  File "chainer\functions\loss\softmax_cross_entropy.py", line 223, in softmax_cross_entropy
    use_cudnn, normalize, cache_score, class_weight)(x, t)
  File "chainer\function.py", line 189, in __call__
    self._check_data_type_forward(in_data)
  File "chainer\function.py", line 280, in _check_data_type_forward
    type_check.InvalidType(e.expect, e.actual, msg=msg), None)
  File "<string>", line 2, in raise_from
chainer.utils.type_check.InvalidType:
Invalid operation is performed in: SoftmaxCrossEntropy (Forward)

Expect: in_types[1].dtype == <class 'numpy.int32'>
Actual: float32 != <class 'numpy.int32'>

このエラーは、正解データを、一次元の numpy.int32の配列にしていない時に出るっぽい。

入力データは、 [0,1,2] みたいに、1次元配列でなければいけない。

(そしてデータは0から始まるnumpy.int32型でないとダメ)

data.astype(numpy.int32) で型を明示的に指定するといい。

学習データは、2次元のfloat32データ
np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32)
正解データは、1次元のint32データで0から開始する
np.array([0,1,2]).astype(np.int32)


学習データは numpy.float32 でなければならないらしい

Traceback (most recent call last):
  File "test.py", line 54, in <module>
    trainer.run()
  File "chainer\training\trainer.py", line 289, in run
    update()
  File "chainer\training\updater.py", line 170, in update
    self.update_core()
  File "chainer\training\updater.py", line 182, in update_core
    optimizer.update(loss_func, *in_vars)
  File "chainer\optimizer.py", line 390, in update
    loss = lossfun(*args, **kwds)
  File "chainer\links\model\classifier.py", line 67, in __call__
    self.y = self.predictor(*x)
  File "test.py", line 22, in __call__
    h1 = F.relu(self.l1(x))
  File "chainer\links\connection\linear.py", line 92, in __call__
    return linear.linear(x, self.W, self.b)
  File "chainer\functions\connection\linear.py", line 79, in linear
    return LinearFunction()(x, W, b)
  File "chainer\function.py", line 189, in __call__
    self._check_data_type_forward(in_data)
  File "chainer\function.py", line 280, in _check_data_type_forward
    type_check.InvalidType(e.expect, e.actual, msg=msg), None)
  File "<string>", line 2, in raise_from
chainer.utils.type_check.InvalidType:
Invalid operation is performed in: LinearFunction (Forward)

Expect: in_types[2].dtype == in_types[0].dtype
Actual: float32 != float64

このエラーは学習データを numpy.float32 にしていないと出るらしい。

data = data.astype(numpy.float32) として、numpy.float32へ変換すると解決できます。

学習データは、2次元のfloat32データ
np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32)
正解データは、1次元のint32データで0から開始する
np.array([0,1,2]).astype(np.int32)

学習データの個数があっていないときのエラー

Traceback (most recent call last):
  File "test.py", line 54, in <module>
    trainer.run()
  File "chainer\training\trainer.py", line 289, in run
    update()
  File "chainer\training\updater.py", line 170, in update
    self.update_core()
  File "chainer\training\updater.py", line 182, in update_core
    optimizer.update(loss_func, *in_vars)
  File "chainer\optimizer.py", line 390, in update
    loss = lossfun(*args, **kwds)
  File "chainer\links\model\classifier.py", line 67, in __call__
    self.y = self.predictor(*x)
  File "test.py", line 22, in __call__
    h1 = F.relu(self.l1(x))
  File "chainer\links\connection\linear.py", line 92, in __call__
    return linear.linear(x, self.W, self.b)
  File "chainer\functions\connection\linear.py", line 79, in linear
    return LinearFunction()(x, W, b)
  File "chainer\function.py", line 189, in __call__
    self._check_data_type_forward(in_data)
  File "chainer\function.py", line 280, in _check_data_type_forward
    type_check.InvalidType(e.expect, e.actual, msg=msg), None)
  File "<string>", line 2, in raise_from
chainer.utils.type_check.InvalidType:
Invalid operation is performed in: LinearFunction (Forward)

Expect: prod(in_types[0].shape[1:]) == in_types[1].shape[1]
Actual: 5 != 4

このエラーは、学習データの個数があっていなときにでるっぽい。


たとえば、以下のようなモデルがあった場合、学習データは[ [1,2,3,4],[5,6,7,8],[9,10,11,12] ] みたいに、定義した数と個数があっていないといけないらしい。

class IrisModel(Chain):
    def __init__(self):
        super(IrisModel, self).__init__(
            l1=L.Linear(4, 100),  #学習データ
            l2=L.Linear(100, 100),
            l3=L.Linear(100, 3),
        )

    def __call__(self, x):
        h1 = F.relu(self.l1(x))
        h2 = F.relu(self.l2(h1))
        y = self.l3(h2)

        return y

l1=L.Linear(学習データの個数, 100),

学習データの個数 = 4 だった場合

学習データは、 [ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]みたいに、要素が4つの要素を持っていないとダメです。

上の例だと、len(arr[0])==4 len(arr[1])==4 len(arr[2])==4 です。( len(arr) ではなく、 len(arr[0])の方の要素数の話です。 )

それを間違えて、 [ [1,2,3,4,99],[5,6,7,8,99],[9,10,11,12,99] ] みたいに個数を間違えると、このエラーが発生します。

学習データは、2次元のfloat32データ
np.array([ [1,2,3,4],[5,6,7,8],[9,10,11,12] ]).astype(np.float32)
正解データは、1次元のint32データで0から開始する
np.array([0,1,2]).astype(np.int32)

2016-12-30

サクラエディタで lint

サクラエディタで lint を走らせるマクロです。

現在、編集しているファイルに対して、チェックします。

問題があれば、別ウィンドウを開いて指摘してくれます。

問題がなければ何もしません。

現在 phpjs に対応しています。

PHPのチェックには php cliを使います。

http://windows.php.net/download/

jsのチェックには jshint を使います

https://nodejs.org/en/

npm install jshint

共に、パスを切ってください。

または、ソース書き換えて、呼び出せるようにしてください。

//サクラエディタで lint
//
//現在、編集しているファイルに問題があれば表示。問題なければ何もしない。
//現在 php と js に対応.
//
//作った人 rti7743
//ライセンス: NYSL / CC0 / Public Domain / ご自由に

//コマンドを実行して、その結果から、特定の文字列を含まない行だけを取得.
//return `cmd | grep -v foo`; 
function system(cmd,ignoreMessageArray)
{
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	var shell = new ActiveXObject("WScript.Shell");
	
	var stdout = fso.GetTempName();
//	var stdout="c:\\temp\\aa.txt";
	
	cmd = "cmd.exe /c " + cmd + " > \"" + stdout + "\" 2>&1";
	shell.Run(cmd,0,1);

	var result = "";
	var fs = fso.OpenTextFile(stdout,1);
	while(! fs.AtEndOfStream )
	{
		var line = fs.ReadLine();
		var found = false;
		for(var i in ignoreMessageArray)
		{
			if ( line.indexOf( ignoreMessageArray[i] ) >= 0)
			{
				found = true;
			}
		}
		if (found)
		{
			continue;
		}
		result += line + "\r\n";
	}
	fs.Close();

	fso.DeleteFile(stdout);
	
	return result;
}

function main()
{
	var filename = "\"" + Editor.GetFilename() + "\"";
	var lower = Editor.GetFilename() + "*";
	lower = lower.toLowerCase();

	var result = "";
	if ( lower.indexOf('.php*') > 0 )
	{//PHPのチェックには php cliを使います
	 //DOWNLOAD http://windows.php.net/download/

		var cmd = "php -l " + filename;
		result = system(cmd,["No syntax","Errors parsing"] );
	}
	else if ( lower.indexOf('.js*') > 0 )
	{//jsのチェックには jshint を使います
	 //DOWNLOAD https://nodejs.org/en/
	 //DOWNLOAD npm install jshint
		var cmd = "jshint " + filename;
		result = system(cmd,["No syntax"]);
	}

	if(result.length >= 1)
	{
		//エラーがあれば表示
		Editor.TraceOut(result,2);
		ActivateWinOutput();
	}
}
main();

サクラエディタで svn|git log/blame

サクラエディタで、現在のファイルに対して、 svn|git log と svn|git blame を発行するマクロです。

\\192.168.x.x 形式へは git.exeとか svn.exe が対応していないので、 mount -t cifs で逆にマウントするか、ネットワークフォルダ割り当てをしてください。

個のルーチンを動かすには、svnまたは、gitが必要です。

GIT

https://git-for-windows.github.io/

SVN

https://www.softel.co.jp/blogs/tech/archives/4667


このルーチンには表示時にバグが1つあります。

サクラエディタはケチなので toSJIS関数マクロから使わせてくれないので、一部日本語が文字化けすることがあります。

たとえば、 ソースコードUTF-8で書いていると、 blameとかの結果が文字化けします。

これは、サクラエディタが、外部出力はShift-JIS要求しているのにもかかわらず、 ToSJIS 変換ルーチンをマクロへ提供していないためです。

//サクラエディタで svn|git log/blame
//
//現在、編集しているファイルの履歴を表示
//
//作った人 rti7743
//ライセンス: NYSL / CC0 / Public Domain / ご自由に

//コマンドを実行して、その結果から、特定の文字列を含まない行だけを取得.
//return `cmd | grep -v foo`; 
//
//バグ: サクラエディタはケチなので toSJIS関数をマクロから使わせてくれないので、一部日本語が文字化けすることがあります。

function system(cmd,ignoreMessageArray)
{
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	var shell = new ActiveXObject("WScript.Shell");
	
	var stdout = fso.GetTempName();
//	var stdout="c:\\temp\\aa.txt";
	
	cmd = "cmd.exe /c " + cmd + " > \"" + stdout + "\" 2>&1";
	shell.Run(cmd,0,1);

	var result = "";
	var fs = fso.OpenTextFile(stdout,1);
	while(! fs.AtEndOfStream )
	{
		var line = fs.ReadLine();
		var found = false;
		for(var i in ignoreMessageArray)
		{
			if ( line.indexOf( ignoreMessageArray[i] ) >= 0)
			{
				found = true;
			}
		}
		if (found)
		{
			continue;
		}
		result += line + "\r\n";
	}
	fs.Close();

	fso.DeleteFile(stdout);
	
	return result;
}

function main()
{
	var filename = "\"" + Editor.GetFilename() + "\"";

	var result = "";
	var cmd="";

	//GIT
	//DOWNLOAD https://git-for-windows.github.io/
	cmd = "git log " + filename;
	result = system(cmd,["Not a git repository"] );
	if (result.length > 0)
	{
		Editor.TraceOut(result,2);
		ActivateWinOutput();

		cmd = "git blame " + filename;
		result = system(cmd,[] );
		Editor.TraceOut(result,2);
		return ;
	}

	//SVN
	//DOWNLOAD https://www.softel.co.jp/blogs/tech/archives/4667
	cmd = "svn log " + filename;
	result = system(cmd,["is not a working copy"] );
	if (result.length > 0)
	{
		Editor.TraceOut(result,2);
		ActivateWinOutput();

		cmd = "svn blame " + filename;
		result = system(cmd,[] );
		Editor.TraceOut(result,2);
		return ;
	}
}
main();