mirror of
https://github.com/Deepshift/DeepCreamPy.git
synced 2024-12-11 06:59:17 +00:00
233 lines
7.8 KiB
Python
233 lines
7.8 KiB
Python
|
import tensorflow as tf
|
||
|
import tensorflow.contrib.layers as layers
|
||
|
import numpy as np
|
||
|
import random as rr
|
||
|
import math as mt
|
||
|
import cv2
|
||
|
from scipy import misc
|
||
|
|
||
|
def instance_norm(input, name="instance_norm"):
|
||
|
with tf.variable_scope(name):
|
||
|
depth = input.get_shape()[3]
|
||
|
scale = tf.get_variable("scale", [depth], initializer=tf.random_normal_initializer(1.0, 0.02, dtype=tf.float32))
|
||
|
offset = tf.get_variable("offset", [depth], initializer=tf.constant_initializer(0.0))
|
||
|
mean, variance = tf.nn.moments(input, axes=[1,2], keep_dims=True)
|
||
|
epsilon = 1e-5
|
||
|
inv = tf.rsqrt(variance + epsilon)
|
||
|
normalized = (input-mean)*inv
|
||
|
return scale*normalized + offset
|
||
|
|
||
|
def make_sq_mask(size, m_size, batch_size):
|
||
|
|
||
|
start_x = rr.randint(0, size - m_size-1)
|
||
|
start_y = rr.randint(0, size - m_size-1)
|
||
|
|
||
|
temp = np.ones([batch_size, size, size, 3])
|
||
|
|
||
|
temp[:, start_x:start_x + m_size, start_y:start_y + m_size, 0:3] *= 0
|
||
|
|
||
|
return temp, start_x, start_y
|
||
|
|
||
|
def softmax(input):
|
||
|
|
||
|
k = tf.exp(input - 3)
|
||
|
k = tf.reduce_sum(k, 3, True)
|
||
|
# k = k - num * tf.ones_like(k)
|
||
|
|
||
|
ouput = tf.exp(input - 3) / k
|
||
|
|
||
|
return ouput
|
||
|
|
||
|
def reduce_var(x, axis=None, keepdims=False):
|
||
|
"""Variance of a tensor, alongside the specified axis.
|
||
|
|
||
|
# Arguments
|
||
|
x: A tensor or variable.
|
||
|
axis: An integer, the axis to compute the variance.
|
||
|
keepdims: A boolean, whether to keep the dimensions or not.
|
||
|
If `keepdims` is `False`, the rank of the tensor is reduced
|
||
|
by 1. If `keepdims` is `True`,
|
||
|
the reduced dimension is retained with length 1.
|
||
|
|
||
|
# Returns
|
||
|
A tensor with the variance of elements of `x`.
|
||
|
"""
|
||
|
m = tf.reduce_mean(x, axis=axis, keepdims=True)
|
||
|
devs_squared = tf.square(x - m)
|
||
|
return tf.reduce_mean(devs_squared, axis=axis, keepdims=keepdims)
|
||
|
|
||
|
def reduce_std(x, axis=None, keepdims=False):
|
||
|
"""Standard deviation of a tensor, alongside the specified axis.
|
||
|
|
||
|
# Arguments
|
||
|
x: A tensor or variable.
|
||
|
axis: An integer, the axis to compute the standard deviation.
|
||
|
keepdims: A boolean, whether to keep the dimensions or not.
|
||
|
If `keepdims` is `False`, the rank of the tensor is reduced
|
||
|
by 1. If `keepdims` is `True`,
|
||
|
the reduced dimension is retained with length 1.
|
||
|
|
||
|
# Returns
|
||
|
A tensor with the standard deviation of elements of `x`.
|
||
|
"""
|
||
|
return tf.sqrt(reduce_var(x, axis=axis, keepdims=keepdims))
|
||
|
|
||
|
def l2_norm(v, eps=1e-12):
|
||
|
return v / (tf.reduce_sum(v ** 2) ** 0.5 + eps)
|
||
|
|
||
|
def ff_mask(size, b_zise, maxLen, maxWid, maxAng, maxNum, maxVer, minLen = 20, minWid = 15, minVer = 5):
|
||
|
|
||
|
mask = np.ones((b_zise, size, size, 3))
|
||
|
|
||
|
num = rr.randint(3, maxNum)
|
||
|
|
||
|
for i in range(num):
|
||
|
startX = rr.randint(0, size)
|
||
|
startY = rr.randint(0, size)
|
||
|
numVer = rr.randint(minVer, maxVer)
|
||
|
width = rr.randint(minWid, maxWid)
|
||
|
for j in range(numVer):
|
||
|
angle = rr.uniform(-maxAng, maxAng)
|
||
|
length = rr.randint(minLen, maxLen)
|
||
|
|
||
|
endX = min(size-1, max(0, int(startX + length * mt.sin(angle))))
|
||
|
endY = min(size-1, max(0, int(startY + length * mt.cos(angle))))
|
||
|
|
||
|
if endX >= startX:
|
||
|
lowx = startX
|
||
|
highx = endX
|
||
|
else:
|
||
|
lowx = endX
|
||
|
highx = startX
|
||
|
if endY >= startY:
|
||
|
lowy = startY
|
||
|
highy = endY
|
||
|
else:
|
||
|
lowy = endY
|
||
|
highy = startY
|
||
|
|
||
|
if abs(startY-endY) + abs(startX - endX) != 0:
|
||
|
|
||
|
wlx = max(0, lowx-int(abs(width * mt.cos(angle))))
|
||
|
whx = min(size - 1, highx+1 + int(abs(width * mt.cos(angle))))
|
||
|
wly = max(0, lowy - int(abs(width * mt.sin(angle))))
|
||
|
why = min(size - 1, highy+1 + int(abs(width * mt.sin(angle))))
|
||
|
|
||
|
for x in range(wlx, whx):
|
||
|
for y in range(wly, why):
|
||
|
|
||
|
d = abs((endY-startY)*x - (endX -startX)*y - endY*startX + startY*endX) / mt.sqrt((startY-endY)**2 + (startX -endX)**2)
|
||
|
|
||
|
if d <= width:
|
||
|
mask[:, x, y, :] = 0
|
||
|
|
||
|
wlx = max(0, lowx-width)
|
||
|
whx = min(size - 1, highx+width+1)
|
||
|
wly = max(0, lowy - width)
|
||
|
why = min(size - 1, highy + width + 1)
|
||
|
|
||
|
for x2 in range(wlx, whx):
|
||
|
for y2 in range(wly, why):
|
||
|
|
||
|
d1 = (startX - x2) ** 2 + (startY - y2) ** 2
|
||
|
d2 = (endX - x2) ** 2 + (endY - y2) ** 2
|
||
|
|
||
|
if np.sqrt(d1) <= width:
|
||
|
mask[:, x2, y2, :] = 0
|
||
|
if np.sqrt(d2) <= width:
|
||
|
mask[:, x2, y2, :] = 0
|
||
|
startX = endX
|
||
|
startY = endY
|
||
|
|
||
|
return mask
|
||
|
|
||
|
def ff_mask_batch(size, b_size, maxLen, maxWid, maxAng, maxNum, maxVer, minLen = 20, minWid = 15, minVer = 5):
|
||
|
|
||
|
mask = None
|
||
|
temp = ff_mask(size, 1, maxLen, maxWid, maxAng, maxNum, maxVer, minLen=minLen, minWid=minWid, minVer=minVer)
|
||
|
temp = temp[0]
|
||
|
for ib in range(b_size):
|
||
|
if ib == 0:
|
||
|
mask = np.expand_dims(temp, 0)
|
||
|
else:
|
||
|
mask = np.concatenate((mask, np.expand_dims(temp, 0)), 0)
|
||
|
|
||
|
temp = cv2.rotate(temp, cv2.ROTATE_90_CLOCKWISE)
|
||
|
if ib == 3:
|
||
|
temp = cv2.flip(temp, 0)
|
||
|
|
||
|
return mask
|
||
|
|
||
|
def spectral_norm(w, name, iteration=1):
|
||
|
w_shape = w.shape.as_list()
|
||
|
w = tf.reshape(w, [-1, w_shape[-1]])
|
||
|
|
||
|
u = tf.get_variable(name+"u", [1, w_shape[-1]], initializer=tf.truncated_normal_initializer(), trainable=False)
|
||
|
|
||
|
u_hat = u
|
||
|
v_hat = None
|
||
|
for i in range(iteration):
|
||
|
"""
|
||
|
power iteration
|
||
|
Usually iteration = 1 will be enough
|
||
|
"""
|
||
|
v_ = tf.matmul(u_hat, tf.transpose(w))
|
||
|
v_hat = l2_norm(v_)
|
||
|
|
||
|
u_ = tf.matmul(v_hat, w)
|
||
|
u_hat = l2_norm(u_)
|
||
|
|
||
|
sigma = tf.matmul(tf.matmul(v_hat, w), tf.transpose(u_hat))
|
||
|
w_norm = w / sigma
|
||
|
|
||
|
with tf.control_dependencies([u.assign(u_hat)]):
|
||
|
w_norm = tf.reshape(w_norm, w_shape)
|
||
|
|
||
|
return w_norm
|
||
|
|
||
|
def convolution_SN(tensor, output_dim, kernel_size, stride, name):
|
||
|
_, h, w, c = [i.value for i in tensor.get_shape()]
|
||
|
|
||
|
w = tf.get_variable(name=name + 'w', shape=[kernel_size, kernel_size, c, output_dim], initializer=layers.xavier_initializer())
|
||
|
b = tf.get_variable(name=name + 'b', shape=[output_dim], initializer=tf.constant_initializer(0.0))
|
||
|
|
||
|
output = tf.nn.conv2d(tensor, filter=spectral_norm(w, name=name + 'w'), strides=[1, stride, stride, 1], padding='SAME') + b
|
||
|
|
||
|
return output
|
||
|
|
||
|
def dense_SN(tensor, output_dim, name):
|
||
|
_, h, w, c = [i.value for i in tensor.get_shape()]
|
||
|
|
||
|
w = tf.get_variable(name=name + 'w', shape=[h, w, c, output_dim], initializer=layers.xavier_initializer())
|
||
|
b = tf.get_variable(name=name + 'b', shape=[output_dim], initializer=tf.constant_initializer(0.0))
|
||
|
|
||
|
output = tf.nn.conv2d(tensor, filter=spectral_norm(w, name=name + 'w'), strides=[1, 1, 1, 1], padding='VALID') + b
|
||
|
|
||
|
return output
|
||
|
|
||
|
def dense_RED_SN(tensor, name):
|
||
|
sn_w = None
|
||
|
|
||
|
_, h, w, c = [i.value for i in tensor.get_shape()]
|
||
|
h = int(h)
|
||
|
w = int(w)
|
||
|
c = int(c)
|
||
|
|
||
|
weight = tf.get_variable(name=name + '_w', shape=[h*w, 1, c, 1], initializer=layers.xavier_initializer())
|
||
|
b = tf.get_variable(name=name + '_b', shape=[1, h, w, 1], initializer=tf.constant_initializer(0.0))
|
||
|
|
||
|
for it in range(h*w):
|
||
|
w_pixel = weight[it:it+1, :, :, :]
|
||
|
sn_w_pixel = spectral_norm(w_pixel, name=name + 'w_%d' %it)
|
||
|
|
||
|
if it == 0:
|
||
|
sn_w = sn_w_pixel
|
||
|
else:
|
||
|
sn_w = tf.concat([sn_w, sn_w_pixel], axis=0)
|
||
|
|
||
|
w_rs = tf.reshape(sn_w, [h, w, c, 1])
|
||
|
w_rs_t = tf.transpose(w_rs, [3, 0, 1, 2])
|
||
|
|
||
|
output_RED = tf.reduce_sum(tensor*w_rs_t + b, axis=3, keepdims=True)
|
||
|
|
||
|
return output_RED
|