{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Demo Regeneration with Demo Model Jurassaic NCA","metadata":{}},{"cell_type":"markdown","source":"This notebook will demonstrate regeneration figures using the pretrained model in [notebook Demo Model Jurassic NCA](https://www.kaggle.com/code/something4kag/demo-model-jurassic-nca/notebook)  Add this notebook in Add data.\n\nA new NCA Emoji Challenge script with moviepy and VideoWriter class included is used in this notebook\n\nYou need to add the [wheels for moviepy dataset](https://www.kaggle.com/datasets/something4kag/whls-for-moviepy) and put in the sys path as shown below.","metadata":{}},{"cell_type":"code","source":"# notebook using NCA emoji challenge script with moviepy ","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ref\n# https://distill.pub/2020/growing-ca/\n\n#https://colab.research.google.com/github/google-research/self-organising-systems/blob/master/notebooks/growing_ca.ipynb\n\n# Licensed under the Apache License, Version 2.0   https://www.apache.org/licenses/LICENSE-2.0","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# to get script with moviepy for NCA Emoji Challenge - \n# File -> Add utility script\n#   add to sys.path the ../usr/lib/<script name folder>/<script name.py>\n#   then can do import","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\n\nSPATH = '../usr/lib/nca_emoji_challenge_script_with_moviepy/nca_emoji_challenge_script_with_moviepy.py'  \nsys.path.insert(1, SPATH)\nSPATH = '../input/whls-for-moviepy'  # add this dataset to the sys path for the script to work on import\nsys.path.insert(1, SPATH)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T09:54:57.091487Z","iopub.execute_input":"2022-07-31T09:54:57.091991Z","iopub.status.idle":"2022-07-31T09:54:57.124664Z","shell.execute_reply.started":"2022-07-31T09:54:57.091892Z","shell.execute_reply":"2022-07-31T09:54:57.123647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from nca_emoji_challenge_script_with_moviepy import *","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-07-31T09:55:16.431557Z","iopub.execute_input":"2022-07-31T09:55:16.432346Z","iopub.status.idle":"2022-07-31T09:55:49.953230Z","shell.execute_reply.started":"2022-07-31T09:55:16.432309Z","shell.execute_reply":"2022-07-31T09:55:49.951783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CAModel().dmodel.summary() # model from script should appear ","metadata":{"execution":{"iopub.status.busy":"2022-07-31T09:58:17.943749Z","iopub.execute_input":"2022-07-31T09:58:17.944129Z","iopub.status.idle":"2022-07-31T09:58:19.079508Z","shell.execute_reply.started":"2022-07-31T09:58:17.944098Z","shell.execute_reply":"2022-07-31T09:58:19.078162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Get the saved model weights for the Demo Model Jurassic NCA notebook.  \nIt has directory kaggle/working (sorry typo forgot the / before kaggle!)","metadata":{}},{"cell_type":"code","source":"nca_model = 'jurassic_nca'  # name used in the final save_weights in the training notebook\nmodel_wts = f'../input/demo-model-jurassic-nca/kaggle/working/{nca_model}' \nmodel_wts","metadata":{"execution":{"iopub.status.busy":"2022-07-31T10:38:16.611011Z","iopub.execute_input":"2022-07-31T10:38:16.611487Z","iopub.status.idle":"2022-07-31T10:38:16.620064Z","shell.execute_reply.started":"2022-07-31T10:38:16.611450Z","shell.execute_reply":"2022-07-31T10:38:16.618893Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Alternatively you can also get the model weights from the nca_trainlog.zip \n","metadata":{}},{"cell_type":"code","source":"if os.path.exists(\"/tmp/nca_model\"):\n    # remove previous \n    shutil.rmtree(\"/tmp/nca_model\")\n    \nos.mkdir('/tmp/nca_model') \nshutil.unpack_archive('../input/demo-model-jurassic-nca/nca_trainlog.zip', '/tmp/nca_model')\nprint('unpack archive complete!') \n# TRAIN_ITERS used was 7000 the default in the script\ni = 7000 # the last of TRAIN_ITERS\nmodel_wts_zip = '/tmp/nca_model/%04d'%i \nmodel_wts_zip\nprint(model_wts_zip)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T10:43:18.420220Z","iopub.execute_input":"2022-07-31T10:43:18.420632Z","iopub.status.idle":"2022-07-31T10:43:18.669086Z","shell.execute_reply.started":"2022-07-31T10:43:18.420599Z","shell.execute_reply":"2022-07-31T10:43:18.667778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ca = CAModel()\nca.load_weights(model_wts)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T09:58:43.381320Z","iopub.execute_input":"2022-07-31T09:58:43.382357Z","iopub.status.idle":"2022-07-31T09:58:43.607706Z","shell.execute_reply.started":"2022-07-31T09:58:43.382313Z","shell.execute_reply":"2022-07-31T09:58:43.606437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Using the NCA model for the loaded weights, regenerate the image in a video like in the getting started notebook.\n","metadata":{}},{"cell_type":"code","source":"models = [ca]\nout_fn = 'train_steps_damage_%d.mp4'%DAMAGE_N\nx = np.zeros([len(models), 72, 72, CHANNEL_N], np.float32)\nx[..., 36, 36, 3:] = 1.0 \nwith VideoWriter(out_fn) as vid:\n  for i in tqdm.trange(500): \n    vis = np.hstack(to_rgb(x))\n    vid.add(zoom(vis, 2))\n    for ca, xk in zip(models, x):\n      xk[:] = ca(xk[None,...])[0]\nmvp.ipython_display(out_fn)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T09:59:03.111522Z","iopub.execute_input":"2022-07-31T09:59:03.111996Z","iopub.status.idle":"2022-07-31T09:59:06.811574Z","shell.execute_reply.started":"2022-07-31T09:59:03.111959Z","shell.execute_reply":"2022-07-31T09:59:06.810211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Below is a regeneration then adding damage - removing bottom, top, right, left, center cutout and then regenerate.\n\nThis is similar to the competition logo which is just a frame from the clip showing the damage. ","metadata":{}},{"cell_type":"code","source":"#@title Regeneration (trained with damage)\n# this vers fr/orig does 5 copies adds damage in the video then regens\nmodelsr = [ca] \nwith VideoWriter('regen2.mp4') as vid:\n  x = np.zeros([len(modelsr), 5, 56, 56, CHANNEL_N], np.float32)\n  cx, cy = 28, 28\n  x[:, :, cy, cx, 3:] = 1.0\n  for i in tqdm.trange(1000):  # 2000\n    if i == 200:\n      x[:, 0, cy:] = x[:, 1, :cy] = 0\n      x[:, 2, :, cx:] = x[:, 3, :, :cx] = 0\n      x[:, 4, cy-8:cy+8, cx-8:cx+8] = 0\n    vis = to_rgb(x)\n    vis = np.vstack([np.hstack(row) for row in vis])\n    vis = zoom(vis, 2)\n    if (i < 400 and i%2==0) or i%8 == 0:\n      vid.add(vis)\n    if i == 200:\n      for _ in range(29):\n        vid.add(vis)\n    for ca, row in zip(modelsr, x):\n      row[:] = ca(row)\n\nmvp.ipython_display('regen2.mp4')","metadata":{"execution":{"iopub.status.busy":"2022-07-31T10:00:38.300127Z","iopub.execute_input":"2022-07-31T10:00:38.301577Z","iopub.status.idle":"2022-07-31T10:00:50.808021Z","shell.execute_reply.started":"2022-07-31T10:00:38.301520Z","shell.execute_reply":"2022-07-31T10:00:50.805339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Below is a regeneration then adding a wave of damage - then regenerate.\n\nThis is similar to the competition overview which is just a gif from the clip. ","metadata":{}},{"cell_type":"code","source":"modelst1 = [ca,ca,ca,ca,ca] #   one row  one model \nsz1 = 72\nsz1h =36\nctrs1 = [30,30,30,30,30] # option to use different centres for different models if desired for look of video \nwith VideoWriter('teaser1.mp4') as vid:\n  x = np.zeros([len(modelst1), sz1, sz1, CHANNEL_N], np.float32)\n  # grow\n  for i in tqdm.trange(100): # 200  or  100  \n    k = i//20  \n    ctr = ctrs1[k]\n    if i%20==0 and k<len(modelst1):      \n      x[k, ctr, ctr, 3:] = 1.0  # 36 36 \n    vid.add(zoom(tile2d(to_rgb(x), 5), 2))  # 2x zoom\n    for ca, xk in zip(modelst1, x):\n      xk[:] = ca(xk[None,...])[0]\n  # damage\n  mask = PIL.Image.new('L', (sz1*5, sz1*1))\n  draw = PIL.ImageDraw.Draw(mask)\n  for i in tqdm.trange(400): # 400 or 500\n    cx, r = i*3-20, 6\n    y1, y2 = sz1h+np.sin(i/5+np.pi)*8, sz1h+sz1+np.sin(i/5)*8\n    draw.rectangle((0, 0, sz1*5, sz1*1), fill=0)  \n    draw.ellipse((cx-r, y1-r, cx+r, y1+r), fill=255)\n    \n    x *= 1.0-(np.float32(mask).reshape(1, sz1, 5, sz1) \n        .transpose([0, 2, 1, 3]).reshape(5, sz1,sz1, 1))/255.0  \n    if i<250 or i%2 == 0:  # 200\n      vid.add(zoom(tile2d(to_rgb(x), 5),2))  \n    for ca, xk in zip(modelst1, x):\n      xk[:] = ca(xk[None,...])[0]\n  # fade out\n  last = zoom(tile2d(to_rgb(x), 5), 2)  \n  for t in np.linspace(0, 1, 30):\n    vid.add(last*(1.0-t)+t)\n\nmvp.ipython_display('teaser1.mp4', loop=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T10:25:00.238448Z","iopub.execute_input":"2022-07-31T10:25:00.239349Z","iopub.status.idle":"2022-07-31T10:25:15.213506Z","shell.execute_reply.started":"2022-07-31T10:25:00.239309Z","shell.execute_reply":"2022-07-31T10:25:15.212267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"You can experiment more with models and regeneration with the Demos or your own.","metadata":{}}]}