I have profiled the data reading with a python loop for loop.
For cleanness, only the loop section is presented.
	for i, db in enumerate(train_dataset.db):
		st = time.time()
		image_file = db['image']
		data_numpy = cv2.imread(
			image_file, cv2.IMREAD_COLOR | cv2.IMREAD_IGNORE_ORIENTATION
		)
		smplRd_tm.update(time.time()- st)
		if i % 100 == 0 :       # print out the time
			print('Time cost {tm.val:.6f}s ({tm.avg:.6f})'.format(tm=smplRd_tm))

The images are supposed to be read continuously without any processing. So it can roughly measure how fast each image is read in from the file system. What I get is:

…
Time cost 0.009754s (0.022841)
Time cost 0.015513s (0.022823)
Time cost 0.034945s (0.022812)
Time cost 0.012610s (0.022782)
Time cost 0.017248s (0.022775)
Time cost 0.030351s (0.022780)
Time cost 0.030921s (0.022800)
…

So each image reading costs roughly 0.02 s.
I found that bottleneck comes from the debug image saving in the training loop.
I reduced frequency and it is much better now.
Thanks.