Coverage for source/model/model_blue_prints/vggception_cnn_blue_print.py: 100%

39 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-30 15:13 +0000

1# model/model_blue_prints/basic_cnn_blue_print.py 

2 

3from tensorflow.keras import Model, layers 

4import math 

5 

6from .base_blue_print import BaseBluePrint 

7from ..model_building_blocks.vgg16_block import Vgg16Block 

8from ..model_building_blocks.xception_block import XceptionBlock 

9 

10class VGGceptionCnnBluePrint(BaseBluePrint): 

11 """ 

12 Blueprint for creating a hybrid CNN architecture combining VGG and Xception patterns. 

13 

14 This class implements a model blueprint that constructs a neural network with a 

15 combined architecture inspired by VGG16 and Xception networks. It's designed to 

16 process both spatial and non-spatial features by separating the input vector 

17 and processing them through different network components before combining them. 

18 """ 

19 

20 def instantiate_model(self, input_shape: tuple[int, int], output_length: int, spatial_data_shape: tuple[int, int], 

21 number_of_filters: int = 32, cnn_squeezing_coeff: int = 2, dense_squeezing_coeff: int = 2, 

22 dense_repetition_coeff: int = 1, filters_number_coeff: int = 2) -> Model: 

23 """ 

24 Creates and returns a hybrid VGG-Xception CNN model according to specified parameters. 

25 

26 The method constructs a neural network that: 

27 1. Separates the input into spatial and non-spatial components 

28 2. Processes the spatial data through VGG16 and Xception blocks 

29 3. Flattens the CNN output and concatenates with non-spatial features 

30 4. Passes the combined features through a series of dense layers 

31 5. Produces a softmax output for classification 

32 

33 Parameters: 

34 input_shape (tuple[int, int]): Shape of the input tensor 

35 output_length (int): Number of output classes/actions 

36 spatial_data_shape (tuple[int, int]): Rows and columns to reshape spatial data 

37 number_of_filters (int): Initial number of convolutional filters 

38 cnn_squeezing_coeff (int): Factor by which CNN dimensions are reduced 

39 dense_squeezing_coeff (int): Factor by which dense layer sizes are reduced 

40 dense_repetition_coeff (int): Number of dense layers of the same size to use 

41 filters_number_coeff (int): Factor by which filter count increases in convolutional layers 

42 

43 Returns: 

44 Model: Keras model implementing the hybrid VGG-Xception architecture to be compiled further. 

45 """ 

46 

47 spatial_data_rows, spatial_data_cols = spatial_data_shape 

48 spatial_data_length = spatial_data_rows * spatial_data_cols 

49 

50 input_vector = layers.Input((1, input_shape[0])) 

51 reshaped_input_vector = layers.Reshape((input_shape[0],))(input_vector) 

52 spatial_part = layers.Lambda(lambda x: x[:, :spatial_data_length])(reshaped_input_vector) 

53 non_spatial_part = layers.Lambda(lambda x: x[:, spatial_data_length:])(reshaped_input_vector) 

54 reshaped_spatial_part = layers.Reshape((spatial_data_rows, spatial_data_cols, 1))(spatial_part) 

55 

56 cnn_part = Vgg16Block([(3, 1), (3, 1), (2, 1)], 

57 [number_of_filters, number_of_filters])(reshaped_spatial_part) 

58 cnn_part = layers.BatchNormalization()(cnn_part) 

59 

60 nr_of_xceptions_blocks = int(math.ceil(math.log(spatial_data_rows // 2, cnn_squeezing_coeff))) 

61 for _ in range(nr_of_xceptions_blocks): 

62 number_of_filters *= filters_number_coeff 

63 cnn_part = XceptionBlock([(3, 1), (3, 1), (3, 1), (1, 1)], 

64 [number_of_filters, number_of_filters, number_of_filters], 

65 [(cnn_squeezing_coeff, 1), (cnn_squeezing_coeff, 1)])(cnn_part) 

66 cnn_part = layers.BatchNormalization()(cnn_part) 

67 

68 flatten_cnn_part = layers.Flatten()(cnn_part) 

69 concatenated_parts = layers.Concatenate()([flatten_cnn_part, non_spatial_part]) 

70 

71 closest_smaller_power_of_coeff = int(math.pow(dense_squeezing_coeff, 

72 int(math.log(concatenated_parts.shape[-1], 

73 dense_squeezing_coeff)))) 

74 dense = layers.Dense(closest_smaller_power_of_coeff, activation='relu')(concatenated_parts) 

75 dense = layers.BatchNormalization()(dense) 

76 

77 number_of_nodes = closest_smaller_power_of_coeff // dense_squeezing_coeff 

78 nr_of_dense_layers = int(math.log(closest_smaller_power_of_coeff, dense_squeezing_coeff)) 

79 for _ in range(nr_of_dense_layers): 

80 for _ in range(dense_repetition_coeff): 

81 dense = layers.Dense(number_of_nodes, activation='relu')(dense) 

82 dense = layers.BatchNormalization()(dense) 

83 number_of_nodes //= dense_squeezing_coeff 

84 if int(math.log(number_of_nodes, 10)) == int(math.log(output_length, 10)) + 1: 

85 dense = layers.Dropout(0.3)(dense) 

86 elif int(math.log(number_of_nodes, 10)) == int(math.log(output_length, 10)): 

87 break 

88 

89 output = layers.Dense(output_length, activation='softmax')(dense) 

90 

91 return Model(inputs=input_vector, outputs=output)