在以下代碼片段中 -
class ResnetIdentityBlock(tf.keras.Model):
def __init__(self, kernel_size, filters):
super(ResnetIdentityBlock, self).__init__(name='')
filters1, filters2, filters3 = filters
self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))
self.bn2a = tf.keras.layers.BatchNormalization()
self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')
self.bn2b = tf.keras.layers.BatchNormalization()
self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))
self.bn2c = tf.keras.layers.BatchNormalization()
def call(self, input_tensor, training=False):
x = self.conv2a(input_tensor)
x = self.bn2a(x, training=training)
x = tf.nn.relu(x)
x = self.conv2b(x)
x = self.bn2b(x, training=training)
x = tf.nn.relu(x)
x = self.conv2c(x)
x = self.bn2c(x, training=training)
x = input_tensor
return tf.nn.relu(x)
block = ResnetIdentityBlock(1, [1, 2, 3])
如果我說 100 層,誰能告訴我 call() 中的語法是什么樣的?我的意思是我不會將第一層復制粘貼 100 次然后更改一些東西(就像他們在 call 方法中所做的那樣)。我認為這將是某種 for 回圈,但我想確切地知道。
uj5u.com熱心網友回復:
實際上,您通常將resnet塊用作較大模型的一部分。通常,您會n像這樣創建多個塊:
import tensorflow as tf
class ResnetIdentityBlock(tf.keras.Model):
def __init__(self, kernel_size, filters):
super(ResnetIdentityBlock, self).__init__(name='')
filters1, filters2, filters3 = filters
self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))
self.bn2a = tf.keras.layers.BatchNormalization()
self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')
self.bn2b = tf.keras.layers.BatchNormalization()
self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))
self.bn2c = tf.keras.layers.BatchNormalization()
def call(self, input_tensor, training=False):
x = self.conv2a(input_tensor)
x = self.bn2a(x, training=training)
x = tf.nn.relu(x)
x = self.conv2b(x)
x = self.bn2b(x, training=training)
x = tf.nn.relu(x)
x = self.conv2c(x)
x = self.bn2c(x, training=training)
x = input_tensor
return tf.nn.relu(x)
inputs = tf.keras.layers.Input(shape=(180, 180, 3))
x = tf.keras.layers.Conv2D(filters=64, kernel_size=9, strides=1, padding="same")(inputs)
current_model = x
for i in range(4):
block = ResnetIdentityBlock(1, [1, 2, 64])
block._name = 'resblock' str(i)
x = block(x)
x = tf.keras.layers.Conv2D(filters=64, kernel_size=3, strides=1, padding="same")(x)
x = tf.keras.layers.BatchNormalization(momentum=0.5)(x)
output = tf.keras.layers.Add()([current_model, x])
model = tf.keras.Model(inputs, output)
print(model.summary())
print(model(tf.random.normal((1, 180, 180, 3))).shape)
Model: "model_6"
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
input_14 (InputLayer) [(None, 180, 180, 3 0 []
)]
conv2d_75 (Conv2D) (None, 180, 180, 64 15616 ['input_14[0][0]']
)
resblock0 (ResnetIdentityBlock (None, 180, 180, 64 529 ['conv2d_75[0][0]']
) )
resblock1 (ResnetIdentityBlock (None, 180, 180, 64 529 ['resblock0[0][0]']
) )
resblock2 (ResnetIdentityBlock (None, 180, 180, 64 529 ['resblock1[0][0]']
) )
resblock3 (ResnetIdentityBlock (None, 180, 180, 64 529 ['resblock2[0][0]']
) )
conv2d_88 (Conv2D) (None, 180, 180, 64 36928 ['resblock3[0][0]']
)
batch_normalization_69 (BatchN (None, 180, 180, 64 256 ['conv2d_88[0][0]']
ormalization) )
add_6 (Add) (None, 180, 180, 64 0 ['conv2d_75[0][0]',
) 'batch_normalization_69[0][0]']
==================================================================================================
Total params: 54,916
Trainable params: 54,252
Non-trainable params: 664
__________________________________________________________________________________________________
None
(1, 180, 180, 64)
uj5u.com熱心網友回復:
首先,您必須繼承 fromtf.keras.layers.Layer來定義您的自定義層,而不是 from tf.keras.Model。
然后,您使用串列理解創建一個包含 100 多個殘差層的模型。
例子:
定義層:類 ResnetIdentityBlock(tf.keras.layers.Layer): def init (self, kernel_size, filters): super(ResnetIdentityBlock, self)。初始化(名稱='')過濾器1,過濾器2,過濾器3 =過濾器
self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))
self.bn2a = tf.keras.layers.BatchNormalization()
self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')
self.bn2b = tf.keras.layers.BatchNormalization()
self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))
self.bn2c = tf.keras.layers.BatchNormalization()
def call(self, input_tensor, training=False):
x = self.conv2a(input_tensor)
x = self.bn2a(x, training=training)
x = tf.nn.relu(x)
x = self.conv2b(x)
x = self.bn2b(x, training=training)
x = tf.nn.relu(x)
x = self.conv2c(x)
x = self.bn2c(x, training=training)
x = input_tensor
return tf.nn.relu(x)
定義模型:
class ResnetCustomModel(tf.keras.Model):
def __init__(self, num_layers, kernel_size, filters):
super(ResnetCustomModel, self).__init__(name='')
# list comprehension to define 100 layers
self.res_blocks = [ResnetIdentityBlock(kernel_size = kernel_size, filters= filters) for _ in range(num_layers)]
def call(self, input_tensor, training=False):
x = input_tensor
for layer in self.res_blocks:
x = layer(x)
return x
構建模型和視圖摘要:
model = ResnetCustomModel(num_layers = 100, kernel_size = 3, filters= (32,32,32))
model.build((1,512,512,32))
model.summary()
為了使您的模型獨立于輸入形狀,您可以撰寫自己的構建方法并self.res_blocks根據輸入形狀進行定義。
對于更多示例,在我的 Github存盤庫DeepSaki中,我還實作了一個殘差層并將其用于類似ResNet的架構中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/422912.html
標籤:
