I use this hypermodel:
class MyHyperModel(HyperModel):
def build(self, hp):
input_shape = (2, None, 1)
activation = "relu"
arc = hp.Choice("arc", values=["common", "res", "att", "att_res"])
dropout_rate = hp.Float("dropout rate", 0, 0.15)
nb_blocks = hp.Int("nb_blocks", 2, 7)
optimizer = hp.Choice("optimizer", values=["RMSprop", "adam"])
batch_norm = hp.Choice("batch_norm", values=[False, True])
pooling = hp.Choice("pooling", values=["GAP", "GSP", "SPP", "GMP"])
dense_list = []
with hp.conditional_scope("pooling", ["SPP"]):
if pooling == "SPP":
dense_depth = hp.Int("dense_depth", 1, 4)
for i in range(dense_depth):
dense_units = hp.Choice(f"dense_units_d{i}", values=[4, 8, 16, 32])
dense_list.append(dense_units)
# specify kernel size fo reach block
kernel_list = []
filter_list=[]
with hp.conditional_scope("nb_blocks", [2]):
if nb_blocks > 1:
kernel_x = hp.Int(f"kernel_x_b1", 1, 10)
kernel_y = hp.Int(f"kernel_y_b1", 1, 2)
kernel_list.append((kernel_y, kernel_x))
kernel_x = hp.Int(f"kernel_x_b2", 1, 10)
kernel_y = hp.Int(f"kernel_y_b2", 1, 2)
kernel_list.append((kernel_y, kernel_x))
filters_per_block = hp.Choice(f"filters_for_block_1", values= [32, 64, 128, 256])
filter_list.append(filters_per_block)
filters_per_block = hp.Choice(f"filters_for_block_2", values= [32, 64, 128, 256])
filter_list.append(filters_per_block)
with hp.conditional_scope("nb_blocks", [3]):
if nb_blocks > 2:
kernel_x = hp.Int(f"kernel_x_b3", 1, 10)
kernel_y = hp.Int(f"kernel_y_b3", 1, 2)
kernel_list.append((kernel_y, kernel_x))
filters_per_block = hp.Choice(f"filters_for_block_3", values= [32, 64, 128, 256])
filter_list.append(filters_per_block)
with hp.conditional_scope("nb_blocks", [4]):
if nb_blocks > 3:
kernel_x = hp.Int(f"kernel_x_b4", 1, 10)
kernel_y = hp.Int(f"kernel_y_b4", 1, 2)
kernel_list.append((kernel_y, kernel_x))
filters_per_block = hp.Choice(f"filters_for_block_4", values= [32, 64, 128, 256])
filter_list.append(filters_per_block)
with hp.conditional_scope("nb_blocks", [5]):
if nb_blocks > 4:
kernel_x = hp.Int(f"kernel_x_b5", 1, 10)
kernel_y = hp.Int(f"kernel_y_b5", 1, 2)
kernel_list.append((kernel_y, kernel_x))
filters_per_block = hp.Choice(f"filters_for_block_5", values= [32, 64, 128, 256])
filter_list.append(filters_per_block)
with hp.conditional_scope("nb_blocks", [6]):
if nb_blocks > 5:
kernel_x = hp.Int(f"kernel_x_b6", 1, 10)
kernel_y = hp.Int(f"kernel_y_b6", 1, 2)
kernel_list.append((kernel_y, kernel_x))
filters_per_block = hp.Choice(f"filters_for_block_6", values= [32, 64, 128, 256])
filter_list.append(filters_per_block)
with hp.conditional_scope("nb_blocks", [7]):
if nb_blocks > 6:
kernel_x = hp.Int(f"kernel_x_b7", 1, 10)
kernel_y = hp.Int(f"kernel_y_b7", 1, 2)
kernel_list.append((kernel_y, kernel_x))
filters_per_block = hp.Choice(f"filters_for_block_7", values= [32, 64, 128, 256])
filter_list.append(filters_per_block)
print(arc,dropout_rate, nb_blocks, optimizer, batch_norm, pooling, dense_list, kernel_list, filter_list)
# build model based on hp
# define INput
input_layer = Input(shape=input_shape, name="Input")
x=input_layer
# choose convolutinal architecture
with hp.conditional_scope("arc", ["common"]):
if arc == "common":
for i, filters in enumerate(filter_list):
conv = conv_block(x, filters, (kernel_list[i][0], kernel_list[i][1]), dropout=dropout_rate, batch_norm=batch_norm, activation = "relu")
x = conv
with hp.conditional_scope("arc", ["res"]):
if arc == "res":
for i, filters in enumerate(filter_list):
conv = res_conv_block(x, filters, kernel_list[i], dropout=dropout_rate, batch_norm=batch_norm, activation = "relu")
x = conv
with hp.conditional_scope("arc", ["att"]):
if arc == "att":
for i, filters in enumerate(filter_list):
conv1 = conv_block(x, filters, kernel_list[i], dropout=dropout_rate, batch_norm=batch_norm, activation = "relu")
conv2 = conv_block(conv1, filters, kernel_list[i], dropout=dropout_rate, batch_norm=batch_norm, activation = "relu")
att = attention_block(conv2, conv1, filters)
x = att
with hp.conditional_scope("arc", ["att_res"]):
if arc == "att_res":
for i, filters in enumerate(filter_list):
conv1 = res_conv_block(x, filters, kernel_list[i], dropout=dropout_rate, batch_norm=batch_norm, activation = "relu")
conv2 = res_conv_block(conv1, filters, kernel_list[i], dropout=dropout_rate, batch_norm=batch_norm, activation = "relu")
att = attention_block(conv2, conv1, filters)
conv3 = conv_block(att, filters, kernel_list[i], dropout=dropout_rate, batch_norm=batch_norm, activation = "relu")
x = conv3
# add pooling method to achieve fixed size unrelated to input size
if pooling == "GAP":
gate = Conv2D(1, (1, 1), padding='same')(x)
GAP = GlobalAveragePooling2D()(gate)
x = GAP
if pooling == "SPP":
spp_layer = SpatialPyramidPooling2D([[2, 2], [1, 2],[1, 1]], name="SPP")(x)
flatten = Flatten()(spp_layer)
x=flatten
if pooling == "GSP":
gate = Conv2D(1, (1, 1), padding='same')(x)
GSP = Lambda(sum_pooling)(gate)
x=GSP
if pooling == "GMP":
gate = Conv2D(1, (1, 1), padding='same')(x)
GMP = GlobalMinPool2D()(gate)
x=GMP
# add dense layers if required
if pooling == "SPP":
for i, units in enumerate(dense_list):
dense = Dense(units, activation=activation)(x)
drop = Dropout(dropout_rate)(dense)
x = drop
x = Dense(1, activation="relu")(x)
# create model
model = Model(inputs=input_layer, outputs=x)
# model.summary()
model.compile(optimizer=optimizer, loss="mape", metrics=['mse', "mape"])
return model
I intentionally don't use a loop for the kernel_sizes, so the optimizer knows which parameters are used and which not.
I would expect it to build the model, however I get an Error:
The optimizer manages to build the first two models but the third model is not built, due to the None values in the lists.
However I don't understand why these are there in the first place.
This is the output print I used in the Hypermodel:
common 0.0 2 RMSprop 0 GAP [] [(1, 1), (1, 1)] [32, 32]
common 0.0 2 RMSprop 0 SPP [4] [(1, 1), (1, 1)] [32, 32]
common 0.0 3 RMSprop 0 GAP [] [(1, 1), (1, 1), (1, 1), (None, None), (None, None), (None, None), (None, None)] [32, 32, 32, None, None, None, None]
---------------------------------------------------------------------------
This is the Error:
TypeError Traceback (most recent call last)
D:\Programme\Python\envs\gpuTEST\lib\site-packages\keras\utils\conv_utils.py in normalize_tuple(value, n, name, allow_zero)
85 try:
---> 86 int(single_value)
87 except (ValueError, TypeError):
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'
During handling of the above exception, another exception occurred:
~\AppData\Local\Temp\ipykernel_18156\3375396705.py in build(self, hp)
155 if arc == "common":
156 for i, filters in enumerate(filter_list):
--> 157 conv = conv_block(x, filters, (kernel_list[i][0], kernel_list[i][1]), dropout=dropout_rate, batch_norm=batch_norm, activation = "relu")
158 x = conv
159 with hp.conditional_scope("arc", ["res"]):
ValueError: The `kernel_size` argument must be a tuple of 2 integers. Received: (None, None)including element None of type <class 'NoneType'>