tensorflow / kerasのカーネルの事前定義されたリストでConv2Dレイヤーを初期化する方法は?

2020-06-30 python tensorflow keras convolution

入力画像をストライドして3つの2x2カーネルを実行するために、 Conv2Dレイヤーを使用したいと思います。

これはテンソルフローの目的ではありませんが、カーネルを効率的に実行し、異なるデバイスのGPUやCPU間で作業負荷を分散するためのバックエンドエンジンとしてテンソルフローを実際に使用したいと考えています。

次のようなコードを試しました。しかし、それは非常にうまく機能していないようです。

import tensorflow as tf

class InitConvKernels(tf.keras.initializers.Initializer):

  def __init__(self, num_kernels, kernel_tensor):
    self.kernel_list= kernel_tensor
    self.index = -1
    self.num_kernels = num_kernels

  def __call__(self, shape, dtype=None):
    index += 1 
    assert(self.index <= self.num_kernels) # doesn't affect anything
    tf.print(shape) # doesn't work
    return self.kernel_list[index]

  def get_config(self):
    return {'kernel_list': self.kernel_list, 'num_kernels': self.num_kernels}

カスタム初期化子を呼び出していますが、返されたレイヤーは空です:

kernel_list = tf.constant([[[-1, -1],  [-1, -1]], [[1, 1],   [1, 1]],  [[-1, 1],  [1, -1]],])
layer = layers.Conv2D(
    filters=3,
    kernel_size=2,
    kernel_initializer=InitConvKernels(3,kernel_list),
    bias_initializer=initializers.Zeros()
)

layer.variablesは空です( []layer.layer.get_weights()も空です( []

私の目標は、入力画像のkernel_listにある3つのカーネルの畳み込みを評価し、すべての結果を集計することです。

Answers

from PIL import Image
import requests
from io import BytesIO
import numpy as np
from keras.models import Sequential
from keras.layers import Conv2D


response = requests.get('https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/Stack_Overflow_logo.svg/1280px-Stack_Overflow_logo.svg.png')
image = Image.open(BytesIO(response.content))

Loading an image from url. enter image description here

Build a model to run a kernel (to run more kernels make kernel_init a generator and readily adjust the number of filters when initializing Conv2D)

def kernel_init(shape, dtype=None, partition_info=None):
    kernel = np.zeros(shape)
    kernel[:,:,0,0] = np.array([[1,0,1],[-1,0,-1],[1,0,1]])
    return kernel

#Build Keras model
model = Sequential()
model.add(Conv2D(1, [3,3], kernel_initializer=kernel_init, 
                 input_shape=(251,1280,4), padding="valid"))
model.build()

# To apply existing filter, we use predict with no training
out = model.predict(image)

And visualizing the output:

import matplotlib.pyplot as plt
plt.matshow(out[0,:,:,0])

enter image description here

Related