Please take a look at the following source codes:
training.py
import tensorflow as tf
from typing import Tuple
from keras import Sequential
from keras.src.layers import Conv1D, MaxPooling1D, Flatten, Dense, TimeDistributed
from src.cnn_lib.get_data3d import getTensor3d, splitTrainValidTest, splitFeaturesLabels
from src.cnn_lib.get_root_dir import getRootDirectory
def getCnnModel(input_shape: Tuple[int, int], num_classes: int) -> tf.keras.Model:
model = tf.keras.models.Sequential([
tf.keras.layers.Conv1D(64, 3, activation='relu', padding='same', input_shape=input_shape),
tf.keras.layers.Conv1D(128, 3, activation='relu', padding='same'),
tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(256, activation='relu')),
tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(128, activation='relu')),
tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(num_classes, activation='softmax'))
])
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
return model
if __name__ == "__main__":
tensor_3d = getTensor3d(getRootDirectory() + "\\data")
train3d, valid3d, _ = splitTrainValidTest(tensor_3d, trainPercent=0.6, validPercent=.3)
x_train, y_train = splitFeaturesLabels(train3d, num_features=8)
x_valid, y_valid = splitFeaturesLabels(valid3d, num_features=8)
print('Training image shape:', x_train.shape) # (4, 10, 8)
print('Training labels shape:', y_train.shape) # (4, 10, 3)
print('Testing image shape:', x_valid.shape) # (2, 10, 8)
print('Testing labels shape:', y_valid.shape) # (2, 10, 3)
# Fit the model to the data
model = getCnnModel((10,8), num_classes=3)
model.fit(x_train, y_train, validation_data=(x_valid, y_valid), epochs=10)
model_search.py
# AutoKeras CNN model search source code
# Import required libraries
import autokeras as ak
import tensorflow as tf
from src.cnn_lib.get_data3d import getTensor3d, splitTrainValidTest, splitFeaturesLabels
from src.cnn_lib.get_root_dir import getRootDirectory
# Load the dataset
tensor_3d: tf.Tensor = getTensor3d(getRootDirectory() + "\\data")
train3d, valid3d, test3d = splitTrainValidTest(tensor_3d, trainPercent=0.6, validPercent=.3) # tf.Tensor, tf.Tensor , tf.Tensor
# Split the dataset
x_train, y_train = splitFeaturesLabels(train3d, num_features=8)# tf.Tensor, tf.Tensor
x_valid, y_valid = splitFeaturesLabels(valid3d, num_features=8)# tf.Tensor, tf.Tensor
x_test, y_test = splitFeaturesLabels(test3d, num_features=8)# tf.Tensor, tf.Tensor
# Convert Tensors to Numpy Arrays
x_train = x_train.numpy()
y_train = y_train.numpy()
x_test = x_test.numpy()
y_test = y_test.numpy()
print('Training image shape:', x_train.shape) # (4, 10, 8)
print('Training labels shape:', y_train.shape) # (4, 10, 3)
print('Testing image shape:', x_test.shape) # (2, 10, 8)
print('Testing labels shape:', y_test.shape) # (2, 10, 3)
# Reshape the labels
y_train = y_train.reshape(y_train.shape[0], -1)
y_test = y_test.reshape(y_test.shape[0], -1)
print('Training labels shape:', y_train.shape) # (4, 30)
print('Testing labels shape:', y_test.shape) # (2, 30)
# Initialize and fit the model
clf = ak.ImageClassifier(max_trials=3)
clf.fit(x_train, y_train, epochs=1000, batch_size=1, callbacks=[tf.keras.callbacks.EarlyStopping(patience=50)])
# Evaluate the model
print('Model evaluation:', clf.evaluate(x_test, y_test))
In the first source code, I am training a CNN model. In the second source code, I am searching a CNN model using AutoKeras NAS.
In both cases, the sizes/dimensions of the data fed to the CNN are the same.
However, in the latter case, the following two extra lines are needed:
# Reshape the labels
y_train = y_train.reshape(y_train.shape[0], -1)
y_test = y_test.reshape(y_test.shape[0], -1)
Otherwise, the script gives the following errors:
C:\Users\pc\AppData\Local\Programs\Python\Python311\python.exe "C:\Program Files\JetBrains\PyCharm 2021.3.3\plugins\python\helpers\pydev\pydevconsole.py" --mode=client --port=64487
-------------------------------------------------------------------------------
pydev debugger: CRITICAL WARNING: This version of python seems to be incorrectly compiled (internal generated filenames are not absolute)
pydev debugger: The debugger may still function, but it will work slower and may miss breakpoints.
pydev debugger: Related bug: http://bugs.python.org/issue1666807
-------------------------------------------------------------------------------
import sys; print('Python %s on %s' % (sys.version, sys.platform))
sys.path.extend(['C:\\git\\heca_v2', 'C:/git/heca_v2'])
PyDev console: starting.
Python 3.11.5 (tags/v3.11.5:cce6ba9, Aug 24 2023, 14:38:34) [MSC v.1936 64 bit (AMD64)] on win32
runfile('C:/git/heca_v2/src/cnn_search_heca.py', wdir='C:/git/heca_v2/src')
Using TensorFlow backend
2023-11-02 04:58:21.553509: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: SSE SSE2 SSE3 SSE4.1 SSE4.2 AVX, in other operations, rebuild TensorFlow with the appropriate compiler flags.
Training image shape: (4, 10, 8)
Training labels shape: (4, 10, 3)
Testing image shape: (2, 10, 8)
Testing labels shape: (2, 10, 3)
Training labels shape: (4, 10, 3)
Testing labels shape: (2, 10, 3)
Reloading Tuner from .\image_classifier\tuner0.json
Traceback (most recent call last):
File "C:\Users\pc\AppData\Local\Programs\Python\Python311\Lib\code.py", line 90, in runcode
exec(code, self.locals)
File "<input>", line 1, in <module>
File "C:\Program Files\JetBrains\PyCharm 2021.3.3\plugins\python\helpers\pydev\_pydev_bundle\pydev_umd.py", line 198, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Program Files\JetBrains\PyCharm 2021.3.3\plugins\python\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/git/heca_v2/src/cnn_search_heca.py", line 36, in <module>
clf.fit(x_train, y_train, epochs=1000, batch_size=1, callbacks=[tf.keras.callbacks.EarlyStopping(patience=50)])
File "C:\Users\pc\AppData\Local\Programs\Python\Python311\Lib\site-packages\autokeras\tasks\image.py", line 165, in fit
history = super().fit(
^^^^^^^^^^^^
File "C:\Users\pc\AppData\Local\Programs\Python\Python311\Lib\site-packages\autokeras\auto_model.py", line 283, in fit
self._analyze_data(dataset)
File "C:\Users\pc\AppData\Local\Programs\Python\Python311\Lib\site-packages\autokeras\auto_model.py", line 373, in _analyze_data
analyser.update(item)
File "C:\Users\pc\AppData\Local\Programs\Python\Python311\Lib\site-packages\autokeras\analysers\output_analysers.py", line 36, in update
raise ValueError(
ValueError: Expect the target data for classification_head_1 to have shape (batch_size, num_classes), but got [1, 10, 3].
My question is, why does the latter script require those two extra lines of code while the former one doesn't?
Crossposted: https://stackoverflow.com/questions/77406862/why-does-the-autokeras-nas-require-resizing-of-data