以下の記事で紹介している画風変換のソースコードからエッセンスを抽出してみました。
画風を変換するアルゴリズム

エッセンスを抽出したソースコードを以下に載せます。
元コードのchainer-gogh.pyに相当します。
#coding:utf-8
import os, sys
import chainer.links as L
import numpy as np
from chainer import optimizers
from PIL import Image
from models import *

# 定数
iter = 5000
width = 435
mean = 120
lr = 4.0

# 画像ファイルの入力と変換
def image_resize(img_file, width):
img = Image.open(img_file)
if img.size != (width, width):
print "Image must be square."
sys.exit()
img = np.asarray(img)[:,:,:3].transpose(2, 0, 1)[::-1].astype(np.float32)
return img.reshape(1, 3, width, width) - mean

# 画像の保存
def save_image(img, width, it):
def to_img(x):
im = np.zeros((width, width, 3))
im[:,:,0] = x[2,:,:]
im[:,:,1] = x[1,:,:]
im[:,:,2] = x[0,:,:]
def clip(a):
return 0 if a<0 else (255 if a>255 else a)
im = np.vectorize(clip)(im).astype(np.uint8)
Image.fromarray(im).save("im_%05d.png"%it)

to_img(img[0,:,:,:] + mean)

# スタイル行列の算出
def get_matrix(y):
ch = y.data.shape[1]
wd = y.data.shape[2]
gogh_y = F.reshape(y, (ch,wd**2))
gogh_matrix = F.matmul(gogh_y, gogh_y, transb=True)/np.float32(ch*wd**2)
return gogh_matrix

# モデルの読み込み
nn = NIN()

# 画像の入力
img_orig = image_resize("cat.png", width)
img_style = image_resize("style_0.png", width)

# 中間層とスタイル行列の算出
mid_orig = nn.forward(Variable(img_orig, volatile=True))
style_mats = [get_matrix(y) for y in nn.forward(Variable(img_style, volatile=True))]

# 初期合成画像を生成し、最適化対象として設定
img_gen = np.random.uniform(-20,20,(1,3,width,width)).astype(np.float32)
img_gen = L.Parameter(img_gen)
optimizer = optimizers.Adam(alpha = lr)
optimizer.setup(img_gen)

for i in range(iter):
img_gen.zerograds()
y = nn.forward(img_gen.W)
loss = Variable(np.zeros((), dtype=np.float32))
for l in range(len(y)):
# 損失関数の算出
loss1 = np.float32(0.005) * np.float32(nn.alpha[l])*F.mean_squared_error(y[l], Variable(mid_orig[l].data))
loss2 = np.float32(nn.beta[l])*F.mean_squared_error(get_matrix(y[l]), Variable(style_mats[l].data))/np.float32(len(y))
loss += loss1 + loss2

loss.backward()
optimizer.update()
tmp_shape = img_gen.W.data.shape
def clip(x):
return -120 if x<-120 else (136 if x>136 else x)
img_gen.W.data += np.vectorize(clip)(img_gen.W.data).reshape(tmp_shape) - img_gen.W.data

if i%50==0:
print i
save_image(img_gen.W.data, width, i)
たったの82行!
やはりChainerすごいですね。

ほとんど解説の必要はなさそうですが……、肝となるのは以下の部分でしょうか。
# 初期合成画像を生成し、最適化対象として設定
img_gen = np.random.uniform(-20,20,(1,3,width,width)).astype(np.float32)
img_gen = L.Parameter(img_gen)
optimizer = optimizers.Adam(alpha = lr)
optimizer.setup(img_gen)
ランダムな画像を生成して、それを最適化対象パラメータとしてoptimizerに設定しています。
ネットワークではなく、画像を更新するのですね。面白い。