整数ではなく、ベクトルラベル付きのカフェを使用したい。いくつかの回答を確認しましたが、HDF5がより良い方法のようです。しかし、それから私は次のようなエラーに行き詰まっています:
precision_layer.cpp:34]チェックに失敗しました:
outer_num_ * inner_num_ == bottom[1]->count()
(50対200)ラベルの数は予測の数と一致する必要があります。たとえば、ラベル軸== 1で予測形状が(N、C、H、W)の場合、ラベル数(ラベル数)はN*H*W
、{0、1、...、C-1}の整数値。
hDF5を次のように作成:
f = h5py.File('train.h5', 'w')
f.create_dataset('data', (1200, 128), dtype='f8')
f.create_dataset('label', (1200, 4), dtype='f4')
私のネットワークは以下によって生成されます:
def net(hdf5, batch_size):
n = caffe.NetSpec()
n.data, n.label = L.HDF5Data(batch_size=batch_size, source=hdf5, ntop=2)
n.ip1 = L.InnerProduct(n.data, num_output=50, weight_filler=dict(type='xavier'))
n.relu1 = L.ReLU(n.ip1, in_place=True)
n.ip2 = L.InnerProduct(n.relu1, num_output=50, weight_filler=dict(type='xavier'))
n.relu2 = L.ReLU(n.ip2, in_place=True)
n.ip3 = L.InnerProduct(n.relu1, num_output=4, weight_filler=dict(type='xavier'))
n.accuracy = L.Accuracy(n.ip3, n.label)
n.loss = L.SoftmaxWithLoss(n.ip3, n.label)
return n.to_proto()
with open(PROJECT_HOME + 'auto_train.prototxt', 'w') as f:
f.write(str(net('/home/romulus/code/project/train.h5list', 50)))
with open(PROJECT_HOME + 'auto_test.prototxt', 'w') as f:
f.write(str(net('/home/romulus/code/project/test.h5list', 20)))
ラベル番号を増やして配列ではなく整数に入れる必要があるようですが、これを行うと、カフェはデータ数とラベルが等しくないことを訴え、存在します。
では、マルチラベルデータをフィードするための正しい形式は何ですか?
また、なぜHDF5がカフェBlobにマップするかをデータ形式だけで記述しないのはなぜでしょうか。
この質問のタイトルへの回答:
HDF5ファイルのルートには、それぞれ「data」と「label」という2つのデータセットが必要です。形状は(data amount
、dimension
)です。 1次元のデータのみを使用しているため、channel
、width
、height
の順序がわかりません。多分それは問題ではありません。 dtype
は、floatまたはdoubleでなければなりません。
h5py
でトレインセットを作成するサンプルコードは次のとおりです。
import h5py、os import numpy as np f = h5py.File( 'train.h5'、 'w') # 1200個のデータ、それぞれが128次元のベクトルです f.create_dataset( 'data'、(1200、128)、dtype = 'f8') #データのラベル、それぞれが4次元ですvector f.create_dataset( 'label'、(1200、4)、dtype = 'f4') #固定パターンで何かを入力 #正規化0と1の間の値、またはSigmoidCrossEntropyLossは機能しません for i in range(1200): a = np.empty(128) if i%4 == 0 : j for range(128): a [j] = j/128.0; l = [1,0,0,0] Elif i%4 == 1: jの範囲(128): a [j] =(128-j)/ 128.0; l = [1,0、 1,0] Elif i%4 == 2: for j in range(128): a [j] =(j%6)/ 128.0; l = [0,1,1,0] Elif i%4 == 3: for j in range(128): a [j] = (j%4) * 4/128.0; l = [1,0,1,1] f ['data'] [i] = a f ['label'] [i ] = l f.close()
また、精度レイヤーは不要で、単に削除するだけで問題ありません。次の問題は損失層です。 SoftmaxWithLoss
には出力(最大値を持つ次元のインデックス)が1つしかないため、マルチラベル問題には使用できません。 AdianとShaiのおかげで、この場合はSigmoidCrossEntropyLoss
が良いと思います。
以下は、データ作成、ネットワークのトレーニング、およびテスト結果の取得からの完全なコードです。
main.py(caffe lanetの例から変更)
import os、sys PROJECT_HOME = '.../project /' CAFFE_HOME =' .../caffe /' os .chdir(PROJECT_HOME) sys.path.insert(0、CAFFE_HOME + 'caffe/python') import caffe、h5py from pylab import * from caffe import layer as L def net(hdf5、batch_size): n = caffe.NetSpec() n.data、n.label = L.HDF5Data(batch_size = batch_size、source = hdf5、ntop = 2) n.ip1 = L.InnerProduct(n.data、num_output = 50、weight_filler = dict(type = 'xavier')) n.relu1 = L.ReLU(n.ip1、in_place = True) n.ip2 = L.InnerProduct(n.relu1、num_output = 50、weight_filler = dict(type = 'xavier')) n.relu2 = L.ReLU(n.ip2、in_place = True) n.ip3 = L.InnerProduct(n.relu2、num_output = 4 、weight_filler = dict(type = 'xavier')) n.loss = L.SigmoidCrossEntropyLoss(n.ip3、n.label) return n.to_proto() open(PROJECT_HOME + 'auto_train.prototxt'、 'w')with f: f.write(str(net(PROJECT_HOME + 'train.h5list'、50))) with open(PROJECT_HOME + 'auto_test.prototxt'、 'w')as f: f。 write(str(net(PROJECT_HOME + 'test.h5list'、20))) caffe.set_device(0) caffe.set_mode_gpu() solver = caffe.SGDSolver(PROJECT_HOME + 'auto_solver.prototxt') solver.net.forward() solver.test_nets [0] .forward() solver.step(1) niter = 200 test_interval = 10 train_loss = zeros(niter) test_acc = zeros(int(np .ceil(niter * 1.0/test_interval))) print len(test_acc) output = zeros((niter、8、4)) #Theメインソルバーループ それの範囲内(niter): solver.step(1)#CaffeによるSGD train_loss [it] = solver.net.blobs ['loss' ] .data solver.test_nets [0] .forward(start = 'data') output [it] = solver.test_nets [0] .blobs ['ip3']。data [: 8] もしそれが%test_interval == 0の場合: print 'Iteration'、 it、 'testing ...' 正しい= 0 data = solver.test_nets [0] .blobs ['ip3']。data label = solver.test_nets [0 ] .blobs ['label']。data test_it for range(100): solver.test_nets [0] .forward() #正の値はラベル1にマップされます、負の値は、範囲内のiのラベル0 にマップされます(len(data)): 範囲内のjの場合(len(data [i])): データの場合[i] [j]> 0およびラベル[i] [j] == 1: 正+ = 1 Elifデータ[i] [j]%lt; = 0およびラベル[ i] [j] == 0: 正しい+ = 1 test_acc [int(it/test_interval)] =正しい* 1.0 /(len(data)* len(data [0]) * 100) #トレーニングとテストが完了し、収束グラフを出力します _、ax1 = subplots() ax2 = ax1.twinx() ax1.plot(arange(niter)、train_loss) ax2.plot(test_interval * arange(len(test_acc))、test_acc、 'r' ) ax1.set_xlabel( 'iteration') ax1.set_ylabel( 'train loss') ax2.set_ylabel( 'test precision') _。savefig ( 'converge.png') #最後のバッチの結果を確認します print solver.test_nets [0] .blobs ['ip3']。data print solver.test_nets [0] .blobs ['label']。data
h5listファイルには、各行にh5ファイルのパスが含まれています。
train.h5list
/home/foo/bar/project/train.h5
test.h5list
/home/foo/bar/project/test.h5
そしてソルバー:
auto_solver.prototxt
train_net: "auto_train.prototxt" test_net: "auto_test.prototxt" test_iter:10 test_interval:20 base_lr:0.01 momentum: 0.9 weight_decay:0.0005 lr_policy: "inv" gamma:0.0001 power:0.75 display:100 max_iter: 10000 snapshot:5000 snapshot_prefix: "sed" solver_mode:GPU
最後のバッチ結果:
[[35.91593933 -37.46276474 -6.2579031 -6.30313492] [42.69248581 -43.00864792 13.19664764 -3.35134125] [-1.36403108 1.38531208 2.77786589 -0.34310576] [2.91686511 -2.8894 4.34043217 0.32656598] ... [35.91593933 -37.46276474 -6.2579031 -6.30313492] [42.69248581 -43.00864792 13.19664764 -3.35134125] [-1.36403108 1.38531208 2.77786589 -0.34310576 ] [2.91686511 -2.88944006 4.34043217 0.32656598]] [[1. 0. 0. 0。] [1. 0. 1. 0.] [0. 1. 1. 0。] [1. 0. 1. 1。] ... [1. 0. 0。 0。] [1. 0. 1. 0。] [0. 1. 1. 0。] [1. 0. 1. 1。]]]
このコードにはまだ改善すべき点がたくさんあると思います。任意の提案をいただければ幸いです。
精度レイヤーは意味がありません。
精度レイヤーの動作方法: caffe で精度レイヤーは2つの入力を想定しています
(i)予測確率vectorおよび
(ii)対応するスカラー整数ラベル。
精度レイヤーは、予測されたラベルの確率が実際に最大である(またはtop_k
)。
したがって、C
異なるクラスを分類する必要がある場合、入力はN
- by -C
になります(ここでN
はバッチサイズ)N
クラスとC
ラベルのそれぞれに属するN
サンプルの入力予測確率。
ネットでの定義方法:精度レイヤーを入力N
- by-4予測とN
- by-4ラベル-これはカフェには意味がありません。