2016-04-25 11 views
6

Voglio impostare un caffe CNN con python, usando l'interfaccia caffe.NetSpec(). Anche se ho visto che possiamo mettere la rete di prova in solver.prototxt, mi piacerebbe scriverlo in model.prototxt con fase diversa. Ad esempio, caffe model prototxt attuare strato di due dati con diverse fasi:caffe: definizione del modello: scrivi lo stesso livello con fase diversa usando caffe.NetSpec()

layer { 
    name: "data" 
    type: "Data" 
    top: "data" 
    top: "label" 
    include { 
    phase: TRAIN 
    } 
.... 
} 
layer { 
    name: "data" 
    type: "Data" 
    top: "data" 
    top: "label" 
    include { 
    phase: TEST 
    } 
.... 
} 

come devo fare in python per ottenere tale attuazione?

+0

v'è un open [bvlc/caffe problema github] (https://github.com/BVLC/caffe/issues/4044). – Shai

risposta

5

Suppongo che intendi come definire la fase durante la scrittura di un prototipo utilizzando caffe.NetSpec?

from caffe import layers as L, params as P, to_proto 
import caffe 

ns = caffe.NetSpec() 
ns.data = L.Data(name="data", 
       data_param={'source':'/path/to/lmdb','batch_size':32}, 
       include={'phase':caffe.TEST}) 

Se si desidera avere ENTRAMBI treno e strati di prova nella stessa prototxt, quello che faccio di solito sta facendo uno ns per il treno con tutti i livelli e un altro ns_test solo con la versione di prova del solo gli strati duplicati. Poi, quando si scrive il file prototxt attuale:

with open('model.prototxt', 'w') as W: 
    W.write('%s\n' % ns_test.to_proto()) 
    W.write('%s\n' % ns.to_proto()) 

questo modo avrete entrambe le fasi nella stessa prototxt. Un po 'hacky, lo so.

+0

sì, io uso caffe.NetSpec(), ma la domanda è che voglio definire due livelli con lo stesso nome ma fasi diverse, qualcosa come ns.data = L.Data (name = "data", data_param = {'source ':'/percorso/per/lmdb ',' batch_size ': 32}, include = {' phase ': caffe.TEST}) ns.data = L.Data (name = "data", data_param = {' source ':'/percorso/per/lmdb ',' batch_size ': 32}, include = {' fase ': caffe.TRAIN}) – user3162707

+0

Ma questo rende solo ns.data per la fase TEST – user3162707

+0

@ user3162707 per favore vedi la mia modifica – Shai

1

Se la rete è come:

layer {phase: TRAIN} 
layer {phase: TEST} 
layer {} 
layer {phase: TRAIN} 
layer {} 
layer {phase: TEST} 
layer {} 
layer {} 
layer {phase: TEST} 

Creare un treno rete ns, creare un test netta ns_test
Ora avete fondamentalmente due stringhe str(ns.to_proto()) e str(ns_test.to_proto())
Unisci quei due con presa python regex in considerazione l'ordine di livello richiesto.

0

Ho trovato un altro modo.
Potrei risolvere questo problema restituendo la stringa di proto.
Fondamentalmente, è possibile aggiungere stringhe con i livelli che verranno sostituiti (nel mio caso, il primo livello).

def lenet(path_to_lmdb_train, path_to_lmdb_test, 
      batch_size_train, batch_size_test): 
    n = caffe.NetSpec() 
    n.data, n.label = L.Data(batch_size=batch_size_train, backend=P.Data.LMDB, source=path_to_lmdb_train, 
          include=dict(phase=caffe.TRAIN), transform_param=dict(scale=1./255), ntop=2) 
    first_layer = str(n.to_proto()) 

    n.data, n.label = L.Data(batch_size=batch_size_test, backend=P.Data.LMDB, source=path_to_lmdb_test, 
          include=dict(phase=caffe.TEST), transform_param=dict(scale=1./255), ntop=2) 
    n.conv1 = L.Convolution(n.data, kernel_size=5, num_output=20, weight_filler=dict(type='xavier')) 
    n.pool1 = L.Pooling(n.conv1, kernel_size=2, stride=2, pool=P.Pooling.MAX) 
    n.conv2 = L.Convolution(n.pool1, kernel_size=5, num_output=50, weight_filler=dict(type='xavier')) 
    n.pool2 = L.Pooling(n.conv2, kernel_size=2, stride=2, pool=P.Pooling.MAX) 
    n.ip1 = L.InnerProduct(n.pool2, num_output=500, weight_filler=dict(type='xavier')) 
    n.relu1 = L.ReLU(n.ip1, in_place=True) 
    n.ip2 = L.InnerProduct(n.relu1, num_output=10, weight_filler=dict(type='xavier')) 
    n.loss = L.SoftmaxWithLoss(n.ip2, n.label) 
    n.accuracy = L.Accuracy(n.ip2, n.label, include=dict(phase=caffe.TEST)) 

    return first_layer + str(n.to_proto()) 
2

Trovo un metodo utile.

È possibile aggiungere una chiave denominata name per il vostro livello di fase di test, e modificare le chiavi ntop e top proprio come questo:

net.data = L.Data(name='data', 
       include=dict(phase=caffe_pb2.Phase.Value('TRAIN')), 
       ntop=1) 
net.test_data = L.Data(name='data', 
        include=dict(phase=caffe_pb2.Phase.Value('TEST')), 
        top='data', 
        ntop=0) 
Problemi correlati