Example #1
0
 def __str__(self):
     val_iters = self.select_iters('val')
     out = 'StatsLogger with {} iters'.format(len(self.stats))
     if val_iters:
         summary = self.summary('val', val_iters[-1])
         out += '. Last val iter:\n'
         with utils.printoptions(suppress=True, precision=4):
             summary_str = ['{} = {}'.format(k, v) for (k, v) in summary.items()]
             out += '\n'.join(summary_str)
     return out
Example #2
0
 def fit_iterable(self, X, y=None):
     trace_op, trace_graph = True, False
     # check params
     self.check_params()
     # init graph and session
     if not hasattr(self, 'session_'):
         self.graph_ = tf.Graph()
         with self.graph_.as_default():
             tf.set_random_seed(self.random_seed)
             with vs.variable_scope('RRI') as scope:
                 self.build_graph()
         config = tf.ConfigProto()
         config.allow_soft_placement = True
         config.log_device_placement = False
         config.gpu_options.allow_growth = True
         self.session_ = tf.Session(graph=self.graph_, config=config)
         if self.reuse_model:  # read model from file
             print('load model from "{}"'.format(self.reuse_model))
             self.saver.restore(self.session_, self.reuse_model)
         else:  # initialize model
             self.session_.run(self.init_all_vars)
             self.session_.run(self.init_all_vars_local)
     # profile
     builder = option_builder.ProfileOptionBuilder
     #profiler = model_analyzer.Profiler(graph=self.graph_)
     run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
     run_metadata = tf.RunMetadata()
     # train
     for epoch in range(self.n_epochs):
         epoch += 1
         start = time.time()
         feed_time_all = 0
         loss_list, com_r_list, stop_r_list, total_offset_list, step_list = [], [], [], [], []
         for i, (fd, feed_time) in enumerate(
                 self.batcher(X,
                              y,
                              self.batch_size,
                              use_permutation=True,
                              batch_num=self.batch_num)):
             feed_time_all += feed_time
             batch_size = len(fd['query'])
             fetch = [
                 self.rri_info['step'], self.rri_info['location'],
                 self.rri_info['match_matrix'], self.loss,
                 self.rri_info['complete_ratio'], self.rri_info['is_stop'],
                 self.rri_info['stop_ratio'], self.rri_info['total_offset'],
                 self.trainer
             ]
             feed_dict = self.feed_dict_postprocess(fd, is_train=True)
             start_time = time.time()
             if self.summary_path != None and i % 1 == 0:  # run statistics
                 step, location, match_matrix, loss, com_r, is_stop, stop_r, total_offset, _ = \
                     self.session_.run(fetch, feed_dict=feed_dict, options=run_options, run_metadata=run_metadata)
                 end_time = time.time()
                 self.train_writer.add_run_metadata(run_metadata,
                                                    'step%d' % i)
                 print('adding run metadata for {}'.format(i))
                 if trace_op:
                     profiler_opts = builder(
                         builder.time_and_memory()).order_by(
                             'micros').build()
                     tf.profiler.profile(self.graph_,
                                         run_meta=run_metadata,
                                         cmd='op',
                                         options=profiler_opts)
                     input('press to continue')
                 if trace_graph:
                     #profiler.add_step(step=i, run_meta=run_metadata)
                     #profiler_opts_builder = builder(builder.time_and_memory())
                     #profiler_opts_builder.with_timeline_output(timeline_file='summary/profiler.json')
                     #profiler_opts_builder.with_step(i)
                     #profiler.profile_graph(profiler_opts_builder.build())
                     trace = timeline.Timeline(
                         step_stats=run_metadata.step_stats)
                     trace_file = open('summary/profiler.json', 'w')
                     trace_file.write(trace.generate_chrome_trace_format())
                 print('profile run metadata for {}'.format(i))
             else:
                 step, location, match_matrix, loss, com_r, is_stop, stop_r, total_offset, _ = \
                     self.session_.run(fetch, feed_dict=feed_dict)
                 end_time = time.time()
             loss_list.append(loss)
             com_r_list.append(com_r)
             stop_r_list.append(stop_r)
             [total_offset_list.append(to) for to in total_offset]
             [step_list.append(st) for st in step]
             if self.verbose >= 2:
                 print(
                     '{:<5}\t{:>5.3f}\tloss:{:>5.3f}\tcom ratio:{:>3.2f}\tstop ratio:{:>3.2f}'
                     .format(i, end_time - start_time, loss, com_r, stop_r))
             if args.debug and hasattr(self, 'test_rnn_grad'):
                 test_rnn_grad, = self.session_.run([self.test_rnn_grad],
                                                    feed_dict=feed_dict)
                 with printoptions(precision=3,
                                   suppress=True,
                                   threshold=np.nan):
                     print(np.max(np.abs(test_rnn_grad), axis=1))
                     #input()
             if args.debug and self.word_vector_trainable and hasattr(
                     self, 'test_wv_grad'):
                 test_grad, = self.session_.run([self.test_wv_grad],
                                                feed_dict=feed_dict)
                 with printoptions(precision=3,
                                   suppress=True,
                                   threshold=np.nan):
                     print(type(test_grad))
                     print(len(test_grad.indices))
                     #print(np.sum(np.any(test_grad[0] != 0, axis=2), axis=1))
                     inds = np.any(np.abs(test_grad.values) >= .001, axis=1)
                     w_inds, u_w_inds = test_grad.indices[inds], np.unique(
                         test_grad.indices[inds])
                     print(np.sum(w_inds), len(u_w_inds))
                     print(w_inds)
                     print(u_w_inds)
                     print(self.vocab.decode(u_w_inds))
                     print(np.max(np.abs(test_grad.values[inds]), axis=1))
                     #input()
             if args.debug:
                 cont = input('continue debug? y for yes:')
                 if cont != 'y':
                     continue
                 with printoptions(precision=3,
                                   suppress=True,
                                   threshold=np.nan):
                     for b in range(batch_size):
                         print(
                             'qd_size: {}, step: {}, is_stop: {}, offset: {}'
                             .format(fd['qd_size'][b], step[b], is_stop[b],
                                     total_offset[b]))
                         print('qid: {}, docid: {}'.format(
                             fd['qid'][b], fd['docid'][b]))
                         print(location[b, :step[b] + 1])
                         print(
                             np.max(match_matrix[b][:fd['qd_size'][
                                 b, 1], :fd['qd_size'][b, 0]],
                                    axis=1))
                         bcont = input('break? y for yes:')
                         if bcont == 'y':
                             break
         if self.verbose >= 1:  # output epoch stat
             print(
                 '{:<10}\t{:>7}:{:>6.3f}\tstop:{:>5.3f}\toffset:{:>5.1f}\tstep:{:>3.1f}'
                 .format(
                     'EPO[{}_{:>3.1f}_{:>3.1f}]'.format(
                         epoch, (time.time() - start) / 60,
                         feed_time_all / 60), 'train', np.mean(loss_list),
                     np.mean(stop_r_list), np.mean(total_offset_list),
                     np.mean(step_list)),
                 end='',
                 flush=True)
         if self.save_epochs and epoch % self.save_epochs == 0:  # save the model
             if self.save_model:
                 self.saver.save(self.session_, self.save_model)
             yield
         # save the final model
         elif epoch == self.n_epochs and self.save_epochs and self.n_epochs % self.save_epochs != 0:
             if self.save_model:
                 self.saver.save(self.session_, self.save_model)
             yield
         if self.verbose:
             print('')
Example #3
0
def main():
    if args.arch not in {'lstm', 'mdlstm', 'cnn'}:
        raise Exception(
            'not support arch type (should be one of "lstm", "mdlstm", "cnn").'
        )

    # config
    visualization = 'saliency'  # kernel, saliency
    learning_rate = 0.001 * 0.5
    anisotropy = False
    distribution = 'power_law'
    mean_match_query_term = 3
    mean_match_count = 5
    batch_size = 256
    h = 5
    w = 10
    channels = 1
    hidden_size = 50
    mean_match_doc_term = max(
        1, int(mean_match_count * h / mean_match_query_term))
    cnn_arch = [[3, 3, 1, 16], [1, 2, 2, 1], [3, 3, 16, 32], [1, 2, 2, 1],
                [2, 2, 32, 64], [1, 2, 2, 1]]
    #cnn_arch = [[3, 3, 1, 1], [1, 1, 1, 1]]
    cnn_activation = 'relu'

    # graph
    #grad_debugger = tf_debug.GradientsDebugger()
    #if args.tf_summary:
    #    global_step = tf.train.get_or_create_global_step()
    #    summary_writer = tf.contrib.summary.create_file_writer(args.tf_summary_path, flush_millis=10000)

    tf.set_random_seed(SEED)
    x = tf.placeholder(tf.float32, [None, h, w, channels])
    y = tf.placeholder(tf.float32, [None, h, w, channels])
    x_w = tf.placeholder(tf.float32, [None, h, w])
    bs = tf.shape(x)[0]

    #with summary_writer.as_default(), tf.contrib.summary.always_record_summaries():
    if args.arch == 'mdlstm':
        print('Using Multi Dimensional LSTM !')
        if args.rnn_type == 'dynamic':
            nn_out, rnn_states = multi_dimensional_rnn_while_loop(
                rnn_size=hidden_size, input_data=x, sh=[1, 1])
        elif args.rnn_type == 'static':
            nn_out, rnn_states = multi_dimensional_rnn_static(
                rnn_size=hidden_size, input_data=x, sh=[1, 1])
        #debug_rnn_states = grad_debugger.identify_gradient(rnn_states)
    elif args.arch == 'lstm':
        print('Using Standard LSTM !')
        nn_out = standard_lstm(input_data=x, rnn_size=hidden_size)
    elif args.arch == 'cnn':
        print('Using CNN !')
        nn_out = cnn(x, architecture=cnn_arch, activation=cnn_activation)
        nn_out = tf.reshape(nn_out, (bs, int(np.prod(nn_out.get_shape()[1:]))))

    # linear transformation (no activation)
    model_out = slim.fully_connected(inputs=nn_out,
                                     num_outputs=1,
                                     activation_fn=None)

    if args.arch == 'cnn':
        loss = 1e4 * tf.reduce_sum(tf.abs(
            tf.reshape(tf.boolean_mask(y, tf.expand_dims(x_w, axis=-1) > 0), [bs, 1]) - model_out)) / \
               tf.cast(bs, tf.float32)
    else:
        loss = 1e4 * tf.reduce_sum(tf.abs(y - model_out) * tf.expand_dims(x_w, axis=-1)) / \
               tf.reduce_sum(x_w)

    optimizer = tf.train.AdamOptimizer(learning_rate)
    grad_update = optimizer.minimize(loss)
    if args.arch == 'cnn':
        saliency = tf.gradients(-loss, x)
    else:
        used_model_out = model_out * tf.expand_dims(x_w, axis=-1)
        saliency = tf.gradients(used_model_out, x)
        if args.rnn_type == 'static':
            rnn_states_grad = tf.gradients(used_model_out,
                                           [s.c for s in rnn_states])
    saver = tf.train.Saver()
    init = tf.global_variables_initializer()
    #merged_summary = tf.summary.merge_all()
    #merged_summary = tf.contrib.summary.all_summary_ops()

    # session
    sess = tf.Session(config=tf.ConfigProto(log_device_placement=False))
    if args.debug:
        sess = tf_debug.LocalCLIDebugWrapperSession(sess)
    #if args.tf_summary:
    #    tf.contrib.summary.initialize(graph=sess.graph, session=sess)
    #    train_writer = tf.summary.FileWriter(args.tf_summary_path, sess.graph)
    # train_writer.add_graph(sess.graph)

    # load model or init model
    if type(args.load_model_path) is str:
        logging.info('load model from "{}"'.format(args.load_model_path))
        saver.restore(sess, args.load_model_path)
    else:
        sess.run(init)

    # train model
    epochs = args.epoch
    for i in range(epochs):
        if args.data == 'gau':
            batch = next_batch(args.data, batch_size, h, w, anisotropy)
        elif args.data == 'ir':
            batch = next_batch(args.data,
                               batch_size,
                               h,
                               w,
                               mean_match_query_term=mean_match_query_term,
                               mean_match_doc_term=mean_match_doc_term,
                               dist=distribution)
        st = time()
        batch_x = np.expand_dims(batch[0], axis=3)
        batch_y = np.expand_dims(batch[1], axis=3)
        batch_x_w = batch[2]

        #if args.debug:
        #    print(batch[0][0])
        #    print(batch[1][0])
        #    print(batch[2][0])
        #    input()

        if args.arch == 'lstm' and i == 0:
            print(
                'Shuffling the batch in the height dimension for the standard LSTM.'
                'Its like having h LSTM on the width axis.')
            perms = np.random.permutation(list(range(w)))
            batch_x = batch_x[:, perms, :, :]
            batch_y = batch_y[:, perms, :, :]
            pass

        loss_val, _ = sess.run([loss, grad_update],
                               feed_dict={
                                   x: batch_x,
                                   y: batch_y,
                                   x_w: batch_x_w
                               })
        # console output
        if i % 50 == 0:
            print('epochs = {0} | loss = {1:.3f} | time {2:.3f}'.format(
                str(i).zfill(3), loss_val,
                time() - st))
            #print([v[0] for v in get_variables(sess)])
            #input()
        # save model
        if args.save_model_path and args.save_model_epoch > 0 and i > 0 and \
                (i % args.save_model_epoch == 0 or i == epochs - 1):
            logging.info('save model to "{}" at epochs {}'.format(
                args.save_model_path, i))
            saver.save(sess, args.save_model_path)
        # visualize model
        if args.visualize and i % args.visualize == 0:
            cnn_vis = CNNVis()
            if visualization == 'kernel' and args.arch == 'cnn':
                conv_kernels, = sess.run([tf.get_collection('conv_kernel')])
                kmax = np.max([np.max(k) for k in conv_kernels])
                kmin = np.min([np.min(k) for k in conv_kernels])
                print('kernal max: {}, min: {}'.format(kmax, kmin))
                kmax = max(abs(kmax), abs(kmin)) or 1
                kmin = -kmax
                cnn_vis.set_max_min(kmax, kmin)
                for i, c in enumerate(tf.get_collection('conv_kernel')):
                    cnn_vis.plot_conv_kernel(conv_kernels[i], c.name)
                    input('press to continue')
            elif visualization == 'saliency':
                saliency_map, = \
                    sess.run(saliency, feed_dict={x: batch_x, y: batch_y, x_w: batch_x_w})
                if args.arch == 'mdlstm':
                    # erase the gradiant at the top-left corner when the corresponding input is zero
                    saliency_mask = np.any(
                        np.abs(batch_x[:, 0, 0, :]) > UNIFORM_NOISE,
                        axis=1,
                        keepdims=True).astype(np.float32)
                    saliency_map[:, 0,
                                 0, :] = saliency_map[:, 0,
                                                      0, :] * saliency_mask
                cnn_vis.plot_saliency_map(batch_x, saliency_map)
                if args.rnn_type == 'static':
                    rnn_states_val = sess.run([s.h for s in rnn_states],
                                              feed_dict={
                                                  x: batch_x,
                                                  y: batch_y,
                                                  x_w: batch_x_w
                                              })
                    rnn_states_grad_val = \
                        sess.run(rnn_states_grad, feed_dict={x: batch_x, y: batch_y, x_w: batch_x_w})
                    rnn_vis = RNNVis()
                    rnn_vis.plot_hidden_grad(
                        np.transpose(np.stack(rnn_states_val), [1, 0, 2]),
                        np.transpose(np.stack(rnn_states_grad_val), [1, 0, 2]),
                        sequence=np.reshape(batch_x, [batch_size, h, w]),
                        shape=[1, h])
        # summarize model
        #if args.tf_summary and i % args.tf_summary == 0:
        #    logging.info('summarize model to "{}" at epochs {}'.format(args.tf_summary_path, i))
        #    summary = sess.run([merged_summary], feed_dict={x: batch_x, y: batch_y, x_w: batch_x_w})
        #    train_writer.add_summary(summary, i)
        # eval model
        if args.eval and i % args.eval == 0:
            act = input('press "c" to continue')
            while act != 'c':
                batch = next_batch(args.data,
                                   1,
                                   h,
                                   w,
                                   mean_match_query_term=mean_match_query_term,
                                   mean_match_doc_term=mean_match_doc_term,
                                   dist=distribution)
                model_out_val, loss_val = sess.run(
                    [model_out, loss],
                    feed_dict={
                        x: np.expand_dims(batch[0], axis=3),
                        y: np.expand_dims(batch[1], axis=3),
                        x_w: batch[2]
                    })
                print('matrix:')
                with printoptions(precision=3, suppress=True):
                    eval_matrix = np.rint(np.abs(batch[0][0] * w)).astype(int)
                    print(eval_matrix)
                    print('TF: {}'.format(np.sum(eval_matrix)))
                if args.arch == 'cnn':
                    print('target: {0:.3f}, output: {1:.3f}'.format(
                        batch[1][0, h - 1, w - 1], model_out_val[0, 0]))
                else:
                    print('target: {0:.3f}, output: {1:.3f}'.format(
                        batch[1][0, h - 1, w - 1], model_out_val[0, h - 1,
                                                                 w - 1, 0]))
                print('loss: {0:.3f}'.format(loss_val))
                act = input('press "c" to continue')
Example #4
0
File: run.py Project: wichersn/rlsp
def experiment_wrapper(env_name='vases',
                       problem_spec='default',
                       inference_algorithm='rlsp',
                       combination_algorithm='additive',
                       prior='gaussian',
                       horizon=20,
                       evaluation_horizon=0,
                       temperature=1,
                       learning_rate=.1,
                       inferred_weight=1,
                       epochs=200,
                       uniform_prior=False,
                       measures=['final_reward'],
                       n_samples=10000,
                       mcmc_burn_in=1000,
                       step_size=.01,
                       seed=0,
                       std=0.5,
                       print_level=1,
                       soft_forward_rl=False,
                       reward_constant=1.0):
    # Check the parameters so that we fail fast
    assert inference_algorithm in [
        'rlsp', 'sampling', 'deviation', 'reachability', 'spec'
    ]
    assert combination_algorithm in ['additive', 'bayesian']
    assert prior in ['gaussian', 'laplace', 'uniform']
    assert all(
        (measure in ['true_reward', 'final_reward'] for measure in measures))

    if evaluation_horizon == 0:
        evaluation_horizon = horizon

    if combination_algorithm == 'bayesian':
        assert inference_algorithm in ['rlsp', 'sampling']

    np.random.seed(seed)
    env, s_current, r_task, r_true = get_problem_parameters(
        env_name, problem_spec)

    if print_level >= 1:
        print('Initial state:')
        env.print_state(env.init_state)
        print()

    p_0 = env.get_initial_state_distribution(
        known_initial_state=not uniform_prior)

    deviation = inference_algorithm == "deviation"
    reachability = inference_algorithm == "reachability"
    reward_center = r_task if combination_algorithm == "bayesian" else np.zeros(
        env.num_features)
    r_prior = get_r_prior(prior, reward_center, std)

    # Infer reward by observing the world state
    if inference_algorithm == "rlsp":
        r_inferred = rlsp(env, s_current, p_0, horizon, temperature, epochs,
                          learning_rate, r_prior)
    elif inference_algorithm == "sampling":
        r_samples = sample_from_posterior(env,
                                          s_current,
                                          p_0,
                                          horizon,
                                          temperature,
                                          n_samples,
                                          step_size,
                                          r_prior,
                                          gamma=1,
                                          print_level=print_level)
        r_inferred = np.mean(r_samples[mcmc_burn_in::], axis=0)
    elif inference_algorithm in ["deviation", "reachability", "spec"]:
        r_inferred = None
    else:
        raise ValueError(
            'Unknown inference algorithm: {}'.format(inference_algorithm))

    if print_level >= 1 and r_inferred is not None:
        with printoptions(precision=4, suppress=True):
            print()
            print('Inferred reward vector: ', r_inferred)

    # Run forward RL to evaluate
    def evaluate(forward_rl_temp):
        if combination_algorithm == "additive":
            r_final = r_task
            if r_inferred is not None:
                r_final = r_task + inferred_weight * r_inferred
            true_reward_obtained = forward_rl(
                env,
                r_final,
                r_true,
                temp=forward_rl_temp,
                h=evaluation_horizon,
                current_s_num=s_current,
                weight=inferred_weight,
                penalize_deviation=deviation,
                relative_reachability=reachability,
                print_level=print_level)
        elif combination_algorithm == "bayesian":
            assert r_inferred is not None
            assert (not deviation) and (not reachability)
            r_final = r_inferred
            true_reward_obtained = forward_rl(env,
                                              r_final,
                                              r_true,
                                              temp=forward_rl_temp,
                                              h=evaluation_horizon,
                                              current_s_num=s_current,
                                              penalize_deviation=False,
                                              relative_reachability=False,
                                              print_level=print_level)
        else:
            raise ValueError('Unknown combination algorithm: {}'.format(
                combination_algorithm))

        best_possible_reward = forward_rl(env,
                                          r_true,
                                          r_true,
                                          temp=forward_rl_temp,
                                          h=evaluation_horizon,
                                          current_s_num=s_current,
                                          print_level=0)

        # Add the reward constant in
        true_reward_obtained += reward_constant * evaluation_horizon
        best_possible_reward += reward_constant * evaluation_horizon

        def get_measure(measure):
            if measure == 'final_reward':
                return r_final
            elif measure == 'true_reward':
                return true_reward_obtained * 1.0 / best_possible_reward
            else:
                raise ValueError('Unknown measure {}'.format(measure))

        return [get_measure(measure) for measure in measures]

    if soft_forward_rl:
        return [evaluate(temp) for temp in [0, 0.1, 0.5, 1, 5, 10]]
    else:
        return [evaluate(0.0)]
Example #5
0
 def __str__(self):
     with utils.printoptions(suppress=True):
         return str(self.M)
Example #6
0
def main():
    parser = build_parser()
    options = parser.parse_args()
    utils.printoptions(options)

    if not os.path.isfile(options.network):
        parser.error(
            "Network %s does not exist. (Did you forget to download it?)" %
            options.network)

    content_image = utils.imread(options.content)
    style_images = [utils.imread(style) for style in options.styles]

    width = options.width
    if width is not None:  # resize content image
        if not options.square_shape:
            new_shape = (int(
                math.floor(
                    float(content_image.shape[0]) / content_image.shape[1] *
                    width)), width)
        else:
            new_shape = (width, width)
        content_image = scipy.misc.imresize(content_image, new_shape)
    target_shape = content_image.shape
    for i in range(len(style_images)):  # resize style image
        if options.style_width is not None:
            style_images[i] = scipy.misc.imresize(
                style_images[i],
                (int(1.0 * style_images[i].shape[0] * options.style_width[i] /
                     style_images[i].shape[1]), int(options.style_width[i])))

    style_blend_weights = options.style_blend_weights
    if style_blend_weights is None:
        # default is equal weights
        style_blend_weights = [1.0 / len(style_images) for _ in style_images]
    else:
        total_blend_weight = sum(style_blend_weights)
        style_blend_weights = [
            weight / total_blend_weight for weight in style_blend_weights
        ]

    initial = options.initial
    if initial is not None:
        initial = scipy.misc.imresize(utils.imread(initial),
                                      content_image.shape[:2])
        # Initial guess is specified, but not noiseblend - no noise should be blended
        if options.initial_noiseblend is None:
            options.initial_noiseblend = 0.0
    else:
        # Neither inital, nor noiseblend is provided, falling back to random generated initial guess
        if options.initial_noiseblend is None:
            options.initial_noiseblend = 1.0
        if options.initial_noiseblend < 1.0:
            initial = content_image

    if options.checkpoint_output and "%s" not in options.checkpoint_output:
        parser.error("To save intermediate images, the checkpoint output "
                     "parameter must contain `%s` (e.g. `foo%s.jpg`)")

    # try saving a dummy image to the output path to make sure that it's writable
    if os.path.isfile(options.output) and not options.overwrite:
        raise IOError(
            "%s already exists, will not replace it without the '--overwrite' flag"
            % options.output)
    try:
        utils.imsave(options.output, np.zeros((500, 500, 3)))
    except:
        raise IOError(
            '%s is not writable or does not have a valid file extension for an image file'
            % options.output)

    for iteration, image, loss_dict in stylize(
            network=options.network,
            initial=initial,
            initial_noiseblend=options.initial_noiseblend,
            content=content_image,
            styles=style_images,
            preserve_colors=options.preserve_colors,
            iterations=options.iterations,
            content_weight=options.content_weight,
            content_weight_blend=options.content_weight_blend,
            style_weight=options.style_weight,
            style_layer_weight_exp=options.style_layer_weight_exp,
            style_blend_weights=style_blend_weights,
            tv_weight=options.tv_weight,
            learning_rate=options.learning_rate,
            beta1=options.beta1,
            beta2=options.beta2,
            epsilon=options.epsilon,
            pooling=options.pooling,
            print_iterations=options.print_iterations,
            checkpoint_iterations=options.checkpoint_iterations):
        output_file = None
        combined_rgb = image
        if iteration is not None:  # iteration when optimize
            if options.checkpoint_output:
                output_file = options.checkpoint_output % iteration
                utils.imsave(output_file, combined_rgb)
        else:  # iteration of the last step
            output_file = options.output
            opt_image = Image.new('RGB', (image.shape[1], image.shape[0]),
                                  (200, 200, 200))
            opt_image = utils.drawdic(
                opt_image,
                OrderedDict(vars(options).items() + loss_dict.items()),
                hight=int((image.shape[0] - 5) /
                          (len(vars(options)) + len(loss_dict))))
            rgb_with_message = np.append(combined_rgb,
                                         np.array(opt_image),
                                         axis=1)
            utils.imsave(output_file, combined_rgb)
            utils.imsave(
                os.path.join(os.path.dirname(output_file),
                             'mesg_' + os.path.basename(output_file)),
                rgb_with_message)