def __init__(self, C=1, N=1, K=1, D=1, H=1, W=1, T=1, R=1, S=1, pad_d=0, pad_h=0, pad_w=0, str_d=1, str_h=1, str_w=1): from ngraph.frontends.neon.layer import output_dim M = output_dim(D, T, pad_d, str_d) P = output_dim(H, R, pad_h, str_h) Q = output_dim(W, S, pad_w, str_w) self.dimO = (K, M, P, Q, N) self.dimI = (C, D, H, W, N) self.dimF = (C, T, R, S, K) self.conv_params = dict(pad_d=pad_d, pad_h=pad_h, pad_w=pad_w, str_d=str_d, str_h=str_h, str_w=str_w, dil_d=1, dil_h=1, dil_w=1) self.batch_axis = ng.make_axis(name='N', length=N) self.ax_i = ng.make_axes([ ng.make_axis(name='C', length=C), ng.make_axis(name='D', length=D), ng.make_axis(name='H', length=H), ng.make_axis(name='W', length=W), self.batch_axis ]) self.ax_f = ng.make_axes([ ng.make_axis(name='C', length=C), ng.make_axis(name='D', length=T), ng.make_axis(name='H', length=R), ng.make_axis(name='W', length=S), ng.make_axis(name='K', length=K), ]) self.ax_o = ng.make_axes([ ng.make_axis(name='C', length=K), ng.make_axis(name='D', length=M), ng.make_axis(name='H', length=P), ng.make_axis(name='W', length=Q), self.batch_axis ])
def __init__(self, C=1, N=1, D=1, H=1, W=1, J=1, T=1, R=1, S=1, pad_c=0, pad_d=0, pad_h=0, pad_w=0, str_c=1, str_d=1, str_h=1, str_w=1, op='max'): K = output_dim(C, J, pad_c, str_c) M = output_dim(D, T, pad_d, str_d) P = output_dim(H, R, pad_h, str_h) Q = output_dim(W, S, pad_w, str_w) self.dimO = (K, M, P, Q, N) self.dimI = (C, D, H, W, N) self.dimF = (J, T, R, S, K) self.pool_params = dict(pad_c=pad_c, pad_d=pad_d, pad_h=pad_h, pad_w=pad_w, str_c=str_c, str_d=str_d, str_h=str_h, str_w=str_w, J=J, T=T, R=R, S=S, op=op) batch_axis = ng.make_axis(name='N', length=N) self.ax_i = ng.make_axes([ ng.make_axis(name='C', length=C), ng.make_axis(name='D', length=D), ng.make_axis(name='H', length=H), ng.make_axis(name='W', length=W), batch_axis ]) self.ax_o = ng.make_axes([ ng.make_axis(name='C', length=K), ng.make_axis(name='D', length=M), ng.make_axis(name='H', length=P), ng.make_axis(name='W', length=Q), batch_axis ])
def test_convolution_backprop(transformer_factory): """ test convolution backprop path """ N = 128 C, K = 3, 2 D, T = 1, 1 H = W = 32 R = S = 2 padding = dict(pad_d=0, pad_h=0, pad_w=0) strides = dict(str_d=1, str_h=1, str_w=1) dilation = dict(dil_d=1, dil_h=1, dil_w=1) conv_params = padding.copy() conv_params.update(strides) conv_params.update(dilation) ax_i = ng.make_axes([ax.C, ax.D, ax.H, ax.W, ax.N]) ax_f = ng.make_axes([ax.C, ax.T, ax.R, ax.S, ax.K]) ax_i.set_shape((C, D, H, W, N)) ax_f.set_shape((C, T, R, S, K)) ax_o = ng.make_axes([ ng.make_axis(roles=[ar.features_input]).named('C'), ng.make_axis(roles=[ar.features_0]).named('D'), ng.make_axis(roles=[ar.features_1]).named('H'), ng.make_axis(roles=[ar.features_2]).named('W'), ax.N ]) ax_o[:-1].set_shape((K, output_dim(D, T, padding['pad_d'], strides['str_d']), output_dim(H, R, padding['pad_h'], strides['str_h']), output_dim(W, S, padding['pad_w'], strides['str_w']))) inputs = ng.placeholder(axes=ax_i) filters = ng.placeholder(axes=ax_f) # randomly initialize input_value = rng.uniform(-1, 1, ax_i) filter_value = rng.uniform(-1, 1, ax_f) assert input_value.shape == ax_i.lengths assert filter_value.shape == ax_f.lengths output = ng.sum(ng.convolution(conv_params, inputs, filters, ax_o), out_axes=()) with ExecutorFactory() as factory: dcdf_sym_fun = factory.derivative(output, filters, inputs) dcdf_num_fun = factory.numeric_derivative(output, filters, .01, inputs) dcdf_sym_val = dcdf_sym_fun(filter_value, input_value) dcdf_num_val = dcdf_num_fun(filter_value, input_value) ng.testing.assert_allclose(dcdf_sym_val, dcdf_num_val, rtol=1)
def test_pooling(): """ test pooling forward and backward path """ N = 128 C = 3 D = 1 H = W = 32 J = T = 1 R = S = 2 ngt.make_transformer() padding = dict(pad_d=0, pad_h=0, pad_w=0, pad_c=0) strides = dict(str_d=1, str_h=1, str_w=1, str_c=1) fshape = dict(J=J, T=T, R=R, S=S) pool_params = dict(op='max') pool_params.update(padding) pool_params.update(strides) pool_params.update(fshape) ax_i = ng.make_axes([ax.C, ax.D, ax.H, ax.W, ax.N]) ax_i.set_shape((C, D, H, W, N)) inputs = ng.placeholder(axes=ax_i) ax_o = ng.make_axes([ ng.make_axis(roles=[ar.features_input]).named('C'), ng.make_axis(roles=[ar.features_0]).named('D'), ng.make_axis(roles=[ar.features_1]).named('H'), ng.make_axis(roles=[ar.features_2]).named('W'), ax.N ]) ax_o[:-1].set_shape((output_dim(C, J, padding['pad_c'], strides['str_c']), output_dim(D, T, padding['pad_d'], strides['str_d']), output_dim(H, R, padding['pad_h'], strides['str_h']), output_dim(W, S, padding['pad_w'], strides['str_w']))) # randomly initialize input_value = rng.uniform(-1, 1, ax_i) assert input_value.shape == ax_i.lengths # compute convolution with graph output = ng.pooling(pool_params, inputs, axes=ax_o) targets = ng.placeholder(axes=ax_o) costs = ng.cross_entropy_binary(ng.sigmoid(output), targets) error = ng.sum(costs, out_axes=()) / ng.batch_size(costs) d_inputs = ng.deriv(error, inputs) targets_value = rng.uniform(.1, 0.9, output.axes) with executor([output, error, d_inputs], inputs, targets) as conv_executor: result_ng, err_ng, gradI_ng = conv_executor(input_value, targets_value) # Now compute reference values via NEON NervanaObject.be.bsz = N neon_layer = Pooling(fshape=fshape, padding=padding, strides=strides, op="max") inp = neon_layer.be.array(input_value.reshape(C * H * W * D, N)) neon_layer.configure((C, H, W)) neon_layer.prev_layer = True neon_layer.allocate() neon_layer.set_deltas(DummyDeltaBuffers()) result_ne = neon_layer.fprop(inp).get().reshape(output.axes.lengths) act_result_ne = 1. / (1.0 + np.exp(-result_ne)) err = neon_layer.be.array( (act_result_ne - targets_value).reshape(-1, N) / float(N)) gradI_ne = neon_layer.bprop(err).get().reshape(ax_i.lengths) # Compare fprop ng.testing.assert_allclose(result_ng, result_ne, rtol=0, atol=1e-6) # Compare bprop ng.testing.assert_allclose(gradI_ng, gradI_ne, rtol=0, atol=1e-6)
def __init__(self, C=1, N=1, K=1, D=1, H=1, W=1, T=1, R=1, S=1, pad_d=0, pad_h=0, pad_w=0, str_d=1, str_h=1, str_w=1, dil_d=1, dil_h=1, dil_w=1, deconv=False): if deconv: M = output_dim_deconv(D, T, pad_d, str_d) P = output_dim_deconv(H, R, pad_h, str_h) Q = output_dim_deconv(W, S, pad_w, str_w) else: M = output_dim(D, T, pad_d, str_d) P = output_dim(H, R, pad_h, str_h) Q = output_dim(W, S, pad_w, str_w) self.dimO = (K, M, P, Q, N) self.dimI = (C, D, H, W, N) if deconv: self.dimF = (K, T, R, S, C) else: self.dimF = (C, T, R, S, K) self.conv_params = dict(pad_d=pad_d, pad_h=pad_h, pad_w=pad_w, str_d=str_d, str_h=str_h, str_w=str_w, dil_d=dil_d, dil_h=dil_h, dil_w=dil_w) batch_axis = ng.make_axis(name='N', length=N) self.ax_i = ng.make_axes([ ng.make_axis(name='C', length=C), ng.make_axis(name='D', length=D), ng.make_axis(name='H', length=H), ng.make_axis(name='W', length=W), batch_axis ]) if deconv: self.ax_f = ng.make_axes([ ng.make_axis(name='C', length=K), ng.make_axis(name='D', length=T), ng.make_axis(name='H', length=R), ng.make_axis(name='W', length=S), ng.make_axis(name='K', length=C), ]) else: self.ax_f = ng.make_axes([ ng.make_axis(name='C', length=C), ng.make_axis(name='D', length=T), ng.make_axis(name='H', length=R), ng.make_axis(name='W', length=S), ng.make_axis(name='K', length=K), ]) self.ax_o = ng.make_axes([ ng.make_axis(name='C', length=K), ng.make_axis(name='D', length=M), ng.make_axis(name='H', length=P), ng.make_axis(name='W', length=Q), batch_axis ])
def Conv(self, c2_op, inputs): """ Computes a 2-D convolution given 4D input and filter tensors. Arguments: c2_op: NodeDef object, the caffe2 node to convert. inputs: List of ngraph Ops as inputs to this node. Returns: A ngraph Op corresponding to the caffe2 node. Inputs to c2_op: input, wegiths, filter Supports caffe2's layout NHWC and NCHW as well. """ X, W, bias = inputs order = [val.s for val in c2_op.arg if val.name == "order"] if 1 != len(order): raise ValueError("Multiple order values in convolution") order = order[0] if order not in ("NHWC", "NCHW"): raise NotImplementedError("Unsupported order in convolution: {}", order) # set input axes shape ax_N = ng.make_axis(name='N') ax_C = ng.make_axis(roles=[ar.Channel]) ax_D = ng.make_axis(roles=[ar.Depth], length=1) ax_H = ng.make_axis(roles=[ar.Height]) ax_W = ng.make_axis(roles=[ar.Width]) # set kernel axes shape ax_kernel_D = ng.make_axis(roles=[ar.Depth], length=1) ax_kernel_H = ng.make_axis(roles=[ar.Height]) ax_kernel_W = ng.make_axis(roles=[ar.Width]) ax_kernel_ofm = ng.make_axis(roles=[ar.Channelout]) # create placeholders for output axes oC = ng.make_axis(roles=[ar.Channel]).named('C') oD = ng.make_axis(roles=[ar.Depth], length=1).named('D') oH = ng.make_axis(roles=[ar.Height]).named('H') oW = ng.make_axis(roles=[ar.Width]).named('W') axes_order = { 'NCHW': { 'X': [ax_N, ax_C, ax_H, ax_W], 'W': [ax_kernel_ofm, ax_C, ax_kernel_H, ax_kernel_W] }, 'NHWC': { 'X': [ax_N, ax_H, ax_W, ax_C], 'W': [ax_kernel_ofm, ax_kernel_H, ax_kernel_W, ax_C] }, } ng.make_axes(axes_order[order]['X']).set_shape(X.axes.lengths) ng.make_axes(axes_order[order]['W']).set_shape(W.axes.lengths) if 1 != len(bias.axes): raise ValueError("Bias's must be 1D.") if ax_kernel_ofm.length != bias.axes.lengths[0]: raise ValueError( "Bias's length must equal to number of output feature maps.") # strides params stride_size = [int(val.i) for val in c2_op.arg if val.name == "stride"] if len(stride_size) != 1: raise ValueError("Stride size must be scalar value") str_h = str_w = stride_size[0] # padding params # TODO: how to handle padding in caffe2? # padding = c2_op.attr['padding'].s.decode("ascii") # padding = (image_size - kernel_size) % stride_size padding = np.mod( np.array([ax_H.length, ax_W.length]) - np.array([ax_kernel_H.length, ax_kernel_W.length]), np.array([str_h, str_w])) if not np.array_equal(padding, [0] * len(padding)): raise NotImplementedError( "Convolution does not support padding yet") pad_t = pad_b = pad_l = pad_r = 0 if pad_t != pad_b or pad_l != pad_r: raise NotImplementedError("Requires symmetric padding in ngraph:" "pad_t(%s) == pad_b(%s) and" "pad_l(%s) == pad_r(%s)" % (pad_t, pad_b, pad_l, pad_r)) # conv params params = dict(pad_d=0, pad_h=pad_t, pad_w=pad_l, str_d=1, str_h=str_h, str_w=str_w, dil_d=1, dil_h=1, dil_w=1) # input, weight, output axes internal_ax_dict = { 'X': ng.make_axes([ax_C, ax_D, ax_H, ax_W, ax_N]), 'W': ng.make_axes( [ax_C, ax_kernel_D, ax_kernel_H, ax_kernel_W, ax_kernel_ofm]) } oC.length = ax_kernel_ofm.length oH.length = output_dim(ax_H.length, ax_kernel_H.length, params['pad_h'], params['str_h']) oW.length = output_dim(ax_W.length, ax_kernel_W.length, params['pad_w'], params['str_w']) internal_ax_dict['Y'] = ng.make_axes([oC, oD, oH, oW, ax_N]) # broadcast input / filter axes # flow for NHWC order: | flow for NCHW order: # input: | input: # expand dims: NHWC -> NDHWC | expand dims: NCHW -> NDCHW # reorder: NDHWC -> CDHWN | reorder: NDCHW -> CDHWN # weights: | weights: # expand dims: (ofm)HWC -> D(ofm)HWC | expand dims: (ofm)CHWC -> D(ofm)CHW # reorder: D(ofm)HWC -> CDHW(ofm) | reorder: D(ofm)CHW -> CDHW(ofm) X = ng.cast_axes(X, ng.make_axes(axes_order[order]['X'])) X = ng.expand_dims(X, ax_D, 1) X = ng.axes_with_order(X, axes=internal_ax_dict['X']) W = ng.cast_axes(W, ng.make_axes(axes_order[order]['W'])) W = ng.expand_dims(W, ax_kernel_D, 0) W = ng.axes_with_order(W, axes=internal_ax_dict['W']) # convolution Y = ng.convolution(params, X, W, axes=internal_ax_dict['Y']) # cast back to proper format Y = ng.broadcast(Y, ng.make_axes([ax_N, oD, oH, oW, oC])) if "NHWC" == order \ else ng.broadcast(Y, ng.make_axes([ax_N, oD, oC, oH, oW])) # NCHW # slice away the oD out_slicing = [slice(None), 0, slice(None), slice(None), slice(None)] Y = ng.tensor_slice(Y, out_slicing) def _conv_bias_add(c2_op, inputs): X, bias = inputs bias = ng.cast_axes(bias, axes=ng.make_axes( [X.axes[1 if 'NCHW' == order else 3]])) Y = ng.Add(X, bias) return Y return _conv_bias_add(c2_op, [Y, bias])
def Pool(self, c2_op, inputs): """ Performs max or average pooling on the input. Arguments: c2_op: NodeDef object, the tensorflow node to convert. inputs: List of ngraph Ops as inputs to this node. Returns: A ngraph Op corresponding to the c2_op node. Inputs to c2_op: input """ supported_pooling = {'MaxPool': 'max', 'AveragePool': 'avg'} image = inputs[0] # TODO: we assume NCHW, make some assert here? # set input axes shape ax_N = ng.make_axis(name='N') ax_C = ng.make_axis(roles=[ar.Channel]) ax_D = ng.make_axis(roles=[ar.Depth], length=1) ax_H = ng.make_axis(roles=[ar.Height]) ax_W = ng.make_axis(roles=[ar.Width]) ng.make_axes([ax_N, ax_C, ax_H, ax_W]).set_shape(image.axes.lengths) # create placeholders for output axes oC = ng.make_axis(roles=[ar.Channel]).named('C') oD = ng.make_axis(roles=[ar.Depth], length=1).named('D') oH = ng.make_axis(roles=[ar.Height]).named('H') oW = ng.make_axis(roles=[ar.Width]).named('W') # spatial kernel size kernel_size = [int(val.i) for val in c2_op.arg if val.name == "kernel"] if len(kernel_size) != 1: raise ValueError("Kernel size must be scalar value") # kernel is square kernel_h = kernel_w = kernel_size[0] kernel_d = kernel_c = 1 # strides params stride_size = [int(val.i) for val in c2_op.arg if val.name == "stride"] if len(stride_size) != 1: raise ValueError("Stride size must be scalar value") stride_h = stride_w = stride_size[0] # padding params # TODO: how to handle padding in caffe2? # padding = c2_op.attr['padding'].s.decode("ascii") # padding = (image_size - kernel_size) % stride_size padding = np.mod( np.array(image.axes.lengths) - np.array([1, 1, kernel_h, kernel_w]), np.array([1, 1, stride_size[0], stride_size[0]])) if not np.array_equal(padding, [0] * len(padding)): raise NotImplementedError( "Max pooling does not support padding yet") pad_t = pad_b = pad_l = pad_r = 0 if pad_t != pad_b or pad_l != pad_r: raise NotImplementedError("Requires symmetric padding in ngraph:" "pad_t(%s) == pad_b(%s) and" "pad_l(%s) == pad_r(%s)" % (pad_t, pad_b, pad_l, pad_r)) # pooling params params = dict(op=supported_pooling[c2_op.type], pad_d=0, pad_h=pad_t, pad_w=pad_l, pad_c=0, str_d=1, str_h=stride_h, str_w=stride_w, str_c=1, J=kernel_c, T=kernel_d, R=kernel_h, S=kernel_w) # i, o axes oC.length = output_dim(ax_C.length, kernel_c, params['pad_c'], params['str_c']) oD.length = output_dim(ax_D.length, kernel_d, params['pad_d'], params['str_d']) oH.length = output_dim(ax_H.length, kernel_h, params['pad_h'], params['str_h']) oW.length = output_dim(ax_W.length, kernel_w, params['pad_w'], params['str_w']) ax_i = ng.make_axes([ax_C, ax_D, ax_H, ax_W, ax_N]) ax_o = ng.make_axes([oC, oD, oH, oW, ax_N]) # broadcast input / filter axes image = ng.cast_axes(image, ng.make_axes([ax_N, ax_C, ax_H, ax_W])) image = ng.expand_dims(image, ax_D, 1) # NCHW -> NDCHW image = ng.axes_with_order(image, axes=ax_i) # NDCHW -> CDHWN # pooling output = ng.pooling(params, image, axes=ax_o) # cast back to NDCHW output = ng.broadcast(output, ng.make_axes([ax_N, oD, oC, oH, oW])) # slice away the oD out_slicing = [slice(None), 0, slice(None), slice(None), slice(None)] output = ng.tensor_slice(output, out_slicing) return output
def test_conv(transformer_factory): """ TODO: make this more interesting """ N, C, K = 64, 32, 32 D, H, W = 1, 32, 32 T, R, S = 1, 3, 3 pad_d, pad_h, pad_w = 0, 0, 0 str_d, str_h, str_w = 1, 1, 1 dil_d, dil_h, dil_w = 1, 1, 1 M = output_dim(D, T, pad_d, str_d) P = output_dim(H, R, pad_h, str_h) Q = output_dim(W, S, pad_w, str_w) padding = dict(pad_d=pad_d, pad_h=pad_h, pad_w=pad_w) strides = dict(str_d=str_d, str_h=str_h, str_w=str_w) dilation = dict(dil_d=dil_d, dil_h=dil_h, dil_w=dil_w) conv_params = padding.copy() conv_params.update(strides) conv_params.update(dilation) ax_i = ng.make_axes([ ng.make_axis(name='C'), ng.make_axis(name='D'), ng.make_axis(name='H'), ng.make_axis(name='W'), ax.N ]) ax_f = ng.make_axes([ ng.make_axis(name='C'), ng.make_axis(name='D'), ng.make_axis(name='H'), ng.make_axis(name='W'), ng.make_axis(name='K'), ]) ax_o = ng.make_axes([ ng.make_axis(name='C'), ng.make_axis(name='D'), ng.make_axis(name='H'), ng.make_axis(name='W'), ax.N ]) ax_i.set_shape((C, D, H, W, N)) ax_f.set_shape((C, T, R, S, K)) ax_o[:-1].set_shape((K, M, P, Q)) inputs = ng.placeholder(axes=ax_i) filters = ng.placeholder(axes=ax_f) # randomly initialize input_value = rng.uniform(-0.5, 0.5, ax_i) filter_value = rng.uniform(-0.5, 0.5, ax_f) error_value = rng.uniform(-0.5, 0.5, ax_o) assert input_value.shape == ax_i.lengths assert filter_value.shape == ax_f.lengths inputs = ng.placeholder(ax_i) filters = ng.placeholder(ax_f) errors = ng.placeholder(ax_o) output = ng.convolution(conv_params, inputs, filters, axes=ax_o) bprop_out = bprop_conv(errors, inputs, filters, output) updat_out = update_conv(errors, inputs, filters, output) with executor([output, bprop_out, updat_out], inputs, filters, errors) as conv_executor: result_ng, gradI_ng, gradF_ng = conv_executor(input_value, filter_value, error_value) # Compute reference with NumPy result_np, gradI_np, gradF_np = reference_conv(C, N, K, D, H, W, T, R, S, M, P, Q, pad_d, pad_h, pad_w, str_d, str_h, str_w, input_value, filter_value, error_value) # Compare fprop assert np.allclose(result_ng, result_np, rtol=0, atol=0.5) # Compare bprop assert np.allclose(gradI_ng, gradI_np, rtol=0, atol=0.5) # Compare update assert np.allclose(gradF_ng, gradF_np, rtol=0, atol=2)
def test_convolution(transformer_factory): """ test convolution forward path """ N = 128 C, K = 3, 8 D, T = 1, 1 H = W = 32 R = S = 2 padding = dict(pad_d=0, pad_h=0, pad_w=0) strides = dict(str_d=1, str_h=1, str_w=1) dilation = dict(dil_d=1, dil_h=1, dil_w=1) conv_params = padding.copy() conv_params.update(strides) conv_params.update(dilation) ax_i = ng.make_axes([ax.C, ax.D, ax.H, ax.W, ax.N]) ax_f = ng.make_axes([ax.C, ax.T, ax.R, ax.S, ax.K]) ax_i.set_shape((C, D, H, W, N)) ax_f.set_shape((C, T, R, S, K)) ax_o = ng.make_axes([ ng.make_axis(roles=[ar.features_input]).named('C'), ng.make_axis(roles=[ar.features_0]).named('D'), ng.make_axis(roles=[ar.features_1]).named('H'), ng.make_axis(roles=[ar.features_2]).named('W'), ax.N ]) ax_o[:-1].set_shape((K, output_dim(D, T, padding['pad_d'], strides['str_d']), output_dim(H, R, padding['pad_h'], strides['str_h']), output_dim(W, S, padding['pad_w'], strides['str_w']))) inputs = ng.placeholder(axes=ax_i) filters = ng.placeholder(axes=ax_f) # randomly initialize input_value = rng.uniform(-1, 1, ax_i) filter_value = rng.uniform(-1, 1, ax_f) assert input_value.shape == ax_i.lengths assert filter_value.shape == ax_f.lengths inputs = ng.placeholder(ax_i) filters = ng.placeholder(ax_f) output = ng.convolution(conv_params, inputs, filters, axes=ax_o) targets = ng.placeholder(axes=output.axes) costs = ng.cross_entropy_binary(ng.sigmoid(output), targets) error = ng.sum(costs, out_axes=()) / ng.batch_size(costs) d_inputs = ng.deriv(error, inputs) d_filters = ng.deriv(error, filters) targets_value = rng.uniform(.1, 0.9, output.axes) with executor([output, error, d_inputs, d_filters], inputs, filters, targets) as conv_executor: result_ng, err_ng, gradI_ng, gradF_ng = \ conv_executor(input_value, filter_value, targets_value) # Now compute reference values via NEON NervanaObject.be.bsz = N neon_layer = Convolution(fshape=(R, S, K), padding=padding, strides=strides) inp = neon_layer.be.array(input_value.reshape(C * H * W * D, N)) neon_layer.W = neon_layer.be.array(filter_value.reshape(C * R * S * T, K)) neon_layer.dW = neon_layer.be.empty_like(neon_layer.W) neon_layer.configure((C, H, W)) neon_layer.prev_layer = True neon_layer.allocate() neon_layer.set_deltas(DummyDeltaBuffers()) result_ne = neon_layer.fprop(inp).get().reshape(output.axes.lengths) act_result_ne = 1. / (1.0 + np.exp(-result_ne)) err = neon_layer.be.array( (act_result_ne - targets_value).reshape(-1, N) / float(N)) gradI_ne = neon_layer.bprop(err).get().reshape(ax_i.lengths) gradF_ne = neon_layer.dW.get().reshape(ax_f.lengths) # Compare fprop ng.testing.assert_allclose(result_ng, result_ne, rtol=0, atol=1e-6) # Compare bprop ng.testing.assert_allclose(gradI_ng, gradI_ne, rtol=0, atol=1e-6) # Compare update ng.testing.assert_allclose(gradF_ng, gradF_ne, rtol=0, atol=1e-4)