UNetとLSTMの組み合わせでのエラー(Graph disconnected: cannot obtain value for tensor Tensor)
Kerasを用いて、UNetとLSTMを組み合わせたモデルを作成しようとしております
(LSTMへの入力は時系列画像を畳み込んだベクトルとし、LSTMから出力される時系列の
隠れ状態ベクトルに転置畳み込みを実行して再び画像に戻す)。
その際に以下のようなエラーが出てしまいます。
原因や解決方法をご教示いただきたいです。
発生している問題・エラーメッセージ
ValueError: Graph disconnected: cannot obtain value for tensor Tensor("first:0", shape=(?, 256, 256, 3), dtype=float32) at layer "first". The following previous layers were accessed without issue: []
該当のソースコード
【追記】後者のソースコードがmodel.pyで、
前者のソースコードを実行しています。
python
1mport numpy as np 2from models import * 3from keras.optimizers import Adam 4 5frames = 20 6height = 256 7width = 256 8in_channels = 3 9out_channels = 3 10dropout_rate = 0.0 11optimizer = Adam(lr=0.0002, beta_1=0.5, beta_2=0.999) 12 13UNet_LSTM = UNet_LSTM(frames, height, width, in_channels, out_channels, dropout_rate) 14 15all = UNet_LSTM.build_all() 16all.compile(loss='binary_crossentropy', optimizer=optimizer) 17all.summary()
python
1from keras.layers.advanced_activations import LeakyReLU 2from keras.layers.convolutional import Conv2D, UpSampling2D 3from keras_contrib.layers.normalization.instancenormalization import InstanceNormalization 4from keras.layers import Input, Dropout, ReLU, Concatenate, Reshape, CuDNNLSTM 5from keras.layers.wrappers import TimeDistributed 6from keras.initializers import glorot_normal 7from keras.models import Model 8 9class UNet_LSTM(): 10 def __init__(self, frames, height, width, in_channels, out_channels, dropout_rate): 11 self.frames = frames 12 self.height = height 13 self.width = width 14 self.in_channels = in_channels 15 self.out_channels = out_channels 16 self.input_imgs_shape = (self.frames, self.height, self.width, self.in_channels) 17 self.output_imgs_shape = (self.frames, self.height, self.width, self.out_channels) 18 self.input_img_shape = (self.height, self.width, self.in_channels) 19 self.output_img_shape = (self.height, self.width, self.out_channels) 20 self.dropout_rate = dropout_rate 21 22 def build_all(self): 23 """U-Net+LSTM""" 24 input_imgs = Input(shape=self.input_imgs_shape, name='all') 25 first = self.build_first() 26 encoded_frames = TimeDistributed(first)(input_imgs) 27 28 length_of_sequences = encoded_frames.shape[1].value 29 latent_dim = encoded_frames.shape[-1].value 30 encoded_frames = Reshape((length_of_sequences, latent_dim))(encoded_frames) 31 32 latent_vector = self.build_LSTM(length_of_sequences, latent_dim)(encoded_frames) 33 latent_vector = Reshape((length_of_sequences, 1, 1, latent_dim))(latent_vector) 34# return Model(input_imgs, latent_vector) 35 36 latter = self.build_latter(latent_dim) 37 output_imgs = TimeDistributed(latter)(latent_vector) 38 return Model(input_imgs, output_imgs) 39 40 def build_first(self): 41 #Image input 42 d0 = Input(shape=self.input_img_shape, name='first') 43 44 # Downsampling 45 self.d1 = self.conv2d(layer_input=d0, filters=64, f_size=4, 46 normalization=False, alpha=0.2, dropout_rate=0) 47 self.d2 = self.conv2d(layer_input=self.d1, filters=128, f_size=4, 48 normalization=True, alpha=0.2, dropout_rate=0) 49 self.d3 = self.conv2d(layer_input=self.d2, filters=256, f_size=4, 50 normalization=True, alpha=0.2, dropout_rate=0) 51 self.d4 = self.conv2d(layer_input=self.d3, filters=512, f_size=4, 52 normalization=True, alpha=0.2, dropout_rate=self.dropout_rate) 53 self.d5 = self.conv2d(layer_input=self.d4, filters=512, f_size=4, 54 normalization=True, alpha=0.2, dropout_rate=self.dropout_rate) 55 self.d6 = self.conv2d(layer_input=self.d5, filters=512, f_size=4, 56 normalization=True, alpha=0.2, dropout_rate=self.dropout_rate) 57 self.d7 = self.conv2d(layer_input=self.d6, filters=512, f_size=4, 58 normalization=True, alpha=0.2, dropout_rate=self.dropout_rate) 59 d8 = self.conv2d(layer_input=self.d7, filters=512, f_size=4, 60 normalization=False, alpha=0.2, dropout_rate=self.dropout_rate) 61 62 return Model(d0, d8) 63 64 def build_LSTM(self, length_of_sequences, latent_dim): 65 x = Input(shape=(length_of_sequences, latent_dim, ), name='LSTM') 66 # LSTM 67 y = CuDNNLSTM(latent_dim, batch_input_shape=(None, length_of_sequences, latent_dim), 68 kernel_initializer=glorot_normal(seed=1), 69 return_sequences=True, stateful=False)(x) 70 return Model(x, y) 71 72 def build_latter(self, latent_dim): 73 # Latent vector input 74 z = Input(shape=(1, 1, latent_dim), name='latter') 75 76 # Upsampling 77 u1 = self.deconv2d(layer_input=z, skip_input=self.d7, filters=512, 78 f_size=4, dropout_rate=self.dropout_rate) 79 u2 = self.deconv2d(layer_input=u1, skip_input=self.d6, filters=512, 80 f_size=4, dropout_rate=self.dropout_rate) 81 u3 = self.deconv2d(layer_input=u2, skip_input=self.d5, filters=512, 82 f_size=4, dropout_rate=self.dropout_rate) 83 u4 = self.deconv2d(layer_input=u3, skip_input=self.d4, filters=512, 84 f_size=4, dropout_rate=self.dropout_rate) 85 u5 = self.deconv2d(layer_input=u4, skip_input=self.d3, filters=256, 86 f_size=4, dropout_rate=0) 87 u6 = self.deconv2d(layer_input=u5, skip_input=self.d2, filters=128, 88 f_size=4, dropout_rate=0) 89 u7 = self.deconv2d(layer_input=u6, skip_input=self.d1, filters=64, 90 f_size=4, dropout_rate=0) 91 92 u8 = UpSampling2D(size=2)(u7) 93 output_img = Conv2D(self.out_channels, kernel_size=4, strides=1, 94 padding='same', activation='tanh')(u8) 95 print('output_img.shape= ', output_img.shape) 96 return Model(z, output_img) 97 98 @staticmethod 99 def conv2d(layer_input, filters, f_size=4, 100 normalization=True, alpha=0.2, dropout_rate=0): 101 # layer_input: input to this layer (figure or feather map) 102 # filters: Number of channels 103 # f_size: kernel size 104 # normalization: impliment the Instance Normalization if True 105 # alpha: parameter of LeakyReLU (gradient in x < 0) 106 # dropout_rate: dropout ratio (0-1) 107 # convolution===>(normalization===>)activation===>(dropout===>) 108 d = Conv2D(filters, kernel_size=f_size, strides=2, padding='same')(layer_input) 109 if normalization: 110 d = InstanceNormalization()(d) 111 d = LeakyReLU(alpha=alpha)(d) 112 if dropout_rate: 113 d = Dropout(dropout_rate)(d) 114 115 return d 116 117 @staticmethod 118 def deconv2d(layer_input, skip_input, filters, 119 f_size=4, dropout_rate=0): 120 # layer_input: input to this layer (figure or feather map) 121 # skip_input: input from skip-connection 122 # filters: Number of channels 123 # f_size: kernel size 124 # dropout_rate: dropout ratio (0-1) 125 # transpose convolution===>normalization===>activation===>(dropout===>) 126 u = UpSampling2D(size=2)(layer_input) 127 u = Conv2D(filters, kernel_size=f_size, strides=1, padding='same')(u) 128 u = InstanceNormalization()(u) 129 u = ReLU()(u) 130 if dropout_rate: 131 u = Dropout(dropout_rate)(u) 132 print('u.shape= ',u.shape) 133 print('skip_input.shape= ', skip_input.shape) 134 u = Concatenate()([u, skip_input]) 135 return u 136
試したこと
input層の入力データの形に関するエラーのようなので、
print文にて様々な場所でデータの形を出力してみました。
結果としては、自分が意図した通りの形になっていました。
input_imgs.shape= (?, 20, 256, 256, 3) self.d7.shape= (?, 2, 2, 512) encoded_frames.shape= (?, 20, 1, 1, 512) encoded_frames.shape= (?, 20, 512) latent_vector.shape= (?, 20, 512) latent_vector.shape= (?, 20, 1, 1, 512) u.shape= (?, 2, 2, 512) skip_input.shape= (?, 2, 2, 512) u.shape= (?, 4, 4, 512) skip_input.shape= (?, 4, 4, 512) u.shape= (?, 8, 8, 512) skip_input.shape= (?, 8, 8, 512) u.shape= (?, 16, 16, 512) skip_input.shape= (?, 16, 16, 512) u.shape= (?, 32, 32, 256) skip_input.shape= (?, 32, 32, 256) u.shape= (?, 64, 64, 128) skip_input.shape= (?, 64, 64, 128) u.shape= (?, 128, 128, 64) skip_input.shape= (?, 128, 128, 64) output_img.shape= (?, 256, 256, 3)
LSTMまで、つまりコメントアウトしているreturn Model(input_imgs, latent_vector)まで
であればエラーは出ず、モデルのsummary情報が出ます。
Model: "model_3" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= all (InputLayer) (None, 20, 256, 256, 3) 0 _________________________________________________________________ time_distributed_1 (TimeDist (None, 20, 1, 1, 512) 19535820 _________________________________________________________________ reshape_1 (Reshape) (None, 20, 512) 0 _________________________________________________________________ model_2 (Model) (None, 20, 512) 2101248 _________________________________________________________________ reshape_2 (Reshape) (None, 20, 1, 1, 512) 0 =================================================================
UNetの後半部分を足すとエラーが出てしまいます。
また、エラーが出るのが
Tensor("first:0", shape=(?, 256, 256, 3), dtype=float32) at layer "first"
にあるようにUNetの前半部分の入力層("first")であるのが理解できず、
試行錯誤したのですが解決できませんでした。
是非ともお力をお借りしたく、どうぞよろしくお願いします。
あなたの回答
tips
プレビュー