def save_graph(net, file_name, graph_name="net", op_only=True):
    from caffe2.python import net_drawer
    graph = None
    ops = net.op
    if not op_only:
        graph = net_drawer.GetPydotGraph(ops, graph_name, rankdir="TB")
    else:
        graph = net_drawer.GetPydotGraphMinimal(ops,
                                                graph_name,
                                                rankdir="TB",
                                                minimal_dependency=True)

    try:
        graph.write_png(file_name)
    except Exception as e:
        print('Error when writing graph to image {}'.format(e))
Example #2
0
def AddMLPModel(model, data, save_png=True):
    """Multi-layer Perceptron model"""
    size = 28 * 28 * 1
    sizes = [size, size * 4, size * 2, 10]
    layer = data
    for i in range(len(sizes) - 1):
        layer = brew.fc(model,
                        layer,
                        'dense_{}'.format(i),
                        dim_in=sizes[i],
                        dim_out=sizes[i + 1])
        layer = brew.relu(model, layer, 'relu_{}'.format(i))
    softmax = brew.softmax(model, layer, 'softmax')

    if save_png:
        graph = net_drawer.GetPydotGraph(model.net)
        graph.write_png("MLP.png")

    return softmax
Example #3
0
def visualize_net(model, path, minimal=False):
    from caffe2.python import net_drawer
    net_name = model.net.Proto().name
    if minimal:
        graph = net_drawer.GetPydotGraphMinimal(model.net.Proto().op,
                                                net_name,
                                                minimal_dependency=True)
    else:
        graph = net_drawer.GetPydotGraph(
            model.net.Proto().op,
            net_name,
        )
    if minimal:
        img_output_path = os.path.join(path, net_name + '_minimal.png')
    else:
        img_output_path = os.path.join(path, net_name + '_full.png')
    with open(img_output_path, 'w') as fopen:
        fopen.write(graph.create_png())
        logger.info("{}: Net image saved to: {}".format(
            net_name, img_output_path))
Example #4
0
def generate_network_graph(model, config, tag="", use_mini=True):
    ''' generate the svg graph that show the network structure
    Args:
        use_mini: whether show full nodes of blobs and operators
        tag: user specific name-tag
    '''
    # resolving necessary params
    graph_dir = os.path.join(config['root_dir'], "output")
    if tag != "":
        tag = tag + "_"

    # draw graph
    if not use_mini:
        # full-graph
        full_graph = net_drawer.GetPydotGraph(
            model.net.Proto().op,
            "full_graph",
            rankdir="TB",
        )
        graph_path = os.path.join(
            graph_dir,
            "{}_{}_{}graph.svg".format(config['model_name'],
                                       config['dataset_name'], tag),
        )
        full_graph.write_svg(graph_path)
    else:
        # mini-graph
        mini_graph = net_drawer.GetPydotGraphMinimal(model.net.Proto().op,
                                                     "mini_graph",
                                                     rankdir="TB",
                                                     minimal_dependency=True)
        graph_path = os.path.join(
            graph_dir,
            "{}_{}_{}graph_minimal.svg".format(config['model_name'],
                                               config['dataset_name'], tag),
        )
        mini_graph.write_svg(graph_path)
    print("[INFO] write graph over...")
test_model = model_helper.ModelHelper(name="event_test",
                                      arg_scope=arg_scope,
                                      init_params=False)
test_features, test_labels = AddInput(test_model,
                                      30,
                                      'event_test1.minidb',
                                      db_type='minidb')
#workspace.FeedBlob("TestD",test_features.astype(np.float32))
#workspace.FeedBlob("TestL", train_labels.astype(np.int32))
softmax = addModel(test_model, test_features)
AddAccuracy(test_model, softmax, test_labels)

from IPython import display
graph = net_drawer.GetPydotGraph(train_model.net.Proto().op,
                                 name="events",
                                 rankdir="LR")
display.Image(graph.create_png(), width=800)

workspace.RunNetOnce(train_model.param_init_net)

workspace.CreateNet(train_model.net, overwrite=True)
total_iters = 1000
accuracy = np.zeros(total_iters)
loss = np.zeros(total_iters)

for i in range(total_iters):
    workspace.RunNet(train_model.net.Proto().name)
    accuracy[i] = workspace.FetchBlob('accuracy')
    loss[i] = workspace.FetchBlob('loss')
    #print("First Layer Weights: ")
Example #6
0
print("Type of X is: {}".format(type(X)))
print("The blob name is: {}".format(str(X)))

W = net.GaussianFill([], ["W"], mean=0.0, std=1.0, shape=[5, 3], run_once=0)
b = net.ConstantFill([], ["b"], shape=[
    5,
], value=1.0, run_once=0)

Y = X.FC([W, b], ["Y"])
print("Current network proto:\n\n{}".format(net.Proto()))

from caffe2.python import net_drawer
from IPython import display

graph = net_drawer.GetPydotGraph(net, rankdir="LR")
display.Image(graph.create_png(), width=800)

workspace.ResetWorkspace()
print("Current blobs in the workspace: {}".format(workspace.Blobs()))
workspace.RunNetOnce(net)
print("Blobs in the workspace after execution: {}".format(workspace.Blobs()))
# Let's dump the contents of the blobs
for name in workspace.Blobs():
    print("{}:\n{}".format(name, workspace.FetchBlob(name)))

workspace.ResetWorkspace()
print("Current blobs in the workspace: {}".format(workspace.Blobs()))
workspace.CreateNet(net)
workspace.RunNet(net.Proto().name)
print("Blobs in the workspace after execution: {}".format(workspace.Blobs()))
Example #7
0
 def draw_nets(self):
     for net_name in self.net_store:
         net = self.net_store[net_name]
         graph = net_drawer.GetPydotGraph(net.Proto().op, rankdir='TB')
         with open(net.Name() + ".png", 'wb') as f:
             f.write(graph.create_png())
Example #8
0
def get_model(cfg_file, weights_file):
    merge_cfg_from_file(cfg_file)
    cfg.TRAIN.WEIGHTS = ''  # NOTE: do not download pretrained model weights
    cfg.TEST.WEIGHTS = weights_file
    cfg.NUM_GPUS = 1
    assert_and_infer_cfg()
    model = infer_engine.initialize_model_from_cfg()
    return model


DETECTRON_ROOT = '/home/long/github/detectron'
cfg_file = '{}/configs/getting_started/res18_1mlp_fpn64.yaml'.format(
    DETECTRON_ROOT)
weights_file = '/media/E/models/detectron/ImageNetPretrained/R-18.pkl'
model = get_model(cfg_file, weights_file)

from caffe2.python import net_drawer
g = net_drawer.GetPydotGraph(model, rankdir="TB")
g.write_dot(model.Proto().name + '.dot')

g.write_png(model.Proto().name + ".png")
img1 = cv2.imread(model.Proto().name + ".png", 1)

cv2.imshow("Netgraph", img1)

cv2.waitKey(0)

#command line
# png: dot graph1.gv -Tpng -o test.png
#
# pdf: dot graph1.gv -Tpdf -o test.pdf
Example #9
0
                    help='Batch Size')
parser.add_argument('--steps', type=int, default=10,
                    help='Number of steps to measure.')
args, _ = parser.parse_known_args()

workspace.ResetWorkspace()
workspace.GlobalInit(['caffe2', '--caffe2_log_level=2',
            '--caffe2_net_async_thread_pool_size=' + str(args.async_threads)])

init_net = mynet.init_net
predict_net = mynet.predict_net
# you must name it something
predict_net.name = "rcnn_predict"

from caffe2.python import net_drawer
g = net_drawer.GetPydotGraph(predict_net, rankdir="TB")
g.write_dot('test.dot')
if args.proto_type != '':
    predict_net.type = 'async_scheduling'
#predict_net.type = 'prof_dag'

img=np.ones((args.batch_size, 3, 224, 224)).astype(np.float32)
workspace.FeedBlob("data", img)

workspace.RunNetOnce(init_net)
workspace.CreateNet(predict_net)

p = workspace.Predictor(init_net.SerializeToString(), predict_net.SerializeToString())
results = p.run({'data': img})

Example #10
0
def plot_net(file_name, net_proto):
    #plot the net
    graph = net_drawer.GetPydotGraph(net_proto.Proto().op,
                                     net_proto.Proto().name,
                                     rankdir="LR")
    graph.write_png(file_name)
Example #11
0
  
  
def get_model(cfg_file, weights_file):  
    merge_cfg_from_file(cfg_file)  
    cfg.TRAIN.WEIGHTS = ''  # NOTE: do not download pretrained model weights  
    cfg.TEST.WEIGHTS = weights_file  
    cfg.NUM_GPUS = 1  
    assert_and_infer_cfg() 
    #according the cfg to bulid model
    model = model_builder.create(cfg.MODEL.TYPE,train=True)  
    return model  
  
  
if __name__ == '__main__':  
    args = parse_args()  
    #get the model 
    model = get_model(args.cfg, args.weights)
    print(model.net)
    ops = model.net.Proto().op
    #ops is protobuf object
    print(len(ops),type(ops))
    for i in range(len(ops)):
        output_name = str(ops[i].output[0]) 
        #remove the all op about grad
        if str(ops[i].type) == 'SigmoidCrossEntropyLossGradient':
            break
    ops = ops[:i]
    g = net_drawer.GetPydotGraph(ops, rankdir="TB")
    #g = net_drawer.GetPydotGraphMinimal(ops, rankdir="TB")  
    g.write_png(model.Proto().name + 'test.png')  
Example #12
0
            sigmoid_bot=-1,
            sigmoid_top=ln_top.size - 1,
            save_onnx=flag_types_shapes,
            ndevices=ndevices,
            # forward_ops = flag_forward_ops
            enable_prof=args.enable_profiling,
        )
    # load nccl if using multiple devices
    if args.sync_dense_params and ndevices > 1:
        dyndep.InitOpsLibrary("//caffe2/caffe2/contrib/nccl:nccl_ops")
    # set the net type for better performance (dag, async_scheduling, etc)
    if args.caffe2_net_type:
        dlrm.parameters().net.Proto().type = args.caffe2_net_type
    # plot compute graph
    if args.plot_compute_graph:
        graph = net_drawer.GetPydotGraph(dlrm.parameters().net, "dlrm_s_caffe2_graph", "BT")
        graph.write_pdf(graph.get_name() + ".pdf")
    # test prints
    if args.debug_mode:
        print("initial parameters (weights and bias):")
        dlrm.print_weights()

    # add training loss if needed
    if not args.inference_only:
        with core.DeviceScope(device_opt):
            # specify the loss function
            nd = 1.0 if dlrm.ndevices <= 1 else 1.0 / dlrm.ndevices  # 1
            if args.loss_function == "mse":
                dlrm.MSEloss(scale=nd)
            elif args.loss_function == "bce":
                dlrm.BCEloss(scale=nd, threshold=args.loss_threshold)
Example #13
0
                       db=os.path.join(data_folder, 'mnist-test-nchw-lmdb'),
                       db_type='lmdb')
softmax = AddLeNetModel(test_model, data)
AddAccuracy(test_model, softmax, label)

# Deployment model. We simply need the main LeNetModel part.
deploy_model = model_helper.ModelHelper(name="mnist_deploy",
                                        arg_scope=arg_scope,
                                        init_params=False)
AddLeNetModel(deploy_model, "data")
# You may wonder what happens with the param_init_net part of the deploy_model.
# No, we will not use them, since during deployment time we will not randomly
# initialize the parameters, but load the parameters from the db.

graph = net_drawer.GetPydotGraph(train_model.net.Proto().op,
                                 "mnist",
                                 rankdir="LR")
graph.write_svg('Second.svg')

graph = net_drawer.GetPydotGraphMinimal(train_model.net.Proto().op,
                                        "mnist",
                                        rankdir="LR",
                                        minimal_dependency=True)
graph.write_svg('Third.svg')

print(str(train_model.param_init_net.Proto())[:400] + '\n...')

with open(os.path.join(root_folder, "train_net.pbtxt"), 'w') as fid:
    fid.write(str(train_model.net.Proto()))
with open(os.path.join(root_folder, "train_init_net.pbtxt"), 'w') as fid:
    fid.write(str(train_model.param_init_net.Proto()))
Example #14
0
# Create model using a model helper
m = model_helper.ModelHelper(name="my first net")
weight = m.param_init_net.XavierFill([], 'fc_w', shape=[10, 100])
bias = m.param_init_net.ConstantFill([], 'fc_b', shape=[
    10,
])

fc_1 = m.net.FC(["data", "fc_w", "fc_b"], "fc1")
pred = m.net.Sigmoid(fc_1, "pred")
softmax, loss = m.net.SoftmaxWithLoss([pred, "label"], ["softmax", "loss"])

# print(m.net.Proto())
# print(m.param_init_net.Proto())

# save the model as graph
graph = net_drawer.GetPydotGraph(m.net, rankdir="BT")
graph.write_png("hello.png")

# init, create and run
m.AddGradientOperators([loss])  # add gradient
# print(m.net.Proto())          # observe gradient

workspace.RunNetOnce(m.param_init_net)
workspace.CreateNet(m.net)

for ii in range(100):
    data = np.random.rand(16, 100).astype(np.float32)
    label = (np.random.rand(16) * 10).astype(np.int32)

    workspace.FeedBlob("data", data)
    workspace.FeedBlob("label", label)
    def TrainModel(self):
        log.debug("Training model")

        workspace.RunNetOnce(self.model.param_init_net)

        # As though we predict the same probability for each character
        smooth_loss = -np.log(1.0 / self.D) * self.seq_length
        last_n_iter = 0
        last_n_loss = 0.0
        num_iter = 0
        N = len(self.text)

        # We split text into batch_size pieces. Each piece will be used only
        # by a corresponding batch during the training process
        text_block_positions = np.zeros(self.batch_size, dtype=np.int32)
        text_block_size = N // self.batch_size
        text_block_starts = list(range(0, N, text_block_size))
        text_block_sizes = [text_block_size] * self.batch_size
        text_block_sizes[self.batch_size - 1] += N % self.batch_size
        assert sum(text_block_sizes) == N

        # Writing to output states which will be copied to input
        # states within the loop below
        workspace.FeedBlob(
            self.hidden_output,
            np.zeros([1, self.batch_size, self.hidden_size], dtype=np.float32))
        workspace.FeedBlob(
            self.cell_state,
            np.zeros([1, self.batch_size, self.hidden_size], dtype=np.float32))
        workspace.CreateNet(self.prepare_state)

        graph = net_drawer.GetPydotGraph(self.model.net, "mnist", rankdir="LR")
        experiment.set_model_graph(graph)

        # We iterate over text in a loop many times. Each time we peak
        # seq_length segment and feed it to LSTM as a sequence
        last_time = datetime.now()
        progress = 0
        while True:
            workspace.FeedBlob(
                "seq_lengths",
                np.array([self.seq_length] * self.batch_size, dtype=np.int32))
            workspace.RunNet(self.prepare_state.Name())

            input = np.zeros([self.seq_length, self.batch_size,
                              self.D]).astype(np.float32)
            target = np.zeros([self.seq_length * self.batch_size
                               ]).astype(np.int32)

            for e in range(self.batch_size):
                for i in range(self.seq_length):
                    pos = text_block_starts[e] + text_block_positions[e]
                    input[i][e][self._idx_at_pos(pos)] = 1
                    target[i * self.batch_size + e] =\
                        self._idx_at_pos((pos + 1) % N)
                    text_block_positions[e] = (text_block_positions[e] +
                                               1) % text_block_sizes[e]
                    progress += 1

            workspace.FeedBlob('input_blob', input)
            workspace.FeedBlob('target', target)

            CreateNetOnce(self.model.net)
            workspace.RunNet(self.model.net.Name())

            num_iter += 1
            last_n_iter += 1

            if num_iter % self.iters_to_report == 0:
                new_time = datetime.now()
                print("Characters Per Second: {}".format(
                    int(progress / (new_time - last_time).total_seconds())))
                print("Iterations Per Second: {}".format(
                    int(self.iters_to_report /
                        (new_time - last_time).total_seconds())))

                last_time = new_time
                progress = 0

                print("{} Iteration {} {}".format('-' * 10, num_iter,
                                                  '-' * 10))

            loss = workspace.FetchBlob(self.loss) * self.seq_length
            smooth_loss = 0.999 * smooth_loss + 0.001 * loss
            last_n_loss += loss

            experiment.log_metric("loss", smooth_loss)

            if num_iter % self.iters_to_report == 0:
                self.GenerateText(500, np.random.choice(self.vocab))
                lass_loss = last_n_loss / last_n_iter

                log.debug("Loss since last report: {}".format(last_n_loss /
                                                              last_n_iter))
                log.debug("Smooth loss: {}".format(smooth_loss))

                last_n_loss = 0.0
                last_n_iter = 0
Example #16
0
 def writeGraphToFile(self, filename):
     graph = net_drawer.GetPydotGraph(self.model.Proto().op,
                                      "train",
                                      rankdir="LR")
     with open(filename, "wb") as f:
         f.write(graph.create_svg())
Example #17
0
def gen_graph(net, output):
    graph = net_drawer.GetPydotGraph(net, rankdir = 'LR')
    graph.write_png(output)
Example #18
0
if __name__ == "__main__":
    if not os.path.exists("data"):
        os.mkdir("data")
    write_db("minidb", "data/iris_train.minidb", train_features, train_labels)
    write_db("minidb", "data/iris_test.minidb", test_features, test_labels)

    #
    # Define a training model
    #
    train_model = model_helper.ModelHelper("iris_train")
    train_data, train_labels = AddInput(train_model, "data/iris_train.minidb",
                                        "minidb", "train_data", "train_label")
    softmax = AddMLPModel(train_model, train_data)
    AddTrainingOperators(train_model, softmax, train_labels)

    graph = net_drawer.GetPydotGraph(train_model, rankdir="LR")
    graph.write_png("Iris_MLP.png")

    #
    # Run training
    #
    workspace.RunNetOnce(train_model.param_init_net)
    workspace.CreateNet(train_model.net, overwrite=True)
    total_iters = 150

    accuracy = np.zeros(total_iters)
    loss = np.zeros(total_iters)

    for i in range(total_iters):
        workspace.RunNet(train_model.net)
        accuracy[i] = workspace.blobs['accuracy']
             cmap=cm.coolwarm,
             linewidth=0,
             antialiased=False)
ax3.plot_surface(X_pred,
                 Y_pred,
                 Z,
                 cmap=cm.coolwarm,
                 linewidth=0,
                 antialiased=False)
ax4.plot_surface(X_pred,
                 Y_pred,
                 Z_pred,
                 cmap=cm.coolwarm,
                 linewidth=0,
                 antialiased=False)
plt.show()

# Eval
eval_net = instantiator.generate_eval_net(model)
graph = net_drawer.GetPydotGraph(eval_net.Proto().op, rankdir='TB')
with open(eval_net.Name() + ".png", 'wb') as f:
    f.write(graph.create_png())
f = open('eval_net.txt', 'w')
f.write(str(eval_net.Proto()))
f.close()
# Predict
# pred_net = instantiator.generate_predict_net(model)
# graph = net_drawer.GetPydotGraph(pred_net.Proto().op, rankdir='TB')
# with open(pred_net.Name() + ".png",'wb') as f:
# 	f.write(graph.create_png())
Example #20
0
brew.fc(full_model, 'hidden', 'prediction', HIDDEN_SIZE, 1)
full_model.Sigmoid('prediction', 'prediction')
gradient_map = full_net.AddGradientOperators(['loss'])
# full_net.WeightedSum(['prediction_w', ONE, gradient_map['prediction_w'], ONE], 'prediction_w')
# full_net.WeightedSum(['prediction_b', ONE, gradient_map['prediction_w'], ONE], 'prediction_b')

# Run the init nets once
workspace.RunNetOnce(forward_init_net)
workspace.RunNetOnce(full_init_net)

# Create the forward and full nets
workspace.CreateNet(forward_net)
workspace.CreateNet(full_net)

graph = net_drawer.GetPydotGraph(forward_net.Proto().op,
                                 "forward",
                                 rankdir="LR")
graph.write_png('forward.png', prog='dot')

graph = net_drawer.GetPydotGraph(full_net.Proto().op, "full", rankdir="LR")
graph.write_png('full.png', prog='dot')

for i_episode in count(1):
    ep_rewards = []
    ep_states = []
    ep_actions = []
    ep_predictions = []
    state = env.reset()

    for t in range(1000):
        env.render() if args.render else False
Example #21
0
# Increment the iteration by one per RunNet()
train_net.Iter(ITER, ITER)
# Compute the learning rate that corresponds to the iteration.
LR = train_net.LearningRate(ITER,
                            "LR",
                            base_lr=-0.1,
                            policy="step",
                            stepsize=20,
                            gamma=0.9)

# Weighted sum: 1 is the weight for W and learning rate is the weight for dw
# So this is equivalent to: W = W + lr*dw
train_net.WeightedSum([W, ONE, gradient_map[W], LR], W)
train_net.WeightedSum([B, ONE, gradient_map[B], LR], B)

graph = net_drawer.GetPydotGraph(train_net.Proto().op, "train", rankdir="LR")
graph.write_png('graph.png')
display.Image(graph.create_png(), width=800)

workspace.RunNetOnce(init_net)
workspace.CreateNet(train_net)

print("Before training, W is: {}".format(workspace.FetchBlob("W")))
print("Before training, B is: {}".format(workspace.FetchBlob("B")))

for i in range(120):
    workspace.RunNet(train_net.Proto().name)
    #print("Iter is: {}".format(workspace.FetchBlob("ITER")))

#print("Y_gt {}".format(workspace.FetchBlob("Y_gt")))
#print("Y_noise {}".format(workspace.FetchBlob("Y_noise")))
Example #22
0
def test(option, iters):
    init_net = core.Net("init")
    # The ground truth parameters.
    W_gt = init_net.GivenTensorFill([],
                                    "W_gt",
                                    shape=[1, 2],
                                    values=[2.0, 1.5])
    B_gt = init_net.GivenTensorFill([], "B_gt", shape=[1], values=[0.5])
    # Constant value ONE is used in weighted sum when updating parameters.
    ONE = init_net.ConstantFill([], "ONE", shape=[1], value=1.)
    # ITER is the iterator count.
    ITER = init_net.ConstantFill([],
                                 "ITER",
                                 shape=[1],
                                 value=0,
                                 dtype=core.DataType.INT32)

    # For the parameters to be learned: we randomly initialize weight
    # from [-1, 1] and init bias with 0.0.
    W = init_net.UniformFill([], "W", shape=[1, 2], min=-1., max=1.)
    B = init_net.ConstantFill([], "B", shape=[1], value=0.0)
    print('Created init net.')

    train_net = core.Net("train")
    # First, we generate random samples of X and create the ground truth.
    X = train_net.GaussianFill([],
                               "X",
                               shape=[64, 2],
                               mean=0.0,
                               std=1.0,
                               run_once=0)
    Y_gt = X.FC([W_gt, B_gt], "Y_gt")
    # We add Gaussian noise to the ground truth
    noise = train_net.GaussianFill([],
                                   "noise",
                                   shape=[64, 1],
                                   mean=0.0,
                                   std=1.0,
                                   run_once=0)
    Y_noise = Y_gt.Add(noise, "Y_noise")
    # Note that we do not need to propagate the gradients back through Y_noise,
    # so we mark StopGradient to notify the auto differentiating algorithm
    # to ignore this path.
    Y_noise = Y_noise.StopGradient([], "Y_noise")

    # Now, for the normal linear regression prediction, this is all we need.
    Y_pred = X.FC([W, B], "Y_pred")

    # The loss function is computed by a squared L2 distance, and then averaged
    # over all items in the minibatch.
    dist = train_net.SquaredL2Distance([Y_noise, Y_pred], "dist")
    loss = dist.AveragedLoss([], ["loss"])

    graph = net_drawer.GetPydotGraph(train_net.Proto().op,
                                     "train",
                                     rankdir="LR")
    img = graph.create_png()
    save_img(img, 'forward.png')
    show_net(train_net)

    # Get gradients for all the computations above.
    gradient_map = train_net.AddGradientOperators([loss])
    graph = net_drawer.GetPydotGraph(train_net.Proto().op,
                                     "train",
                                     rankdir="LR")
    img = graph.create_png()
    save_img(img, 'grad.png')
    show_net(train_net)

    # Increment the iteration by one.
    train_net.Iter(ITER, ITER)
    # Compute the learning rate that corresponds to the iteration.
    LR = train_net.LearningRate(ITER,
                                "LR",
                                base_lr=-0.1,
                                policy="step",
                                stepsize=20,
                                gamma=0.9)

    # Weighted sum
    train_net.WeightedSum([W, ONE, gradient_map[W], LR], W)
    train_net.WeightedSum([B, ONE, gradient_map[B], LR], B)

    # Let's show the graph again.
    graph = net_drawer.GetPydotGraph(train_net.Proto().op,
                                     "train",
                                     rankdir="LR")
    img = graph.create_png()
    save_img(img, 'backprop.png')

    show_net(train_net)

    workspace.RunNetOnce(init_net)
    workspace.CreateNet(train_net)

    if option == 1:
        show_all_blobs()
        print('run once')
        workspace.RunNet(train_net.Proto().name)
        show_all_blobs()

        print('run iters')
        for i in range(iters):
            workspace.RunNet(train_net.Proto().name)

        show_all_blobs()

    if option == 2:
        workspace.RunNetOnce(init_net)
        w_history = []
        b_history = []
        for i in range(iters):
            workspace.RunNet(train_net.Proto().name)
            w_history.append(workspace.FetchBlob("W"))
            b_history.append(workspace.FetchBlob("B"))

        show_all_blobs()
        w_history = np.vstack(w_history)
        b_history = np.vstack(b_history)
        pyplot.plot(w_history[:, 0], w_history[:, 1], 'r')
        pyplot.axis('equal')
        pyplot.xlabel('w_0')
        pyplot.ylabel('w_1')
        pyplot.grid(True)
        pyplot.figure()
        pyplot.plot(b_history)
        pyplot.xlabel('iter')
        pyplot.ylabel('b')
        pyplot.grid(True)
        pyplot.show()