https://www.jianshu.com/p/2961d27674a5?from=timeline 代码如下:
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 22 14:30:27 2019
@author: 10244074
"""
import scipy.io as sio
import tensorflow as tf
import numpy as np
import PIL
vgg19Model = "imagenet-vgg-verydeep-19.mat"
vggLayer = sio.loadmat(vgg19Model)['layers'][0]
noiseSave = "noiseImage"
contextPath = "2 (1).png"
stylePath = "2 (2).png"
# 设置图像的路径以及需要调整到的宽度值和高度值
IMAGE_W = 800
IMAGE_H = 600
CONTENT_LAYERS = [('conv4_2', 1.)]
STYLE_LAYERS = [('conv1_1', 1.), ('conv2_1', 1.), ('conv3_1', 1.), ('conv4_1', 1.), ('conv5_1', 1.)]
def getWeightAndBias(i):
weight = vggLayer[i][0][0][0][0][0]
weight = tf.constant(weight)
bias = vggLayer[i][0][0][0][0][1]
bias = tf.constant(np.reshape(bias, bias.size))
return weight, bias
# 定义建立池化层和卷积层网络的函数
def build_net(ntype, nin, nwb=None):
if ntype == 'conv':
return tf.nn.relu(tf.nn.conv2d(nin, nwb[0], strides=[1, 1, 1, 1], padding='SAME') + nwb[1])
elif ntype == 'pool':
return tf.nn.avg_pool(nin, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
def getNet(inputImage):
net = {}
# net["input"] = tf.Variable(np.zeros((1, IMAGE_H, IMAGE_W, 3)).astype("float32"))
net["input"] = inputImage
net["conv1_1"] = build_net("conv", net["input"], getWeightAndBias(0))
net['conv1_2'] = build_net('conv', net['conv1_1'], getWeightAndBias(2))
net['pool1'] = build_net('pool', net['conv1_2'])
net['conv2_1'] = build_net('conv', net['pool1'], getWeightAndBias(5))
net['conv2_2'] = build_net('conv', net['conv2_1'], getWeightAndBias(7))
net['pool2'] = build_net('pool', net['conv2_2'])
net['conv3_1'] = build_net('conv', net['pool2'], getWeightAndBias(10))
net['conv3_2'] = build_net('conv', net['conv3_1'], getWeightAndBias(12))
net['conv3_3'] = build_net('conv', net['conv3_2'], getWeightAndBias(14))
net['conv3_4'] = build_net('conv', net['conv3_3'], getWeightAndBias(16))
net['pool3'] = build_net('pool', net['conv3_4'])
net['conv4_1'] = build_net('conv', net['pool3'], getWeightAndBias(19))
net['conv4_2'] = build_net('conv', net['conv4_1'], getWeightAndBias(21))
net['conv4_3'] = build_net('conv', net['conv4_2'], getWeightAndBias(23))
net['conv4_4'] = build_net('conv', net['conv4_3'], getWeightAndBias(25))
net['pool4'] = build_net('pool', net['conv4_4'])
net['conv5_1'] = build_net('conv', net['pool4'], getWeightAndBias(28))
net['conv5_2'] = build_net('conv', net['conv5_1'], getWeightAndBias(30))
net['conv5_3'] = build_net('conv', net['conv5_2'], getWeightAndBias(32))
net['conv5_4'] = build_net('conv', net['conv5_3'], getWeightAndBias(34))
net['pool5'] = build_net('pool', net['conv5_4'])
return net
def getImage(path):
image = np.array(PIL.Image.open(path))
# image=scipy.misc.imresize(image,(IMAGE_H,IMAGE_W))
image = image[np.newaxis, :, :, :] - 128.0 # 以0为中心,可以加快收敛
image = image.astype(np.float32)
return image
def saveImage(image, path, i):
image = image + 128
image = image[0]
image = np.clip(image, 0, 255).astype("uint8")
path1 = path + str(i) + ".png"
PIL.Image.fromarray(image).save(path1)
def getLoss(noiseImage, contextImage, styleImag):
contextLay = getNet(contextImage)
styleLay = getNet(styleImag)
noiseLay = getNet(noiseImage)
styleLoss = sum(map(lambda l: l[1] * buildStyLoss(noiseLay, styleLay, l[0]), STYLE_LAYERS))
contextLoss = sum(map(lambda l: l[1] * buildConLoss(noiseLay, contextLay, l[0]), CONTENT_LAYERS))
return contextLoss, styleLoss
def buildConLoss(noiseLay, contextLay, strKey):
noiseLay = noiseLay[strKey]
contextLay = contextLay[strKey]
_, high, wid, chan = map(lambda l: l.value, noiseLay.get_shape())
size = high * wid * chan
return tf.nn.l2_loss(contextLay - noiseLay) / size
def buildStyLoss(noiseLay, styleLay, strKey):
noiseLay = noiseLay[strKey]
styleLay = styleLay[strKey]
_, high, wid, chan = map(lambda l: l.value, noiseLay.get_shape())
size = high * wid * chan
noiseLay = tf.reshape(noiseLay, (-1, chan))
noiseLay = tf.matmul(tf.transpose(noiseLay), noiseLay)
styleLay = tf.reshape(styleLay, (-1, chan))
styleLay = tf.matmul(tf.transpose(styleLay), styleLay)
return tf.nn.l2_loss(noiseLay - styleLay) / (size ** 2)
with tf.Session() as sess:
contextImage = getImage(contextPath)
styleImage = getImage(stylePath)
noiseImage = tf.Variable(np.random.randn(1, IMAGE_H, IMAGE_W, 3), dtype="float32")
contextLoss, styleLoss = getLoss(noiseImage, contextImage, styleImage)
totalLoss = contextLoss + 0.0001*styleLoss
train = tf.train.AdamOptimizer(2.0).minimize(totalLoss)
sess.run(tf.global_variables_initializer())
for i in range(0, 500):
finaIma, _, loss, mu, xin = sess.run([noiseImage, train, totalLoss, contextLoss, styleLoss])
print("contextLoss: " + str(mu) + " " + "styleLoss: " + str(xin))
if i % 25 == 0:
saveImage(finaIma, noiseSave, i)