1

我正在尝试从存储库运行转换后的模型:https ://github.com/HasnainRaz/Fast-SRGAN 。嗯,转换成功了。但是当我尝试初始化模型时,我看到了错误:"Unknown layer: TensorFlowOpLayer.". 如果我们调查保存的模型,我们可以看到 TensorFlowOpLayer:

模型结构

据我了解,这是代码的和平:

keras.layers.UpSampling2D(size=2, interpolation='bilinear')(layer_input).

我决定编写自己的课程“TensorFlowOpLayer”。

import * as tf from '@tensorflow/tfjs';

 export class TensorFlowOpLayer extends tf.layers.Layer {
    constructor() {
        super({});
    }

    computeOutputShape(shape: Array<number>) {
        return [1, null, null, 32];
    }

    call(input_3): tf.Tensor {
        const result = tf.layers.upSampling2d({ size: [2, 2], dataFormat: 'channelsLast', interpolation: 'bilinear' }).apply(input_3) as tf.Tensor;
        return result;
    }

    static get className() {
        return 'TensorFlowOpLayer';
    }
}

但它不起作用。有人可以帮助我了解如何写入方法“computeOutputShape”吗?第二个误解,为什么在上图中我们看到了下一层的顺序:

    Conv2D -> TensorFlowOpLayer -> PReLU

据我了解,TensorFlowOpLayer 层是python 代码中的“UpSampling2D” 。H5模型是通过网站调查的:https ://netron.app

u = keras.layers.UpSampling2D(size=2, interpolation='bilinear')(layer_input)
u = keras.layers.Conv2D(self.gf, kernel_size=3, strides=1, padding='same')(u)
u = keras.layers.PReLU(shared_axes=[1, 2])(u)

TS中模型的初始化:

  async loadModel() {
    this.model = await tf.loadLayersModel('/assets/fast_srgan/model.json');
    const inputs = tf.layers.input({shape: [null, null, 32]});
    const outputs = this.model.apply(inputs) as tf.SymbolicTensor;
    this.model = tf.model({inputs: inputs, outputs: outputs});

    console.log("Model has been loaded");
  }

就像在python代码中一样:

from tensorflow import keras

# Load the model
model = keras.models.load_model('models/generator.h5')

# Define arbitrary spatial dims, and 3 channels.
inputs = keras.Input((None, None, 3))

# Trace out the graph using the input:
outputs = model(inputs)

# Override the model:
model = keras.models.Model(inputs, outputs)

然后,它是如何使用的:

    tf.tidy(() => {
      let img = tf.browser.fromPixels(this.imgLr.nativeElement, 3);
      img = tf.div(img, 255.0);
      img = tf.image.resizeNearestNeighbor(img, [96, 96]);
      img = tf.expandDims(img, 0);
      let sr = this.model.predict(img) as tf.Tensor;

    });

就像在python代码中一样:

def predict(img):
    # Rescale to 0-1.
    lr = tf.math.divide(img, 255)

    # Get super resolution image
    sr = model.predict(tf.expand_dims(lr, axis=0))

    return sr[0]

当我添加自己的类“TensorFlowOpLayer”时,我看到了下一个错误:
"expected input1 to have shape [null,null,null,32] but got array with shape [1,96,96,3]."

4

1 回答 1

0

解决了这个问题。该问题与代码版本和保存的模型有关。代码作者对代码进行了重构,并没有更改保存的模型。我重写了所需的类:

import * as tf from '@tensorflow/tfjs';

 export class DepthToSpace extends tf.layers.Layer {
    constructor() {
        super({});
    }

    computeOutputShape(shape: Array<number>) {
        return [null, ...shape.slice(1, 3).map(x => x * 2), 32];
    }

    call(input): tf.Tensor {
        input = input[0];
        const result = tf.depthToSpace(input, 2);
        return result;
    }

    static get className() {
        return 'TensorFlowOpLayer';
    }
}

它有效。

作者的原始代码是:

 u = keras.layers.Conv2D(filters, kernel_size=3, strides=1, padding='same')(layer_input)
 u = tf.nn.depth_to_space(u, 2)
 u = keras.layers.PReLU(shared_axes=[1, 2])(u)
于 2020-12-19T23:41:35.033 回答