net: the main net operator should be added to cell_net: cell_net which is executed in a recurrent fasion inputs: sequences to be fed into the recurrent net. Currently only one input is supported. It has to be in a format T x N x (D1...Dk) where T is lengths of the sequence. N
(
net, cell_net, inputs, initial_cell_inputs,
links, timestep=None, scope=None, outputs_with_grads=(0,),
recompute_blobs_on_backward=None, forward_only=False,
)
| 8 | from caffe2.python import core, workspace |
| 9 | |
| 10 | def recurrent_net( |
| 11 | net, cell_net, inputs, initial_cell_inputs, |
| 12 | links, timestep=None, scope=None, outputs_with_grads=(0,), |
| 13 | recompute_blobs_on_backward=None, forward_only=False, |
| 14 | ): |
| 15 | ''' |
| 16 | net: the main net operator should be added to |
| 17 | |
| 18 | cell_net: cell_net which is executed in a recurrent fasion |
| 19 | |
| 20 | inputs: sequences to be fed into the recurrent net. Currently only one input |
| 21 | is supported. It has to be in a format T x N x (D1...Dk) where T is lengths |
| 22 | of the sequence. N is a batch size and (D1...Dk) are the rest of dimentions |
| 23 | |
| 24 | initial_cell_inputs: inputs of the cell_net for the 0 timestamp. |
| 25 | Format for each input is: |
| 26 | (cell_net_input_name, external_blob_with_data) |
| 27 | |
| 28 | links: a dictionary from cell_net input names in moment t+1 and |
| 29 | output names of moment t. Currently we assume that each output becomes |
| 30 | an input for the next timestep. |
| 31 | |
| 32 | timestep: name of the timestep blob to be used. If not provided "timestep" |
| 33 | is used. |
| 34 | |
| 35 | scope: Internal blobs are going to be scoped in a format |
| 36 | <scope_name>/<blob_name> |
| 37 | If not provided we generate a scope name automatically |
| 38 | |
| 39 | outputs_with_grads : position indices of output blobs which will receive |
| 40 | error gradient (from outside recurrent network) during backpropagation |
| 41 | |
| 42 | recompute_blobs_on_backward: specify a list of blobs that will be |
| 43 | recomputed for backward pass, and thus need not to be |
| 44 | stored for each forward timestep. |
| 45 | |
| 46 | forward_only: if True, only forward steps are executed |
| 47 | ''' |
| 48 | assert len(inputs) == 1, "Only one input blob is supported so far" |
| 49 | |
| 50 | input_blobs = [str(i[0]) for i in inputs] |
| 51 | initial_input_blobs = [str(x[1]) for x in initial_cell_inputs] |
| 52 | op_name = net.NextName('recurrent') |
| 53 | |
| 54 | def s(name): |
| 55 | # We have to manually scope due to our internal/external blob |
| 56 | # relationships. |
| 57 | scope_name = op_name if scope is None else scope |
| 58 | return "{}/{}".format(str(scope_name), str(name)) |
| 59 | |
| 60 | # determine inputs that are considered to be references |
| 61 | # it is those that are not referred to in inputs or initial_cell_inputs |
| 62 | known_inputs = [str(b) for b in input_blobs + initial_input_blobs] |
| 63 | known_inputs += [str(x[0]) for x in initial_cell_inputs] |
| 64 | if timestep is not None: |
| 65 | known_inputs.append(str(timestep)) |
| 66 | references = [ |
| 67 | core.BlobReference(b) for b in cell_net.Proto().external_input |
nothing calls this directly
no test coverage detected
searching dependent graphs…