图片风格转换--深度学习介绍

前言

先举个机器学习的应用例子:图片的风格转换。

原图.jpg
处理后的图.jpg

机器学习

通过计算机强大的计算能力进行迭代运算、试错得到相关知识。
形象生动的描述请看:机器学习

深度学习

神经网络

上图是一个网络神经示意图,左边的是输入层,最右边的是输出层,两层之间的叫隐藏层,隐藏层大于2的神经网络就叫深度神经网络,深度学习就是基于深度神经网络的机器学习,深度学习是机器学习中的一种。

深度学习的相关概念

1、感知器
2、线性单元和梯度下降
3、神经网络和反向传播算法
4、卷积神经网络

一、感知器

感知器.png
1、输入权值:

x1,x2...是值,w1,w2....是权重。

2、激活函数 :

这里举个最简单的例子,采用阶跃函数


阶跃函数.png

输入权值,经过激活函数后就是0或1。

3、输出:

感知器就是通过输入的权重与值,经过激活函数预算,再通过输出公式得出结果

二、线性单元和梯度下降

1、什么是线性单元

激活函数为线性函数的感知器就叫做线性单元。
当面对的数据集不是线性可分的时候,『感知器规则』可能无法收敛,所以我们用可导线性函数来替代感知器的激活函数,例如f(x) = x
之后,线性单元将返回一个实数值而不是0,1分类。因此线性单元用来解决回归问题。

2、监督学习和无监督学习

机器学习有一类学习方法叫做监督学习,它是说为了训练一个模型,我们要提供这样一堆训练样本:每个训练样本即包括输入特征x,也包括对应的输出y(y也叫做标记,label)。也就是说,我们要找到很多人,我们既知道他们的特征x(工作年限,行业...),也知道他们的收入y。我们用这样的样本去训练模型,让模型既看到我们提出的每个问题(输入特征x),也看到对应问题的答案(标记y)。当模型看到足够多的样本之后,它就能总结出其中的一些规律。然后,就可以预测那些它没看过的输入所对应的答案了。

另外一类学习方法叫做无监督学习,这种方法的训练样本中只有x而没有y。模型可以总结出特征x的一些规律,但是无法知道其对应的答案y。

3、线性单元的目标函数
所有误差之和.png
Paste_Image.png
误差

模型的训练,实际上就是求取到合适的w,使误差E取得最小值。这在数学上称作优化问题,而就是我们优化的目标,称之为目标函数

4、梯度下降优化算法

梯度是一个向量,它指向函数值上升最快的方向,梯度的反方向当然就是函数值下降最快的方向.沿着梯度相反方向去修改x的值,进行迭代获得最小值。

Paste_Image.png

首先我们选择一个点开始,x0,接下来迭代x1,x2,x3..一直到函数最小值。
梯度下降算法的公式如下:


梯度下降算法公式.png

三、神经网络和反向传播算法

神经元

神经元就是激活函数或tanh函数的感知器。
多个神经元构成神经网络

神经元.png
sigmoid函数.png

神经网络的输出
神经网络实际上就是一个输入向量x(向量,不是普通的变量,具有方向)到输出向量y的函数,即:

Paste_Image.png
神经网络的输出.png
神经网络.png
反向传播算法(Back Propagation)

我们需要知道一个神经网络的每个连接上的权值是如何得到的。我们可以说神经网络是一个模型,那么这些权值就是模型的参数,也就是模型要学习的东西。然而,一个神经网络的连接方式、网络的层数、每层的节点数这些参数,则不是学习出来的,而是人为事先设置的。对于这些人为设置的参数,我们称之为超参数(Hyper-Parameters)。而我们需要做的是通过算法对神经网络进行训练,反向传播算法是神经网络训练算法。

计算一个节点的误差项,需要先计算每个与其相连的下一层节点的误差项。这就要求误差项的计算顺序必须是从输出层开始,然后反向依次计算每个隐藏层的误差项,直到与输入层相连的那个隐藏层。这就是反向传播算法的名字的含义,最后我们可以通过计算出的误差反过来修正权重。

就这样,通过不断迭代,不断修正权重对神经网络进行训练。

神经网络的输出.png

四、卷积神经网络

适合图像、语音识别任务的神经网络结构——卷积神经网络

1、Relu激活函数

在卷积神经网络中Relu函数更为适合作为激活函数,公式如下:

Relu.png

Relu函数图像如下图所示:


采用Relu函数,有以下优点:

速度快
减轻梯度消失问题
稀疏性

2、卷积神经网络

一个卷积神经网络由若干卷积层Pooling层全连接层组成

卷积神经网络.png

我们可以发现卷积神经网络的层结构和全连接神经网络的层结构有很大不同。全连接神经网络每层的神经元是按照一维排列的,也就是排成一条线的样子;而卷积神经网络每层的神经元是按照三维排列的,也就是排成一个长方体的样子,有宽度高度深度

实践应用:

一、通过深度学习对图片进行风格转换

原图与名画合成新图片:

原图.jpg
bigjiasuo.jpg
14764268560.0-10-bigjiasuo-googlenet-content-1e4-512.jpg
14764182840.0-10-fango-googlenet-content-1e4-512.jpg

主要的流程是:利用Caffe框架进行深度学习,通过梯度算法,完成颜色、线条等的训练集,然后对图片进行重绘。

1、框架、依赖等准备

(1)、安装python、pip、numpy。
(2)、安装深度学习框架caffe
(3)、下载训练模型:我采用的是googlenet model
(4)、下载style-transfer代码,根据自己的需求进行修改、优化。
(5)、根据style-transfer文档运行。

这几个步骤操作起来都是比较困难的,也算是个不小的门槛。其中Caffe的安装琐碎,会出现很多意外,是个大难题;style-transfer代码修改是最核心的部分。

2、核心代码展示

梯度处理代码:

def _compute_style_grad(F, G, G_style, layer):
    (Fl, Gl) = (F[layer], G[layer])
    c = Fl.shape[0]**-2 * Fl.shape[1]**-2
    El = Gl - G_style[layer]
    loss = c/4 * (El**2).sum()
    grad = c * sgemm(1.0, El, Fl) * (Fl>0)

    return loss, grad

def _compute_content_grad(F, F_content, layer):
    Fl = F[layer]
    El = Fl - F_content[layer]
    loss = (El**2).sum() / 2
    grad = El * (Fl>0)

    return loss, grad

矩阵计算

def _compute_reprs(net_in, net, layers_style, layers_content, gram_scale=1):
    (repr_s, repr_c) = ({}, {})
    net.blobs["data"].data[0] = net_in
    net.forward()

    for layer in set(layers_style)|set(layers_content):
        F = net.blobs[layer].data[0].copy()
        F.shape = (F.shape[0], -1)
        repr_c[layer] = F
        if layer in layers_style:
            repr_s[layer] = sgemm(gram_scale, F, F.T)

    return repr_s, repr_c

进行转换:

def transfer_style(self, img_style, img_content, length=512, ratio=1e5,
                       n_iter=512, init="-1", verbose=False, callback=None):
      

        # assume that convnet input is square
        orig_dim = min(self.net.blobs["data"].shape[2:])

        # rescale the images
        scale = max(length / float(max(img_style.shape[:2])),
                    orig_dim / float(min(img_style.shape[:2])))
        img_style = rescale(img_style, STYLE_SCALE*scale)
        scale = max(length / float(max(img_content.shape[:2])),
                    orig_dim / float(min(img_content.shape[:2])))
        img_content = rescale(img_content, scale)

        # compute style representations
        self._rescale_net(img_style)
        layers = self.weights["style"].keys()
        net_in = self.transformer.preprocess("data", img_style)
        gram_scale = float(img_content.size)/img_style.size
        G_style = _compute_reprs(net_in, self.net, layers, [],
                                 gram_scale=1)[0]

        # compute content representations
        self._rescale_net(img_content)
        layers = self.weights["content"].keys()
        net_in = self.transformer.preprocess("data", img_content)
        F_content = _compute_reprs(net_in, self.net, [], layers)[1]

        # generate initial net input
        # "content" = content image, see kaishengtai/neuralart
        if isinstance(init, np.ndarray):
            img0 = self.transformer.preprocess("data", init)
        elif init == "content":
            img0 = self.transformer.preprocess("data", img_content)
        elif init == "mixed":
            img0 = 0.95*self.transformer.preprocess("data", img_content) + \
                   0.05*self.transformer.preprocess("data", img_style)
        else:
            img0 = self._make_noise_input(init)

        # compute data bounds
        data_min = -self.transformer.mean["data"][:,0,0]
        data_max = data_min + self.transformer.raw_scale["data"]
        data_bounds = [(data_min[0], data_max[0])]*(img0.size/3) + \
                      [(data_min[1], data_max[1])]*(img0.size/3) + \
                      [(data_min[2], data_max[2])]*(img0.size/3)

        # optimization params
        grad_method = "L-BFGS-B"
        reprs = (G_style, F_content)
        minfn_args = {
            "args": (self.net, self.weights, self.layers, reprs, ratio),
            "method": grad_method, "jac": True, "bounds": data_bounds,
            "options": {"maxcor": 8, "maxiter": n_iter, "disp": verbose}
        }

        # optimize
        self._callback = callback
        minfn_args["callback"] = self.callback
        if self.use_pbar and not verbose:
            self._create_pbar(n_iter)
            self.pbar.start()
            res = minimize(style_optfn, img0.flatten(), **minfn_args).nit
            self.pbar.finish()
        else:
            res = minimize(style_optfn, img0.flatten(), **minfn_args).nit

        return res

二、其他比较出名的应用:

1、谷歌的deepdream:可以让你的机器自己做梦。

效果图.png

2、雅虎的色情图片检测神经网络:效果不知道,千万不能结合爬虫去爬图片,违法的。

参考链接:

感知器
线性单元和梯度下降
DeepDream安装
雅虎NSFW
谷歌DeepDream
caffe官网

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容

  • 你来到我身边时我还只是个孩子,当我长大后才发现你只是陪伴我长大教我成长的一个知己,我愿意把你留在自己的心里,而你却...
    大木子_f923阅读 366评论 0 3
  • 你们中间谁是有智慧有见识的呢?他就当在智慧的温柔上显出他的善行来。 (雅各书 3:13 和合本) 分享:原来有智慧...
    探路者James阅读 416评论 0 1
  • PS:作者很懒,所以能展示源码他就不会多说话 先来测试一下简书的Markdown语法支持,再bb 首先是简书支持的...
    谭雅翔阅读 325评论 4 3
  • Linux proc system proc 文件系统是由内核创建的虚拟文件系统,被内核用来向外界报告信息的一个文...
    Creator_Ly阅读 2,945评论 0 7