0

ラザニアとテアノを使用して、VGG から回帰タスクの 20 個の数値を予測しています。私が書いたスクリプトの例では、画像の数は 100 です。

ネットで調べてみると、nolearnを使っている人は を指定することで直りますregression=Trueが、私はラザニアばかり使っています

そう:

('X.shape', (100, 3, 224, 224))
('y.shape', (100, 20))

これが正確なエラーメッセージです

Traceback (most recent call last):
  File "script_1.py", line 167, in <module>
    loss = train_batch()
  File "script_1.py", line 90, in train_batch
    return train_fn(X_tr[ix], y_tr[ix])
  File "/usr/local/lib/python2.7/dist-packages/Theano-0.8.0rc1-py2.7.egg/theano/compile/function_module.py", line 786, in __call__
    allow_downcast=s.allow_downcast)
  File "/usr/local/lib/python2.7/dist-packages/Theano-0.8.0rc1-py2.7.egg/theano/tensor/type.py", line 177, in filter
    data.shape))
TypeError: ('Bad input argument to theano function with name "script_1.py:159"  at index 1(0-based)', 'Wrong number of dimensions: expected 1, got 2 with shape (16, 20).')

モデルはこちら

def build_model():
    net = {}
    net['input'] = InputLayer((None, 3, 224, 224))
    net['conv1'] = ConvLayer(net['input'], num_filters=96, filter_size=7, stride=2, flip_filters=False)
     ...............
    net['drop7'] = DropoutLayer(net['fc7'], p=0.5)
    net['fc8'] = DenseLayer(net['drop7'], num_units=20, nonlinearity=None)
    return net

ジェネレーター:

def batches(iterable, N):
    chunk = []
    for item in iterable:
        chunk.append(item)
        if len(chunk) == N:
            yield chunk
            chunk = []
    if chunk:
        yield chunk
def train_batch():
    ix = range(len(y_tr))
    np.random.shuffle(ix)
    ix = ix[:BATCH_SIZE]
    return train_fn(X_tr[ix], y_tr[ix])

関連するトレーニング スニペット

X_sym = T.tensor4()
y_sym = T.ivector()
output_layer = net['fc8']
prediction = lasagne.layers.get_output(output_layer, X_sym)
loss = lasagne.objectives.squared_error(prediction, y_sym)
loss = loss.mean()
acc = T.mean(T.eq(T.argmax(prediction, axis=1), y_sym), dtype=theano.config.floatX)
params = lasagne.layers.get_all_params(output_layer, trainable=True)
updates = lasagne.updates.nesterov_momentum(loss, params, learning_rate=0.0001, momentum=0.9)

train_fn = theano.function([X_sym, y_sym], loss, updates=updates)
val_fn = theano.function([X_sym, y_sym], [loss, acc])
pred_fn = theano.function([X_sym], prediction)

for epoch in range(5):
    for batch in range(25):
       loss = train_batch()
.....
4

1 に答える 1

1

予測出力の形状は (バッチサイズ、20) ですが、y_sym 変数は ive​​ctor 型であるため、おそらく長さバッチサイズのベクトルです。これがエラーの原因かどうかはわかりませんが、これら 2 つの量の二乗誤差項を計算できるとは思いません。1 つは行列で、もう 1 つはベクトルですが、形状が一致していないように見えますか?

回帰のターゲットは何ですか? 各データポイントに対して 20 個の数値を予測している場合、y_sym はおそらく行列である必要があり、二乗誤差項を計算できます。

別の可能性は、最後のレイヤーを変更して非線形性をシグモイドにすることです。このようにして、畳み込みニューラル ネットワークをマルチラベル確率を生成するものとして解釈できます。次に、回帰用のマルチラベル確率ターゲット変数を合成的に生成できます。1 つの例として、データポイント x にマルチラベル 0、1、10 があるとします。長さ 20 のベクトルを作成できます。ここで、0、1、10 は小さな a の 1-a のようなもので、他のエントリは小さな正の数です。 .

目的関数をバイナリ クロス エントロピーに切り替えることもできます。この場合、回帰は実行していません。ただし、ネットワークがベクトルではなく、クラス スコアマトリックスを出力することはまだあります。これは通常、画像内の K 個の異なるオブジェクト (猫、犬、人間、車、自転車など) の存在を検出するときに使用される損失関数です (マルチラベル分類など)。このルートを試してみたい場合は、最後のレイヤーを次のように変更します。

net['fc8'] = DenseLayer(net['drop7'], num_units=20, nonlinearity=sigmoid)

ここで、ネットワークを出力確率として解釈します。各確率は、オブジェクト クラスが画像内にあるとネットワークが信じるかどうかに関する信頼スコアを表します。

これで、次の損失関数が得られます。

X_sym = T.tensor4()
y_sym = T.imatrix() 
output_layer = net['fc8']
probabilities = lasagne.layers.get_output(output_layer, X_sym)
loss = lasagne.objectives.binary_crossentropy(probabilities, y_sym)
loss = loss.mean()
... the rest of the update stuff...
train_fn = theano.function([X_sym, y_sym], loss, updates=updates)

ここでの主な違いは、ターゲット変数 y_sym が行列になっていることです。これは {0,1} 値 (batchsize,K) のサイズの行列である必要があります。0 は画像に存在しないオブジェクトを表し、1 は画像に存在するオブジェクトを表します。

また、マルチラベル予測の精度を計算するには、通常、F1 スコアを使用します。これは、 scikit -learn を使用して F1 スコアを計算する方法への参照です。この場合、検証関数は異なります。次のようになります。

 from sklearn.metrics import f1_score
 probabilities_fn = theano.function([X_sym], probabilities)
 confidence_threshold = .5 
 predictions = np.where(probabilities_fn(X_sym) > confidence_threshold, 1, 0)  
 f1_score(y_true, predictions, average='micro')

上記のコード スニペットは、ネットワークから確率/信頼スコアを返し、confidence_threshold パラメーターを超える確率を返します。ここでは .5 を選択し、クラス ラベルが存在すると解釈します。

于 2016-03-28T13:27:04.637 に答える