00001
00002 #include "network.h"
00003 #include "parser.h"
00004 #include "blas.h"
00005 #include "utils.h"
00006
00007 #ifdef OPENCV
00008 #include "opencv2/highgui/highgui_c.h"
00009 #endif
00010
00011
00012
00013 float abs_mean(float *x, int n)
00014 {
00015 int i;
00016 float sum = 0;
00017 for (i = 0; i < n; ++i){
00018 sum += fabs(x[i]);
00019 }
00020 return sum/n;
00021 }
00022
00023 void calculate_loss(float *output, float *delta, int n, float thresh)
00024 {
00025 int i;
00026 float mean = mean_array(output, n);
00027 float var = variance_array(output, n);
00028 for(i = 0; i < n; ++i){
00029 if(delta[i] > mean + thresh*sqrt(var)) delta[i] = output[i];
00030 else delta[i] = 0;
00031 }
00032 }
00033
00034 void optimize_picture(network *net, image orig, int max_layer, float scale, float rate, float thresh, int norm)
00035 {
00036
00037
00038 net->n = max_layer + 1;
00039
00040 int dx = rand()%16 - 8;
00041 int dy = rand()%16 - 8;
00042 int flip = rand()%2;
00043
00044 image crop = crop_image(orig, dx, dy, orig.w, orig.h);
00045 image im = resize_image(crop, (int)(orig.w * scale), (int)(orig.h * scale));
00046 if(flip) flip_image(im);
00047
00048 resize_network(net, im.w, im.h);
00049 layer last = net->layers[net->n-1];
00050
00051
00052 image delta = make_image(im.w, im.h, im.c);
00053
00054 network_state state = {0};
00055
00056 #ifdef GPU
00057 state.input = cuda_make_array(im.data, im.w*im.h*im.c);
00058 state.delta = cuda_make_array(im.data, im.w*im.h*im.c);
00059
00060 forward_network_gpu(*net, state);
00061 copy_ongpu(last.outputs, last.output_gpu, 1, last.delta_gpu, 1);
00062
00063 cuda_pull_array(last.delta_gpu, last.delta, last.outputs);
00064 calculate_loss(last.delta, last.delta, last.outputs, thresh);
00065 cuda_push_array(last.delta_gpu, last.delta, last.outputs);
00066
00067 backward_network_gpu(*net, state);
00068
00069 cuda_pull_array(state.delta, delta.data, im.w*im.h*im.c);
00070 cuda_free(state.input);
00071 cuda_free(state.delta);
00072 #else
00073 state.input = im.data;
00074 state.delta = delta.data;
00075 forward_network(*net, state);
00076 copy_cpu(last.outputs, last.output, 1, last.delta, 1);
00077 calculate_loss(last.output, last.delta, last.outputs, thresh);
00078 backward_network(*net, state);
00079 #endif
00080
00081 if(flip) flip_image(delta);
00082
00083 image resized = resize_image(delta, orig.w, orig.h);
00084 image out = crop_image(resized, -dx, -dy, orig.w, orig.h);
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 if(norm) normalize_array(out.data, out.w*out.h*out.c);
00095 axpy_cpu(orig.w*orig.h*orig.c, rate, out.data, 1, orig.data, 1);
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 constrain_image(orig);
00108
00109 free_image(crop);
00110 free_image(im);
00111 free_image(delta);
00112 free_image(resized);
00113 free_image(out);
00114
00115 }
00116
00117 void smooth(image recon, image update, float lambda, int num)
00118 {
00119 int i, j, k;
00120 int ii, jj;
00121 for(k = 0; k < recon.c; ++k){
00122 for(j = 0; j < recon.h; ++j){
00123 for(i = 0; i < recon.w; ++i){
00124 int out_index = i + recon.w*(j + recon.h*k);
00125 for(jj = j-num; jj <= j + num && jj < recon.h; ++jj){
00126 if (jj < 0) continue;
00127 for(ii = i-num; ii <= i + num && ii < recon.w; ++ii){
00128 if (ii < 0) continue;
00129 int in_index = ii + recon.w*(jj + recon.h*k);
00130 update.data[out_index] += lambda * (recon.data[in_index] - recon.data[out_index]);
00131 }
00132 }
00133 }
00134 }
00135 }
00136 }
00137
00138 void reconstruct_picture(network net, float *features, image recon, image update, float rate, float momentum, float lambda, int smooth_size, int iters)
00139 {
00140 int iter = 0;
00141 for (iter = 0; iter < iters; ++iter) {
00142 image delta = make_image(recon.w, recon.h, recon.c);
00143
00144 network_state state = {0};
00145 #ifdef GPU
00146 state.input = cuda_make_array(recon.data, recon.w*recon.h*recon.c);
00147 state.delta = cuda_make_array(delta.data, delta.w*delta.h*delta.c);
00148 state.truth = cuda_make_array(features, get_network_output_size(net));
00149
00150 forward_network_gpu(net, state);
00151 backward_network_gpu(net, state);
00152
00153 cuda_pull_array(state.delta, delta.data, delta.w*delta.h*delta.c);
00154
00155 cuda_free(state.input);
00156 cuda_free(state.delta);
00157 cuda_free(state.truth);
00158 #else
00159 state.input = recon.data;
00160 state.delta = delta.data;
00161 state.truth = features;
00162
00163 forward_network(net, state);
00164 backward_network(net, state);
00165 #endif
00166
00167 axpy_cpu(recon.w*recon.h*recon.c, 1, delta.data, 1, update.data, 1);
00168 smooth(recon, update, lambda, smooth_size);
00169
00170 axpy_cpu(recon.w*recon.h*recon.c, rate, update.data, 1, recon.data, 1);
00171 scal_cpu(recon.w*recon.h*recon.c, momentum, update.data, 1);
00172
00173
00174
00175
00176 constrain_image(recon);
00177 free_image(delta);
00178 }
00179 }
00180
00181
00182 void run_nightmare(int argc, char **argv)
00183 {
00184 srand(0);
00185 if(argc < 4){
00186 fprintf(stderr, "usage: %s %s [cfg] [weights] [image] [layer] [options! (optional)]\n", argv[0], argv[1]);
00187 return;
00188 }
00189
00190 char *cfg = argv[2];
00191 char *weights = argv[3];
00192 char *input = argv[4];
00193 int max_layer = atoi(argv[5]);
00194
00195 int range = find_int_arg(argc, argv, "-range", 1);
00196 int norm = find_int_arg(argc, argv, "-norm", 1);
00197 int rounds = find_int_arg(argc, argv, "-rounds", 1);
00198 int iters = find_int_arg(argc, argv, "-iters", 10);
00199 int octaves = find_int_arg(argc, argv, "-octaves", 4);
00200 float zoom = find_float_arg(argc, argv, "-zoom", 1.);
00201 float rate = find_float_arg(argc, argv, "-rate", .04);
00202 float thresh = find_float_arg(argc, argv, "-thresh", 1.);
00203 float rotate = find_float_arg(argc, argv, "-rotate", 0);
00204 float momentum = find_float_arg(argc, argv, "-momentum", .9);
00205 float lambda = find_float_arg(argc, argv, "-lambda", .01);
00206 char *prefix = find_char_arg(argc, argv, "-prefix", 0);
00207 int reconstruct = find_arg(argc, argv, "-reconstruct");
00208 int smooth_size = find_int_arg(argc, argv, "-smooth", 1);
00209
00210 network net = parse_network_cfg(cfg);
00211 load_weights(&net, weights);
00212 char *cfgbase = basecfg(cfg);
00213 char *imbase = basecfg(input);
00214
00215 set_batch_network(&net, 1);
00216 image im = load_image_color(input, 0, 0);
00217 if(0){
00218 float scale = 1;
00219 if(im.w > 512 || im.h > 512){
00220 if(im.w > im.h) scale = 512.0/im.w;
00221 else scale = 512.0/im.h;
00222 }
00223 image resized = resize_image(im, scale*im.w, scale*im.h);
00224 free_image(im);
00225 im = resized;
00226 }
00227
00228 float *features = 0;
00229 image update;
00230 if (reconstruct){
00231 resize_network(&net, im.w, im.h);
00232
00233 int zz = 0;
00234 network_predict(net, im.data);
00235 image out_im = get_network_image(net);
00236 image crop = crop_image(out_im, zz, zz, out_im.w-2*zz, out_im.h-2*zz);
00237
00238 image f_im = resize_image(crop, out_im.w, out_im.h);
00239 free_image(crop);
00240 printf("%d features\n", out_im.w*out_im.h*out_im.c);
00241
00242
00243 im = resize_image(im, im.w, im.h);
00244 f_im = resize_image(f_im, f_im.w, f_im.h);
00245 features = f_im.data;
00246
00247 int i;
00248 for(i = 0; i < 14*14*512; ++i){
00249 features[i] += rand_uniform(-.19, .19);
00250 }
00251
00252 free_image(im);
00253 im = make_random_image(im.w, im.h, im.c);
00254 update = make_image(im.w, im.h, im.c);
00255
00256 }
00257
00258 int e;
00259 int n;
00260 for(e = 0; e < rounds; ++e){
00261 fprintf(stderr, "Iteration: ");
00262 fflush(stderr);
00263 for(n = 0; n < iters; ++n){
00264 fprintf(stderr, "%d, ", n);
00265 fflush(stderr);
00266 if(reconstruct){
00267 reconstruct_picture(net, features, im, update, rate, momentum, lambda, smooth_size, 1);
00268
00269 show_image(im, "reconstruction");
00270 #ifdef OPENCV
00271 cvWaitKey(10);
00272 #endif
00273 }else{
00274 int layer = max_layer + rand()%range - range/2;
00275 int octave = rand()%octaves;
00276 optimize_picture(&net, im, layer, 1/pow(1.33333333, octave), rate, thresh, norm);
00277 }
00278 }
00279 fprintf(stderr, "done\n");
00280 if(0){
00281 image g = grayscale_image(im);
00282 free_image(im);
00283 im = g;
00284 }
00285 char buff[256];
00286 if (prefix){
00287 sprintf(buff, "%s/%s_%s_%d_%06d",prefix, imbase, cfgbase, max_layer, e);
00288 }else{
00289 sprintf(buff, "%s_%s_%d_%06d",imbase, cfgbase, max_layer, e);
00290 }
00291 printf("%d %s\n", e, buff);
00292 save_image(im, buff);
00293
00294
00295
00296 if(rotate){
00297 image rot = rotate_image(im, rotate);
00298 free_image(im);
00299 im = rot;
00300 }
00301 image crop = crop_image(im, im.w * (1. - zoom)/2., im.h * (1.-zoom)/2., im.w*zoom, im.h*zoom);
00302 image resized = resize_image(crop, im.w, im.h);
00303 free_image(im);
00304 free_image(crop);
00305 im = resized;
00306 }
00307 }
00308