头歌DeepDream---让计算机成为抽象派画家

第一关

from keras import backend as K
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt
import numpy as np
def feature_map_vis(model, image):
    '''
    将model的第6层所生成最后4个特征图可视化,并保存到./step1/result/feature_map.png中
    :param model: VGG16模型
    :param image: 待输入的图像,类型为ndarray,shape为(224, 224, 3)
    :return: 无
    '''
    #********* Begin *********#
    image = np.expand_dims(image, axis=0)
    get_feature_map_op = K.function([model.layers[0].input], [model.layers[6].output])
    feature_map = get_feature_map_op([image])[0]
    for i in range(4):
                show_img = feature_map[:, :, :, -i]
                show_img.shape = [feature_map.shape[1], feature_map.shape[2]]
                plt.subplot(1, 4, i + 1)
                plt.imshow(show_img, cmap='gray')
                plt.axis('off')
    plt.savefig('./step1/result/feature_map.png')
    #********* End *********#

​

第二关

from keras import backend as K
import numpy as np
def update_img(epochs, input_layer, feature_map, learning_rate):
    '''
    随机生成1张宽224,高224的RGB图像,并更行图像
    :param epochs: 梯度上升的迭代次数
    :param input_layer: CNN模型的输入层
    :param feature_map: CNN模型的指定的特征图
    :param learning_rate: 梯度上升的学习率
    :return: 更新后的图像和,其中图像的维度为(图像的高,图像的宽,通道数)
    '''
    #********* Begin *********#
    def normalize(x):
        return x / (K.sqrt(K.mean(K.square(x))) + K.epsilon())
    img = np.random.randint(low=0, high=255, size=(1, 224, 224, 3))
    img = img / 255.0
    loss = K.mean(feature_map)
    grads = K.gradients(loss, input_layer)[0]
    grads = normalize(grads)
    iterate = K.function([input_layer], [loss, grads])
    for _ in range(epochs):
        loss_value, grads_value = iterate([img])
        img += grads_value * learning_rate
        if loss_value <= K.epsilon():
            break
    return img
    #********* End *********#

第三关

from keras import backend as K
import numpy as np
def deep_dream(img, model, epochs, learning_rate, max_threshold):
    '''
    将VGG16的block4_conv1与block5_conv2用来做deep dream,其中block4_conv1的权重为0.05,block5_conv2的权重为0.2,并将图像返回
    :param img: 预处理后的图像,类型为ndarray,shape为(样本个数,图像的宽,图像的高,通道数)
    :param model: VGG16
    :param epochs: 梯度上升的迭代次数
    :param learning_rate: 梯度上升的学习率
    :param max_threshold: 损失值的最大阈值
    :return: deep dream后的图像,其中图像的维度为(图像的高,图像的宽,通道数)
    '''
    #********* Begin *********#
    layer_contributions = {
        'block4_conv1': 0.05,
        'block5_conv2': 0.2
    }
    # 定义一个包含损失的张量,即上面列出的激活的L2范数的加权和。
    layer_dict = dict([(layer.name, layer) for layer in model.layers])
    # 定义损失
    loss = K.variable(0.)
    for layer_name in layer_contributions:
        # 将丢失的图层特征的L2范数添加到损失中。
        coeff = layer_contributions[layer_name]
        activation = layer_dict[layer_name].output
        # 通过仅涉及损失中的非边界像素来避免边界伪影。
        scaling = K.prod(K.cast(K.shape(activation), 'float32'))
        loss += coeff * K.sum(K.square(activation[:, :, :, :])) / scaling
    dream = model.input
    # 计算损失的梯度的变化
    grads = K.gradients(loss, dream)[0]
    # 标准化梯度
    grads /= K.maximum(K.mean(K.abs(grads)), 1e-7)
    # 设置函数以检索给定输入图像的损失和梯度值。
    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
    for i in range(epochs):
        loss_value, grad_values = eval_loss_and_grads(img)
        if max_threshold is not None and loss_value > max_threshold:
            break
        img = img + learning_rate * grad_values
    return img
    #********* End *********#

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值