在Xcode中改变.tflite模型中的变量?



我正在尝试通过https://arxiv.org/pdf/1610.07629.pdf在iOS应用程序中实现神经风格转移模型。本文使用这个条件实例规范层来允许单个模型学习多种风格,并将这些风格组合起来。

下面是我的代码:

class ConditionalInstanceNorm(tf.keras.layers.Layer):
def __init__(self, scope_bn, y1, y2, alpha):
super(ConditionalInstanceNorm, self).__init__()
self.scope_bn = scope_bn
self.y1 = y1
self.y2 = y2
self.alpha = alpha

def build(self, input_shape):
self.beta = self.add_weight(name="beta"+self.scope_bn, shape=(self.y1.shape[-1], input_shape[-1]), initializer=betaInitializer, trainable=True)
self.gamma = self.add_weight(name="gamma"+self.scope_bn, shape=(self.y1.shape[-1], input_shape[-1]), initializer=gammaInitializer, trainable=True)

def call(self, inputs):
mean, var = tf.nn.moments(x=inputs, axes=[1,2], keepdims=True)
beta1 = tf.matmul(self.y1, self.beta)
gamma1 = tf.matmul(self.y1, self.gamma)
beta2 = tf.matmul(self.y2, self.beta)
gamma2 = tf.matmul(self.y2, self.gamma)
beta = self.alpha*beta1 + (1. - self.alpha)*beta2
gamma = self.alpha*gamma1 + (1. - self.alpha)*gamma2
x = tf.nn.batch_normalization(x=inputs, mean=mean, variance=var, offset=beta, scale=gamma, variance_epsilon=1e-10)
return x

它要求我传递3个超参数:y1, y2和alpha。每个样式都有一个惟一的y值(y1和y2是允许组合样式的不同样式)。Alpha决定了每个样式的影响力。

在python中,我在不同样式组合之间切换的方式是通过访问每个层,识别条件实例范数层,然后更改存储的y1, y2和alpha值:

for layer in filter(lambda x: "conditional_instance_norm" in x.name, model.layers):
layer.y1 = y1
layer.y1 = y2
layer.alpha = alpha

如何在swift中使用。tflite模型?现在我可以运行模型,但它被初始化时的y1, y2和alpha值卡住了。

我找到了一种能够输入值的方法,通过改变我的python模型的结构来包括3个额外的输入- y1, y2和alpha,就像这样:

def ImageTransformNetwork():
inputs = Input(shape=(dim,dim,3))
y1 = Input(shape=(13), batch_size=1)
y2 = Input(shape=(13), batch_size=1)
alpha = Input(shape=(1), batch_size=1)
x = PadConvBatch(x=inputs, kernel_size=9, scope_bn="1", y1=y1, y2=y2, alpha=alpha) 
x = PadConvBatch(x=x, filters=64, strides=2, scope_bn="2", y1=y1, y2=y2, alpha=alpha)
x = PadConvBatch(x=x, filters=128, strides=2, scope_bn="3", y1=y1, y2=y2, alpha=alpha)
x = Resblock(x=x, scope_bn1="4", scope_bn2="5", y1=y1, y2=y2, alpha=alpha)
x = Resblock(x=x, scope_bn1="6", scope_bn2="7", y1=y1, y2=y2, alpha=alpha)
x = Resblock(x=x, scope_bn1="8", scope_bn2="9", y1=y1, y2=y2, alpha=alpha)
x = Resblock(x=x, scope_bn1="10", scope_bn2="11", y1=y1, y2=y2, alpha=alpha)
x = Resblock(x=x, scope_bn1="12", scope_bn2="13", y1=y1, y2=y2, alpha=alpha)
x = PadConvBatch(x=x, filters=64, strides=0.5, scope_bn="14", y1=y1, y2=y2, alpha=alpha)
x = PadConvBatch(x=x, filters=32, strides=0.5, scope_bn="15", y1=y1, y2=y2, alpha=alpha)
x = tf.pad(x, [[0,0], [4,4], [4,4], [0,0]], "REFLECT")
x = Conv2D(filters=3, kernel_size=9, strides=1, activation='sigmoid', kernel_initializer=initializer)(x)
model = Model(inputs=[inputs, y1, y2, alpha], outputs=x)
return model

因此,在将其转换为tflite模型之后,我可以像这样放入变量:

try self.imageTransformInterpreter.copy(inputRGBData, toInputAt: 3)
try self.imageTransformInterpreter.copy(Data(bytes: yArray1, count: 52), toInputAt: 0)
try self.imageTransformInterpreter.copy(Data(bytes: yArray2, count: 52), toInputAt: 2)
try self.imageTransformInterpreter.copy(Data(buffer: alphaBuffer), toInputAt: 1)