I am training a DNN with keras for a regression model, I have a n inputs and n outputs and the model is the following
# init the model
self._model = Sequential()
self._model.add(Dense(self._n, input_dim=self._n, kernel_initializer='normal', activation='relu'))
self._model.add(Dense(self._n + 10, activation='relu'))
self._model.add(Dense(self._n + 10, activation='relu'))
self._model.add(Dense(self._n, activation='linear'))
# self._model.summary()
self._model.compile(loss='mse', optimizer='adam', metrics=['mse', 'mae'])
I read the data from a simple .txt file that has a fixed lines size, so I can do seek for quickly retrieving the line. Therefore, with a custom data generator I create batches of data by shuffling the line indexes at every epoch. The problem is that when I start training the network, whatever is the batch size from 16 to 2048, I get intensive tasks on CPU and for 1 epoch of about 500'000 lines it estimates about 3 hours (the txt file size is about 60mb), is that normal? I mean, I have 16gb of RAM, could it be convenient to load the entire file in memory? And why I get that the most of the operation are CPU bound? Is there something wrong in the way I create the dataset?
The placement logging is 98% with the following lines
2020-04-12 11:41:16.829552: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op MapDataset in device /job:localhost/replica:0/task:0/device:CPU:0
2020-04-12 11:41:16.829917: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op PrefetchDataset in device /job:localhost/replica:0/task:0/device:CPU:0
2020-04-12 11:41:16.837311: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op FlatMapDataset in device /job:localhost/replica:0/task:0/device:CPU:0
2020-04-12 11:41:16.837884: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op TensorDataset in device /job:localhost/replica:0/task:0/device:CPU:0
2020-04-12 11:41:16.838019: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op RepeatDataset in device /job:localhost/replica:0/task:0/device:CPU:0
2020-04-12 11:41:16.838178: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op ZipDataset in device /job:localhost/replica:0/task:0/device:CPU:0
2020-04-12 11:41:16.841638: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op ParallelMapDataset in device /job:localhost/replica:0/task:0/device:CPU:0
2020-04-12 11:41:16.842229: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op ModelDataset in device /job:localhost/replica:0/task:0/device:CPU:0
2020-04-12 11:41:16.849076: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op RangeDataset in device /job:localhost/replica:0/task:0/device:CPU:0
2020-04-12 11:41:16.849240: I tensorflow/core/common_runtime/eager/execute.cc:573] Executing op RepeatDataset in device /job:localhost/replica:0/task:0/device:CPU:0
The remaining 2% of these ones
input_iterator: (_Arg): /job:localhost/replica:0/task:0/device:CPU:0
input_iterator_1: (_Arg): /job:localhost/replica:0/task:0/device:CPU:0
sequential_1_dense_4_matmul_readvariableop_resource: (_Arg): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1_dense_4_biasadd_readvariableop_resource: (_Arg): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1_dense_5_matmul_readvariableop_resource: (_Arg): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1_dense_5_biasadd_readvariableop_resource: (_Arg): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1_dense_6_matmul_readvariableop_resource: (_Arg): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1_dense_6_biasadd_readvariableop_resource: (_Arg): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1_dense_7_matmul_readvariableop_resource: (_Arg): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1_dense_7_biasadd_readvariableop_resource: (_Arg): /job:localhost/replica:0/task:0/device:GPU:0
IteratorGetNext: (IteratorGetNext): /job:localhost/replica:0/task:0/device:CPU:0
Cast: (Cast): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_4/MatMul/ReadVariableOp: (ReadVariableOp): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_4/MatMul: (MatMul): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_4/BiasAdd/ReadVariableOp: (ReadVariableOp): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_4/BiasAdd: (BiasAdd): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_4/Relu: (Relu): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_5/MatMul/ReadVariableOp: (ReadVariableOp): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_5/MatMul: (MatMul): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_5/BiasAdd/ReadVariableOp: (ReadVariableOp): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_5/BiasAdd: (BiasAdd): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_5/Relu: (Relu): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_6/MatMul/ReadVariableOp: (ReadVariableOp): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_6/MatMul: (MatMul): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_6/BiasAdd/ReadVariableOp: (ReadVariableOp): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_6/BiasAdd: (BiasAdd): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_6/Relu: (Relu): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_7/MatMul/ReadVariableOp: (ReadVariableOp): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_7/MatMul: (MatMul): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_7/BiasAdd/ReadVariableOp: (ReadVariableOp): /job:localhost/replica:0/task:0/device:GPU:0
sequential_1/dense_7/BiasAdd: (BiasAdd): /job:localhost/replica:0/task:0/device:GPU:0
Identity: (Identity): /job:localhost/replica:0/task:0/device:GPU:0
identity_RetVal: (_Retval): /job:localhost/replica:0/task:0/device:GPU:0
Const: (Const): /job:localhost/replica:0/task:0/device:GPU:0
def __getitem__(self, index):
"""Generate one batch of data
:param index: index of the batch
:return: X and y when fitting. X only when predicting
"""
# Generate indexes of the batch
last_item_for_batch = (index + 1) * self._batch_size if (index + 1) * self._batch_size < len(
self._indexes) else len(self._indexes) - 1
indexes = self._indexes[index * self._batch_size: last_item_for_batch]
# Find list of IDs
data_ids_temp = indexes # [self._indexes[k] for k in indexes]
# Generate data
x_arr = self._generate_x_arr(data_ids_temp)
self._total_requested_batches += 1
if self._to_fit:
y_arr = self._generate_y_arr(data_ids_temp)
return x_arr, y_arr, [None]
else:
return x_arr
def on_epoch_end(self):
"""Updates indexes after each epoch"""
self._total_requested_batches = 0
if self._shuffle:
np.random.shuffle(self._indexes)
def _generate_x_arr(self, data_ids_temp):
"""Generates data containing batch_size images (shape [batch_size, n])
:param list_IDs_temp: list of label ids to load
:return: batch of images
"""
# Initialization
x_arr = np.empty((self._batch_size, self._n_nodes))
for i, line_number in enumerate(data_ids_temp):
line = self._get_data_file_line(line_number)
components = line.split(" ")
input_data = [] # the state of all nodes
# parse input
for j in range(self._n_nodes):
input_data.append(float(components[j]))
x_arr[i,] = np.asarray(input_data)
return x_arr
def _generate_y_arr(self, data_ids_temp):
"""Generates data containing batch_size masks
:param list_IDs_temp: list of label ids to load
:return: batch if masks
"""
# Initialization
y_arr = np.empty((self._batch_size, self._n_nodes))
for i, line_number in enumerate(data_ids_temp):
line = self._get_data_file_line(line_number)
components = line.split(" ")
input_data = [] # the state of all nodes
target_data = [] # the expected values for all actions
# parse input_data
for j in range(self._n_nodes):
input_data.append(float(components[j]))
action = int(components[self._n_nodes])
reward = float(components[self._n_nodes + 1])
prediction = [[0.0 for i in range(self._n_nodes)]] # these comes from another network
# generate expected value
for j in range(self._n_nodes):
if j == action:
target_data.append(reward - prediction[0][j])
else:
target_data.append(prediction[0][j])
y_arr[i,] = np.asarray(target_data)
return y_arr
def _get_data_file_line(self, line_number) -> str:
"""Get a line in the data file by seeking"""
self._train_file_fp.seek(line_number * self._train_file_line_size)
line = self._train_file_fp.read(self._train_file_line_size).strip()
return line
Thanks to anyone helps me to figure it out what is going on!