损失函数与噪声图像无关。
网络运行两次以确定损失函数的参数。一次用于内容图像,一次用于样式图像。您询问的代码随后出现。
首先,网络针对内容图像运行(注意这里没有噪声混合):
sess.run([net['input'].assign(content_img)])
旁白:使用赋值函数 - 而不是 a feed_dict- 因为为了使样式转换起作用,输入已成为 tf 变量,而不是占位符。
然后针对此运行中的一些网络参数定义第一个损失函数(这将从网络中提取感兴趣的激活作为损失函数的固定参数 - 因为它使用来自 的输出sess.run,而不是对张量变量的引用):
cost_content = sum(map(lambda l,: l[1]*
build_content_loss(sess.run(net[l[0]]),net[l[0]]) , CONTENT_LAYERS))
对样式图像执行相同的操作:
sess.run([net['input'].assign(style_img)])
cost_style = sum(map(lambda l: l[1]*
build_style_loss(sess.run(net[l[0]]), net[l[0]]), STYLE_LAYERS))
最终成本函数定义为:
cost_total = cost_content + STYLE_STRENGTH * cost_style
现在,在定义了成本函数之后,代码初始化了一个新的输入(这也是我们的风格转换输出):
sess.run(net['input'].assign( INI_NOISE_RATIO* noise_img +
(1.-INI_NOISE_RATIO) * content_img))
这条线与定义损失无关。它只是初始化网络,准备好针对起始图像和预先定义的损失函数生成梯度。您可以从纯噪声或内容图像的副本开始该过程,每个都会给出略有不同的结果。
原始论文从随机图像开始。引用论文(第 10 页):
因此我们可以改变最初的随机图像x~直到它在 CNN 的某一层产生相同的响应 [. . .]
. . . 但是,从内容图像开始,很快就被许多人在实践中尝试和使用,并且效果很好。
这两种方法的混合是作者选择的,大概是因为它得到了令人满意的结果。由于网络中没有比输入更低的层,实际上您可以从任意图像(例如全零)开始,您仍然应该得到结果,尽管它可能看起来不太好。
要(某种程度上)按书面形式回答您的问题:
为什么在内容丢失中使用噪声图像和内容图像的混合作为白噪声位的输入?
代码没有这样做。正如你所说,混合正在发生。但是您显示的线不是内容丢失的一部分。混合图像是初始解决方案,迭代会将其变成风格化图像。