官网实例详解4.11(deep_dream.py)-keras学习笔记四

基于Keras(实现)深梦

Keras实例目录

代码注释

'''Deep Dreaming in Keras.
基于Keras(实现)深梦
Run the script with:
使用如下指令运行脚本:
```
python deep_dream.py path_to_your_base_image.jpg prefix_for_results

运行执行 运行文件 参数1 参数2
python:运行python文件的python指令
deep_dream.py:python文件
path_to_your_base_image.jpg:参数1
prefix_for_results:参数2

```
e.g.:
或者以下指令:
```
python deep_dream.py img/mypic.jpg results/dream
```
'''
from __future__ import print_function

from keras.preprocessing.image import load_img, img_to_array
import numpy as np
import scipy
import argparse

from keras.applications import inception_v3
from keras import backend as K

parser = argparse.ArgumentParser(description='Deep Dreams with Keras.')
parser.add_argument('base_image_path', metavar='base', type=str,
                    help='Path to the image to transform.')
parser.add_argument('result_prefix', metavar='res_prefix', type=str,
                    help='Prefix for the saved results.')

args = parser.parse_args()
base_image_path = args.base_image_path
result_prefix = args.result_prefix

# These are the names of the layers
# for which we try to maximize activation,
# as well as their weight in the final loss
# we try to maximize.
# 这些是我们试图最大化激活的层的名称,以及它们在我们试图最大化的最终损失中的权重。
# You can tweak these setting to obtain new visual effects.
# 调整这些设置以获得新的视觉效果
settings = {
    'features': {
        'mixed2': 0.2,
        'mixed3': 0.5,
        'mixed4': 2.,
        'mixed5': 1.5,
    },
}


def preprocess_image(image_path):
    # Util function to open, resize and format pictures
    # into appropriate tensors.
    # 该(Util,跑龙套)函数打开,调整大小并将图片格式化为适当的张量。
    img = load_img(image_path)
    img = img_to_array(img)
    img = np.expand_dims(img, axis=0)
    img = inception_v3.preprocess_input(img)
    return img


def deprocess_image(x):
    # Util function to convert a tensor into a valid image.
    # 该函数将张量转换为有效图像。
    if K.image_data_format() == 'channels_first':
        x = x.reshape((3, x.shape[2], x.shape[3]))
        x = x.transpose((1, 2, 0))
    else:
        x = x.reshape((x.shape[1], x.shape[2], 3))
    x /= 2.
    x += 0.5
    x *= 255.
    x = np.clip(x, 0, 255).astype('uint8')
    return x

K.set_learning_phase(0)

# Build the InceptionV3 network with our placeholder.
# 我们的占位符构建InceptionV3网络。
# The model will be loaded with pre-trained ImageNet weights.
# 该模型将加载预先训练的ImageNet权重。
# ImageNet,创始人李飞飞, 是一个计算机视觉系统识别项目名称, 是目前世界上图像识别最大的数据库。是美国斯坦福的计算机科学家,
# 模拟人类的识别系统建立的。ImageNet能够从图片识别物体,是未来用在机器人身上,可以直接辨认物品和人了。
# www.image-net.org/
model = inception_v3.InceptionV3(weights='imagenet',
                                 include_top=False)
dream = model.input
print('Model loaded.')

# Get the symbolic outputs of each "key" layer (we gave them unique names).
# 获取每个“关键”层的符号输出(给它们唯一命名)。
layer_dict = dict([(layer.name, layer) for layer in model.layers])

# Define the loss.
# 定义损失函数
loss = K.variable(0.)
for layer_name in settings['features']:
    # Add the L2 norm of the features of a layer to the loss.
    # 将层的特征的L2范数添加到损失中。
    assert layer_name in layer_dict.keys(), 'Layer ' + layer_name + ' not found in model.'
    coeff = settings['features'][layer_name]
    x = layer_dict[layer_name].output
    # We avoid border artifacts by only involving non-border pixels in the loss.
    # 在损失中使用非边界像素来避免边界伪影。
    scaling = K.prod(K.cast(K.shape(x), 'float32'))
    if K.image_data_format() == 'channels_first':
        loss += coeff * K.sum(K.square(x[:, :, 2: -2, 2: -2])) / scaling
    else:
        loss += coeff * K.sum(K.square(x[:, 2: -2, 2: -2, :])) / scaling

# Compute the gradients of the dream wrt the loss.
# 计算梦想的梯度损失。
grads = K.gradients(loss, dream)[0]
# Normalize gradients.
# 归一化梯度
grads /= K.maximum(K.mean(K.abs(grads)), K.epsilon())

# Set up function to retrieve the value
# of the loss and gradients given an input image.
# 设置函数以获取给定输入图像的损失和梯度的值。
outputs = [loss, grads]
fetch_loss_and_grads = K.function([dream], outputs)


def eval_loss_and_grads(x):
    outs = fetch_loss_and_grads([x])
    loss_value = outs[0]
    grad_values = outs[1]
    return loss_value, grad_values


def resize_img(img, size):
    img = np.copy(img)
    if K.image_data_format() == 'channels_first':
        factors = (1, 1,
                   float(size[0]) / img.shape[2],
                   float(size[1]) / img.shape[3])
    else:
        factors = (1,
                   float(size[0]) / img.shape[1],
                   float(size[1]) / img.shape[2],
                   1)
    return scipy.ndimage.zoom(img, factors, order=1)


def gradient_ascent(x, iterations, step, max_loss=None):
    for i in range(iterations):
        loss_value, grad_values = eval_loss_and_grads(x)
        if max_loss is not None and loss_value > max_loss:
            break
        print('..Loss value at', i, ':', loss_value)
        x += step * grad_values
    return x


def save_img(img, fname):
    pil_img = deprocess_image(np.copy(img))
    scipy.misc.imsave(fname, pil_img)


"""Process:
处理过程:
- Load the original image.
    加载图片
- Define a number of processing scales (i.e. image shapes),
    from smallest to largest.
    定义处理尺度(级别范围)(即图像形状)从最小到最大
- Resize the original image to the smallest scale.
    调整原图为较小尺度
- For every scale, starting with the smallest (i.e. current one):
    对于每一个尺度,从最小的(即当前的)开始:
    - Run gradient ascent 运行梯度上升
    - Upscale image to the next scale  提升图像到下一个级别
    - Reinject the detail that was lost at upscaling time 重新填充在缩放时丢失的细节
- Stop when we are back to the original size.当我们回到原来的尺寸时停止。
    
To obtain the detail lost during upscaling, we simply
take the original image, shrink it down, upscale it,
and compare the result to the (resized) original image.
为了获得在缩放过程中丢失的细节,我们只需获取原始图像,缩小它,升级它,并将结果与(大小调整)原始图像进行比较。
"""


# Playing with these hyperparameters will also allow you to achieve new effects
# 使用超参数也会获得新的效果。
step = 0.01  # Gradient ascent step size 梯度上升步长
num_octave = 3  # Number of scales at which to run gradient ascent 运行梯度上升的级别数量
octave_scale = 1.4  # Size ratio between scales 刻度大小比率
iterations = 20  # Number of ascent steps per scale  比例上升步长数
max_loss = 10.

img = preprocess_image(base_image_path)
if K.image_data_format() == 'channels_first':
    original_shape = img.shape[2:]
else:
    original_shape = img.shape[1:3]
successive_shapes = [original_shape]
for i in range(1, num_octave):
    shape = tuple([int(dim / (octave_scale ** i)) for dim in original_shape])
    successive_shapes.append(shape)
successive_shapes = successive_shapes[::-1]
original_img = np.copy(img)
shrunk_original_img = resize_img(img, successive_shapes[0])

for shape in successive_shapes:
    print('Processing image shape', shape)
    img = resize_img(img, shape)
    img = gradient_ascent(img,
                          iterations=iterations,
                          step=step,
                          max_loss=max_loss)
    upscaled_shrunk_original_img = resize_img(shrunk_original_img, shape)
    same_size_original = resize_img(original_img, shape)
    lost_detail = same_size_original - upscaled_shrunk_original_img

    img += lost_detail
    shrunk_original_img = resize_img(original_img, shape)

save_img(img, fname=result_prefix + '.png')

代码执行

 

Keras详细介绍

英文:https://keras.io/

中文:http://keras-cn.readthedocs.io/en/latest/

实例下载

https://github.com/keras-team/keras

https://github.com/keras-team/keras/tree/master/examples

完整项目下载

方便没积分童鞋,请加企鹅452205574,共享文件夹。

包括:代码、数据集合(图片)、已生成model、安装库文件等。

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值