【发布时间】:2023-04-02 00:58:02
【问题描述】:
我正在尝试创建一个模型,该模型拍摄两张图像(一张紧接着一张)并对其进行训练,以便它可以预测相机在两张图像之间移动了多少。我使用一个较小的模型,一次处理一张图像,然后将两个输出连接到一个较大的模型中。
我尝试对其进行测试,模型编译得很好,但是当我调用 fit() 时它崩溃并给我一个无效的参数错误。
Epoch 1/5
2021-10-11 11:41:23.993854: I tensorflow/compiler/mlir/mlir_graph_optimization_pass.cc:185] None of the MLIR Optimization Passes are enabled (registered 2)
2021-10-11 11:41:28.606390: I tensorflow/stream_executor/cuda/cuda_dnn.cc:369] Loaded cuDNN version 8200
7/Unknown - 18s 81ms/step - loss: 63.80682021-10-11 11:41:41.279014: W tensorflow/core/framework/op_kernel.cc:1692] OP_REQUIRES failed at transpose_op.cc:143 : Invalid argument: transpose expects a vector of size 3. But input(1) is a vector of size 4
2021-10-11 11:41:41.279317: W tensorflow/core/framework/op_kernel.cc:1692] OP_REQUIRES failed at transpose_op.cc:143 : Invalid argument: transpose expects a vector of size 3. But input(1) is a vector of size 4
Traceback (most recent call last):
File "d:/.../Deep Sight/deep_sight.py", line 155, in <module>
main()
File "d:/.../Deep Sight/deep_sight.py", line 150, in main
final_model.fit(train_data, epochs=5)
File "C:\Users\...\AppData\Local\Programs\Python\Python37\lib\site-packages\keras\engine\training.py", line 1184, in fit
tmp_logs = self.train_function(iterator)
File "C:\Users\...\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\def_function.py", line 885, in __call__
result = self._call(*args, **kwds)
File "C:\Users\...\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\def_function.py", line 917, in _call
return self._stateless_fn(*args, **kwds) # pylint: disable=not-callable
File "C:\Users\...\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\function.py", line 3040, in __call__
filtered_flat_args, captured_inputs=graph_function.captured_inputs) # pylint: disable=protected-access
File "C:\Users\...\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\function.py", line 1964, in _call_flat
ctx, args, cancellation_manager=cancellation_manager))
File "C:\Users\...\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\function.py", line 596, in call
ctx=ctx)
File "C:\Users\...\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\eager\execute.py", line 60, in quick_execute
inputs, attrs, num_outputs)
tensorflow.python.framework.errors_impl.InvalidArgumentError: 2 root error(s) found.
(0) Invalid argument: transpose expects a vector of size 3. But input(1) is a vector of size 4
[[{{node gradient_tape/model_1/model/conv2d/Conv2D/Conv2DBackpropFilter-0-TransposeNHWCToNCHW-LayoutOptimizer}}]]
[[Func/mean_squared_error/cond/then/_0/input/_29/_48]]
(1) Invalid argument: transpose expects a vector of size 3. But input(1) is a vector of size 4
[[{{node gradient_tape/model_1/model/conv2d/Conv2D/Conv2DBackpropFilter-0-TransposeNHWCToNCHW-LayoutOptimizer}}]]
0 successful operations.
0 derived errors ignored. [Op:__inference_train_function_3137]
Function call stack:
train_function -> train_function
按照我的数据集中的定义,我的批量大小是 32。我相信这与我使用 tf.Datasets 的方式有关。以前,我只是将所有数据加载到内存中,模型运行得很好。但是,因为我的数据集现在要大得多,所以我转而使用 tf.Datasets 来输入数据。这要求我将 2 张图像一起输入到一个张量中作为输入。它还需要我添加 tf.split 和挤压方法来分离模型内的图像。
train_data的形状是一个嵌套结构,如下: (批次:32,特征:[2, 128, 128, 3],标签:标量(两幅图像之间的垂直移动))
def load_data(image_files):
image_file, image_file2 = bytes.decode(image_files.numpy()[0]), bytes.decode(image_files.numpy()[1])
# Extract number of png file
run_folder = image_file[:image_file.rfind('\\')][:-6]
pic_number = int(image_file[image_file.rfind('\\')+1:image_file.find('.')])
# Grab the y positions for the indicated pictures, then find their difference
with open(run_folder+"\\yPos.txt", 'r') as yPosFile:
for _ in range(pic_number):
yPosFile.readline()
oldY = float(yPosFile.readline())
dY = float(yPosFile.readline()) - oldY
# Load in the images from their file names, and strip the Alpha value from the RGBA values. It's always 255, so we don't need that extra data.
image = imageio.imread(image_file)
# Scale the RGB data down to between 0-1 so that the model has an easier time creating weights.
return image[:, :, :-1]/255, imageio.imread(image_file2)[:, :, :-1]/255, dY
# Takes the list of output from the load_data function (which must be wrapped in tf.py_function)
# and outputs the data in the nested structure necessary for training, which the map function can process.
# Unfortunately, the py_function cannot output nested data structures, so we have to do a little wrapping here.
def load_data_wrapper(image_files):
image, image2, dY = tf.py_function(load_data, [image_files], [tf.float32, tf.float32, tf.float32])
return ([image, image2], dY)
# Takes dataset like [0, 1, 2, 3, 4]
# and converts it to: [[0,1],[1,2],[2,3],[3,4]]
def prep_dataset(dtst):
# First repeat individual elements, then print those repeated elements after each other
dtst = dtst.interleave(lambda x: tf.data.Dataset.from_tensors(x).repeat(2), cycle_length=2, block_length=2)
# Skip the first element so that numbers are paired with the next greatest in the sequence with the batch function.
return dtst.skip(1).batch(2, drop_remainder=True) #.take_while(lambda x: tf.squeeze(tf.greater(tf.shape(x), 1)))
def tf_load_data():
runs = os.listdir("Data")
image_datasets = None
for run in runs:
image_dataset = tf.data.Dataset.list_files("Data/"+run+"/photos/?.png", shuffle=False).apply(prep_dataset)
image_dataset = image_dataset.map(load_data_wrapper, num_parallel_calls=tf.data.experimental.AUTOTUNE)
if image_datasets == None:
image_datasets = image_dataset
else:
image_datasets = image_datasets.concatenate(image_dataset)
#print(image_datasets)
image_datasets = image_datasets.shuffle(buffer_size=int(599*25/32)).batch(32)
# for data in image_datasets.take(1):
# print(data)
return image_datasets
def main():
# Create model
# Start with smaller model that processes the two images in the same way.
single_image_input = keras.Input(shape=(128,128,3))
image = layers.Conv2D(64, (3,3))(single_image_input)
image = layers.LeakyReLU()(image)
image = layers.BatchNormalization()(image)
# Run through MaxPool2D to help the algorithm identify features in different areas of the image.
# Has the effect of downsampling and cutting the dimensions in half.
image = layers.MaxPool2D()(image)
image = layers.Conv2D(128, (3, 3))(image)
image = layers.LeakyReLU()(image)
image = layers.BatchNormalization()(image)
image = layers.Dropout(.3)(image)
image_model = keras.Model(single_image_input, image)
# Create larger model
image_inputs = keras.Input(shape=(2,128,128,3))
first_image, second_image = tf.split(image_inputs, num_or_size_splits=2, axis=1)
first_image, second_image = tf.squeeze(first_image), tf.squeeze(second_image)
image_outputs = [image_model(first_image), image_model(second_image)]
model = layers.Concatenate()(image_outputs)
model = layers.Flatten()(model)
model = layers.Dense(128)(model)
model = layers.LeakyReLU()(model)
model = layers.BatchNormalization()(model)
model = layers.Dropout(.3)(model)
# Output is change in y-position of drone
out_layer = layers.Dense(1, activation='linear')(model)
final_model = keras.Model(image_inputs, out_layer)
final_model.compile(loss="mse", optimizer=optimizers.Adam(lr=0.0003, beta_1=0.7))
image_model.summary()
final_model.summary()
#Preprocess data
print("Loading and processing data...")
train_data = tf_load_data()
#Train model
final_model.fit(train_data, epochs=5)
if __name__ == "__main__":
main()
#tf_load_data()
这是我的完整代码文件和我正在使用的数据示例,以防万一:Data
【问题讨论】:
-
您需要为这两个图像创建两个
Input层。不要使用tf.squeeze和tf.split,因为它们不可区分。 -
我确认完整模型在合成数据上运行良好,问题似乎出在数据集上。您能否分享数据或告诉我们在哪里可以找到它进行测试?
-
@ShubhamPanchal 我尝试使用两个
Input层而不是拆分,但是模型在完成编译之前抛出一个错误,说我只提供了一个输入张量。它似乎将我的数据集解释为一个形状为(2, 128, 128, 3)的张量,而不是两个形状为(128, 128, 3)的张量。 -
对我之前评论的小修正。当我调用 fit() 期望 2 个输入但接收到一个时,它会出错。另外,我在帖子中提供了我的一些数据的链接。
标签: python tensorflow keras