Skip to content

Instantly share code, notes, and snippets.

@xiangze
Last active October 27, 2018 06:49
Show Gist options
  • Save xiangze/4aff6ded56bf058318d8bd19c3a819d4 to your computer and use it in GitHub Desktop.
Save xiangze/4aff6ded56bf058318d8bd19c3a819d4 to your computer and use it in GitHub Desktop.
VEA in Edward
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 変分オートエンコーダ(VAE)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Variable AutoEncoder(VAE)は\n",
"edwardでは単一のクラスとして提供してはおらずencoder部分、decoder部分をそれぞれ定義することで記述することができる。\n",
"\n",
"- [exampleのコード](https://github.com/blei-lab/edward/blob/master/examples/vae.py)\n",
"- http://edwardlib.org/tutorials/decoder\n",
"- http://edwardlib.org/tutorials/inference-network"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"from __future__ import absolute_import\n",
"from __future__ import division\n",
"from __future__ import print_function\n",
"\n",
"import edward as ed\n",
"import numpy as np\n",
"import os\n",
"import tensorflow as tf\n",
"\n",
"from edward.models import Bernoulli, Normal\n",
"from edward.util import Progbar\n",
"from keras.layers import Dense\n",
"from observations import mnist\n",
"\n",
"ed.set_seed(42)\n",
"#from scipy.misc import imsave\n",
"from PIL import Image"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 実行"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Generatorの定義"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"def generator(array, batch_size):\n",
" \"\"\"Generate batch with respect to array's first axis.\"\"\"\n",
" start = 0 # pointer to where we are in iteration\n",
" while True:\n",
" stop = start + batch_size\n",
" diff = stop - array.shape[0]\n",
" if diff <= 0:\n",
" batch = array[start:stop]\n",
" start += batch_size\n",
" else:\n",
" batch = np.concatenate((array[start:], array[:diff]))\n",
" start = diff\n",
" batch = batch.astype(np.float32) / 255.0 # normalize pixel intensities\n",
" batch = np.random.binomial(1, batch) # 二値化画像\n",
" yield batch"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"訓練用データをミニバッチごとに分割する関数generatorを定義する。\n",
"メモリ節約のためdata x_train,x_test をpython文法のgeneratorとして定義する。"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"data_dir = \"/tmp/data\"\n",
"out_dir = \"/tmp/out\"\n",
"if not os.path.exists(out_dir):\n",
" os.makedirs(out_dir)\n",
"\n",
"M = 100 # batch size during training\n",
"d = 2 # latent dimension"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"MNISTのデータをダウンロードして使う。\n",
"[edwardlibの元のコード](https://github.com/edwardlib/observations/blob/master/observations/mnist.py#L27) だとアカウントの関係でかダウンロードできなかったので以下の改変したコードを用いる。"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [],
"source": [
"from observations.util import maybe_download_and_extract\n",
"\n",
"def mnist(path,url='http://yann.lecun.com/exdb/mnist/'):\n",
"# url = 'https://storage.googleapis.com/cvdf-datasets/mnist/'\n",
" path = os.path.expanduser(path)\n",
" train_images = 'train-images-idx3-ubyte'\n",
" train_labels = 'train-labels-idx1-ubyte'\n",
" test_images = 't10k-images-idx3-ubyte'\n",
" test_labels = 't10k-labels-idx1-ubyte'\n",
"\n",
" if not os.path.exists(os.path.join(path, train_images)):\n",
" maybe_download_and_extract(path, url + train_images + '.gz')\n",
" if not os.path.exists(os.path.join(path, train_labels)):\n",
" maybe_download_and_extract(path, url + train_labels + '.gz')\n",
" if not os.path.exists(os.path.join(path, test_images)):\n",
" maybe_download_and_extract(path, url + test_images + '.gz')\n",
" if not os.path.exists(os.path.join(path, test_labels)):\n",
" maybe_download_and_extract(path, url + test_labels + '.gz')\n",
"\n",
" with open(os.path.join(path, train_images)) as f:\n",
" loaded = np.fromfile(file=f, dtype='uint8')\n",
" x_train = loaded[16:].reshape((60000, 28 * 28)).astype(float)\n",
" with open(os.path.join(path, train_labels)) as f:\n",
" loaded = np.fromfile(file=f, dtype='uint8')\n",
" y_train = loaded[8:].reshape((60000,))\n",
" with open(os.path.join(path, test_images)) as f:\n",
" loaded = np.fromfile(file=f, dtype='uint8')\n",
" x_test = loaded[16:].reshape((10000, 28 * 28)).astype(float)\n",
" with open(os.path.join(path, test_labels)) as f:\n",
" loaded = np.fromfile(file=f, dtype='uint8')\n",
" y_test = loaded[8:].reshape((10000,))\n",
"\n",
" return (x_train, y_train), (x_test, y_test)"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
">> Downloading tmp/data/train-images-idx3-ubyte.gz.part \n",
">> [9.5 MB/9.5 MB] 105% @46.2 KB/s,[0s remaining, 3m 41s elapsed] \n",
"URL http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz downloaded to tmp/data/train-images-idx3-ubyte.gz \n",
">> Downloading tmp/data/train-labels-idx1-ubyte.gz.part \n",
">> [28.2 KB/28.2 KB] 3630% @1.1 MB/s,[0s remaining, 0s elapsed] \n",
"URL http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz downloaded to tmp/data/train-labels-idx1-ubyte.gz \n",
">> Downloading tmp/data/t10k-images-idx3-ubyte.gz.part \n",
">> [1.6 MB/1.6 MB] 127% @42.9 KB/s,[0s remaining, 47s elapsed] \n",
"URL http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz downloaded to tmp/data/t10k-images-idx3-ubyte.gz \n",
">> Downloading tmp/data/t10k-labels-idx1-ubyte.gz.part \n",
">> [4.4 KB/4.4 KB] 23086% @2.4 MB/s,[0s remaining, 0s elapsed] \n",
"URL http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz downloaded to tmp/data/t10k-labels-idx1-ubyte.gz \n"
]
}
],
"source": [
"(x_train, _), (x_test, _) = mnist(data_dir)\n",
"x_train_generator = generator(x_train, M)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"ミニバッチサイズMに対応するモデルの部分グラフを定義する。\n",
"\n",
"全結合1層ニューラルネットの関数としてKerasのDenseを使っている所に注目"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## decoder"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"z = Normal(loc=tf.zeros([M, d]), scale=tf.ones([M, d]))\n",
"hidden = Dense(256, activation='relu')(z.value())\n",
"x = Bernoulli(logits=Dense(28 * 28)(hidden))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"対応するグラフを図示すると以下のようになる。\n",
"![a](simpleVAE.png)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## decoder"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"decoderの定義モデルとは変数の依存関係の流れが逆になっている(x_ph-(NN)->hidden_z->qz)\n",
"\n",
"隠れた変数qzの推測の過程で勾配を用いるので qzのパラメータloc,scaleとして隠れた変数を使ったモデルにしている。"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [],
"source": [
"x_ph = tf.placeholder(tf.int32, [M, 28 * 28])\n",
"hidden_z = Dense(256, activation='relu')(tf.cast(x_ph, tf.float32))\n",
"qz = Normal(loc=Dense(d)(hidden_z),\n",
" scale=Dense(d, activation='softplus')(hidden_z))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 推測"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"推測処理"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [],
"source": [
"inference = ed.KLqp({z: qz}, data={x: x_ph})\n",
"optimizer = tf.train.RMSPropOptimizer(0.01, epsilon=1.0)\n",
"inference.initialize(optimizer=optimizer)"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [],
"source": [
"tf.global_variables_initializer().run()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## lossの計算と出力"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 1\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 8s\n",
"-log p(x) <= 159.379\n",
"Epoch: 2\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 8s\n",
"-log p(x) <= 159.805\n",
"Epoch: 3\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 9s\n",
"-log p(x) <= 160.656\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 12s\n",
"-log p(x) <= 186.619\n",
"Epoch: 92\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"600/600 [100%] ██████████████████████████████ Elapsed: 9s\n",
"-log p(x) <= 173.224\n",
"Epoch: 93\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 10s\n",
"-log p(x) <= 166.082\n",
"Epoch: 94\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 11s\n",
"-log p(x) <= 164.938\n",
"Epoch: 95\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 10s\n",
"-log p(x) <= 163.156\n",
"Epoch: 96\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 11s\n",
"-log p(x) <= 163.522\n",
"Epoch: 97\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 12s\n",
"-log p(x) <= 168.908\n",
"Epoch: 98\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 10s\n",
"-log p(x) <= 166.630\n",
"Epoch: 99\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 11s\n",
"-log p(x) <= 163.932\n",
"Epoch: 100\n",
"600/600 [100%] ██████████████████████████████ Elapsed: 12s\n",
"-log p(x) <= 169.667\n"
]
}
],
"source": [
"n_epoch = 100\n",
"n_iter_per_epoch = x_train.shape[0] // M\n",
"\n",
"for epoch in range(1, n_epoch + 1):\n",
" print(\"Epoch: {0}\".format(epoch))\n",
" avg_loss = 0.0\n",
"\n",
" pbar = Progbar(n_iter_per_epoch)\n",
" for t in range(1, n_iter_per_epoch + 1):\n",
" pbar.update(t)\n",
" x_batch = next(x_train_generator)\n",
" info_dict = inference.update(feed_dict={x_ph: x_batch})\n",
" avg_loss += info_dict['loss']\n",
"\n",
" #1つの画像に対する平均周辺化尤度の下限を表示\n",
" avg_loss = avg_loss / n_iter_per_epoch\n",
" avg_loss = avg_loss / M\n",
" print(\"-log p(x) <= {:0.3f}\".format(avg_loss))\n",
"\n",
" # 事前予測チェック\n",
" images = x.eval()\n",
" for m in range(M):\n",
" im= Image.fromarray(images[m].reshape(28, 28))\n",
" im.save(os.path.join(out_dir, '_%d.png') % m)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 生成画像を出力"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAP8AAAD8CAYAAAC4nHJkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4wLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvpW3flQAAC/dJREFUeJzt3W+oJXUdx/H3N1tX2grc/iybLVkh\ngQitcVkDJQr7YxKsPZH2gWwgbQ8SCnqQ2IN8KFGJD0K45tIaZQUl7gOpbAkkiMWrmH+y0mSj3dZd\nYwUtaF3t24M7Gze9957jmZkz59zv+wWXO2fO3Jkvw3525pzvzPwiM5FUzxuGLkDSMAy/VJThl4oy\n/FJRhl8qyvBLRRl+qSjDLxVl+KWi3jjNjZ0bm/M8tkxzk1Ip/+ZfvJSnY5xlW4U/Iq4CbgPOAb6X\nmbest/x5bOGyuLLNJiWt43AeGnvZiU/7I+Ic4LvAp4GLgT0RcfGk65M0XW0+8+8Cns7MZzLzJeDH\nwO5uypLUtzbhvwD424rXR5t5/yci9kXEUkQsneF0i81J6lLv3/Zn5mJmLmTmwiY29705SWNqE/5j\nwI4Vr9/dzJM0B9qE/0Hgooh4b0ScC3wOONhNWZL6NnGrLzNfjogbgF+y3Orbn5lPdFaZpF616vNn\n5n3AfR3VImmKvLxXKsrwS0UZfqkowy8VZfilogy/VJThl4oy/FJRhl8qyvBLRRl+qSjDLxVl+KWi\nDL9UlOGXijL8UlGGXyrK8EtFGX6pKMMvFWX4paIMv1SU4ZeKMvxSUYZfKsrwS0UZfqkowy8VZfil\nolqN0hsRR4AXgVeAlzNzoYui1J1f/v2Rdd//1Lt2Drb9jbztedAq/I2PZeY/OliPpCnytF8qqm34\nE/hVRDwUEfu6KEjSdLQ97b8iM49FxDuB+yPij5n5wMoFmv8U9gGcx5tabk5SV1od+TPzWPP7JHAP\nsGuVZRYzcyEzFzaxuc3mJHVo4vBHxJaIeMvZaeCTwONdFSapX21O+7cB90TE2fX8KDN/0UlVkno3\ncfgz8xnggx3Woh7Mcz971DUKasdWn1SU4ZeKMvxSUYZfKsrwS0UZfqmoLu7qU89sea1uVBuzzX5r\nu8/b1Dat9qxHfqkowy8VZfilogy/VJThl4oy/FJRhl8qyj5/B9o+HnvIx2sP2c8ect1ttz3r6x+H\nR36pKMMvFWX4paIMv1SU4ZeKMvxSUYZfKioyc2obe2tszcviyqltb6MYepjt9fRZW5/XIMzyPm3j\ncB7ihTwV4yzrkV8qyvBLRRl+qSjDLxVl+KWiDL9UlOGXihp5P39E7Ac+A5zMzEuaeVuBnwAXAkeA\nazPz+f7K1Kzqs4/fttfe5/3+G+E6gXGO/N8HrnrVvBuBQ5l5EXCoeS1pjowMf2Y+AJx61ezdwIFm\n+gBwTcd1SerZpJ/5t2Xm8Wb6WWBbR/VImpLWX/jl8s0Ba94gEBH7ImIpIpbOcLrt5iR1ZNLwn4iI\n7QDN75NrLZiZi5m5kJkLm9g84eYkdW3S8B8E9jbTe4F7uylH0rSMDH9E3A38DvhARByNiOuBW4BP\nRMRTwMeb15LmyMg+f2buWeMtb8wfU5/95r7XPw/96rW0uZ+/zbrnhVf4SUUZfqkowy8VZfilogy/\nVJThl4pyiO4pGHKo6VGqDh++EVp1bXnkl4oy/FJRhl8qyvBLRRl+qSjDLxVl+KWi7PPPgSF76X1u\ne5avf6jAI79UlOGXijL8UlGGXyrK8EtFGX6pKMMvFRXLo21Nx1tja14WPvG7a/P6PIBZvqd+Xofg\nPpyHeCFPxTjLeuSXijL8UlGGXyrK8EtFGX6pKMMvFWX4paJG3s8fEfuBzwAnM/OSZt7NwBeA55rF\nbsrM+/oqct713TPucyjqUfpc/yw/a2AjGOfI/33gqlXm35qZO5sfgy/NmZHhz8wHgFNTqEXSFLX5\nzH9DRDwaEfsj4vzOKpI0FZOG/3bg/cBO4Djw7bUWjIh9EbEUEUtnOD3h5iR1baLwZ+aJzHwlM/8D\n3AHsWmfZxcxcyMyFTWyetE5JHZso/BGxfcXLzwKPd1OOpGkZp9V3N/BR4O0RcRT4BvDRiNgJJHAE\n+GKPNUrqwcjwZ+aeVWbf2UMtG1bbnvE8P7++Qr98XnmFn1SU4ZeKMvxSUYZfKsrwS0UZfqkoH929\nwfV9W2ybNqRtwO756G5JIxl+qSjDLxVl+KWiDL9UlOGXijL8UlEjb+nVaG176X3//axqW7fXCbTj\nkV8qyvBLRRl+qSjDLxVl+KWiDL9UlOGXirLP34E+h9iGYYeqHvIaAvv4/fLILxVl+KWiDL9UlOGX\nijL8UlGGXyrK8EtFjezzR8QO4C5gG5DAYmbeFhFbgZ8AFwJHgGsz8/n+Sq2rzXUAfV+DMEqftamd\ncY78LwNfzcyLgQ8DX4qIi4EbgUOZeRFwqHktaU6MDH9mHs/Mh5vpF4EngQuA3cCBZrEDwDV9FSmp\ne6/rM39EXAhcChwGtmXm8eatZ1n+WCBpTowd/oh4M/Az4CuZ+cLK93J5wL9VB/2LiH0RsRQRS2c4\n3apYSd0ZK/wRsYnl4P8wM3/ezD4REdub97cDJ1f728xczMyFzFzYxOYuapbUgZHhj4gA7gSezMzv\nrHjrILC3md4L3Nt9eZL6Ms4tvZcD1wGPRcTZvs1NwC3ATyPieuCvwLX9lDj7hrzldtT65/Wx3urf\nyPBn5m+Btcb7vrLbciRNi1f4SUUZfqkowy8VZfilogy/VJThl4raMI/uHrLXXvnW1Da3Gw99fUR1\nHvmlogy/VJThl4oy/FJRhl8qyvBLRRl+qagN0+cfsic8y/fMtx3+u+/tazge+aWiDL9UlOGXijL8\nUlGGXyrK8EtFGX6pqA3T5x9Sn8NYd7H+odYN7a4j8BqBfnnkl4oy/FJRhl8qyvBLRRl+qSjDLxVl\n+KWiRvb5I2IHcBewDUhgMTNvi4ibgS8AzzWL3pSZ9/VVqOaTvfrZNc5FPi8DX83MhyPiLcBDEXF/\n896tmfmt/sqT1JeR4c/M48DxZvrFiHgSuKDvwiT163V95o+IC4FLgcPNrBsi4tGI2B8R56/xN/si\nYikils5wulWxkrozdvgj4s3Az4CvZOYLwO3A+4GdLJ8ZfHu1v8vMxcxcyMyFTWzuoGRJXRgr/BGx\nieXg/zAzfw6QmScy85XM/A9wB7CrvzIldW1k+CMigDuBJzPzOyvmb1+x2GeBx7svT1Jfxvm2/3Lg\nOuCxiDh7f+ZNwJ6I2Mly++8I8MVeKizAdpiGMM63/b8FYpW37OlLc8wr/KSiDL9UlOGXijL8UlGG\nXyrK8EtFGX6pKMMvFWX4paIMv1SU4ZeKMvxSUYZfKsrwS0VFZk5vYxHPAX9dMevtwD+mVsDrM6u1\nzWpdYG2T6rK292TmO8ZZcKrhf83GI5Yyc2GwAtYxq7XNal1gbZMaqjZP+6WiDL9U1NDhXxx4++uZ\n1dpmtS6wtkkNUtugn/klDWfoI7+kgQwS/oi4KiL+FBFPR8SNQ9Swlog4EhGPRcQjEbE0cC37I+Jk\nRDy+Yt7WiLg/Ip5qfq86TNpAtd0cEceaffdIRFw9UG07IuI3EfGHiHgiIr7czB90361T1yD7beqn\n/RFxDvBn4BPAUeBBYE9m/mGqhawhIo4AC5k5eE84Ij4C/BO4KzMvaeZ9EziVmbc0/3Gen5lfm5Ha\nbgb+OfTIzc2AMttXjiwNXAN8ngH33Tp1XcsA+22II/8u4OnMfCYzXwJ+DOweoI6Zl5kPAKdeNXs3\ncKCZPsDyP56pW6O2mZCZxzPz4Wb6ReDsyNKD7rt16hrEEOG/APjbitdHma0hvxP4VUQ8FBH7hi5m\nFduaYdMBngW2DVnMKkaO3DxNrxpZemb23SQjXnfNL/xe64rM/BDwaeBLzentTMrlz2yz1K4Za+Tm\naVllZOn/GXLfTTriddeGCP8xYMeK1+9u5s2EzDzW/D4J3MPsjT584uwgqc3vkwPX8z+zNHLzaiNL\nMwP7bpZGvB4i/A8CF0XEeyPiXOBzwMEB6niNiNjSfBFDRGwBPsnsjT58ENjbTO8F7h2wlv8zKyM3\nrzWyNAPvu5kb8Tozp/4DXM3yN/5/Ab4+RA1r1PU+4PfNzxND1wbczfJp4BmWvxu5HngbcAh4Cvg1\nsHWGavsB8BjwKMtB2z5QbVewfEr/KPBI83P10PtunboG2W9e4ScV5Rd+UlGGXyrK8EtFGX6pKMMv\nFWX4paIMv1SU4ZeK+i/IRTHXOh7KiAAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x119feb588>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x119fd9940>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x11a091e80>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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\nYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x11a55b128>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"for m in range(4):\n",
" im = Image.open('tmp/out/%d.png'%m, \"r\")\n",
" plt.imshow(np.array(im))\n",
" plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"残念…"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment