TensorFlow CNN报错:输出深度无法被组数整除,如何解决?
卷积操作报错:输出深度与组数不匹配
问题背景
基于Kaggle机器视觉课程实现CNN时,运行代码抛出错误,仅能显示原始车辆图像和卷积核,后续无输出。谷歌搜索后未找到匹配的解决方案。
原始代码
import numpy as np from itertools import product import tensorflow as tf import matplotlib.pyplot as plt import sys import keras from keras import layers def show_kernel(kernel, label=True, digits=None, text_size=28): # Format kernel kernel = np.array(kernel) if digits is not None: kernel = kernel.round(digits) # Plot kernel cmap = plt.get_cmap('Blues_r') plt.imshow(kernel, cmap=cmap) rows, cols = kernel.shape thresh = (kernel.max() + kernel.min())/2 # Optionally, add value labels if label: for i, j in product(range(rows), range(cols)): val = kernel[i, j] color = cmap(0) if val > thresh else cmap(255) plt.text(j, i, val, color=color, size=text_size, horizontalalignment='center', verticalalignment='center') plt.xticks([]) plt.yticks([]) plt.rc('figure', autolayout=True) plt.rc('axes', labelweight='bold', labelsize='large', titleweight='bold', titlesize=18, titlepad=10) plt.rc('image', cmap='magma') img_source = sys.path[0] + "/car_feature.png" image_path = img_source image = tf.io.read_file(image_path) image = tf.io.decode_png(image) plt.figure(figsize=(6, 6)) plt.imshow(tf.squeeze(image), cmap='gray') plt.axis('off') kernel = tf.constant([ [-1, -1, -1], [-1, 8, -1], [-1, -1, -1], ]) plt.figure(figsize=(3, 3)) # Reformat for batch compatibility. image = tf.image.convert_image_dtype(image, dtype=tf.float32) image = tf.expand_dims(image, axis=0) kernel = tf.reshape(kernel, [*kernel.shape, 1, 1]) kernel = tf.cast(kernel, dtype=tf.float32) image_filter = tf.nn.conv2d( input=image, filters=kernel, strides=1, padding='SAME', ) plt.figure(figsize=(6, 6)) plt.imshow(tf.squeeze(image_filter)) plt.axis('off') plt.show();
报错信息
Traceback (most recent call last): File "c:\Users\q621208\WorkSpace\Tensorflow\Keras\cnn_relu.py", line 64, in <module> image_filter = tf.nn.conv2d( File "C:\Users\q621208\AppData\Local\Programs\Python\Python310\lib\site-packages\tensorflow\python\util\traceback_utils.py", line 153, in error_handler raise e.with_traceback(filtered_tb) from None File "C:\Users\q621208\AppData\Local\Programs\Python\Python310\lib\site-packages\tensorflow\python\framework\ops.py", line 7262, in raise_from_not_ok_status raise core._status_to_exception(e) from None # pylint: disable=protected-access tensorflow.python.framework.errors_impl.InvalidArgumentError: {{function_node __wrapped__Conv2D_device_/job:localhost/replica:0/task:0/device:CPU:0}} output depth must be evenly divisible by number of groups: 1 vs 4 [Op:Conv2D]
期望效果
得到经过卷积核处理后的车辆图像(边缘增强效果),原始图像为彩色车辆图,处理后图像应突出车辆轮廓。
错误原因
tf.io.decode_png读取的PNG图像默认是4通道(RGBA,包含透明度通道),而定义的卷积核是单通道(适配灰度图),导致卷积操作时输入通道数(4)与核的输入通道数(1)不匹配,触发组数不兼容的错误。
解决方法
有两种可行方案:
方案1:将图像转为单通道灰度图
在读取图像后添加一行代码,把4通道图像转成灰度图:
image = tf.io.decode_png(image) # 添加此行 image = tf.image.rgb_to_grayscale(image)
方案2:调整卷积核适配4通道输入
如果需要保留彩色图像,将单通道卷积核复制4份,匹配输入的4通道:
kernel = tf.reshape(kernel, [*kernel.shape, 1, 1]) kernel = tf.cast(kernel, dtype=tf.float32) # 添加此行,将核复制4份适配4通道 kernel = tf.tile(kernel, [1,1,4,1])
修改后的完整代码(方案1示例)
import numpy as np from itertools import product import tensorflow as tf import matplotlib.pyplot as plt import sys import keras from keras import layers def show_kernel(kernel, label=True, digits=None, text_size=28): # Format kernel kernel = np.array(kernel) if digits is not None: kernel = kernel.round(digits) # Plot kernel cmap = plt.get_cmap('Blues_r') plt.imshow(kernel, cmap=cmap) rows, cols = kernel.shape thresh = (kernel.max() + kernel.min())/2 # Optionally, add value labels if label: for i, j in product(range(rows), range(cols)): val = kernel[i, j] color = cmap(0) if val > thresh else cmap(255) plt.text(j, i, val, color=color, size=text_size, horizontalalignment='center', verticalalignment='center') plt.xticks([]) plt.yticks([]) plt.rc('figure', autolayout=True) plt.rc('axes', labelweight='bold', labelsize='large', titleweight='bold', titlesize=18, titlepad=10) plt.rc('image', cmap='magma') img_source = sys.path[0] + "/car_feature.png" image_path = img_source image = tf.io.read_file(image_path) image = tf.io.decode_png(image) # 转为灰度图 image = tf.image.rgb_to_grayscale(image) plt.figure(figsize=(6, 6)) plt.imshow(tf.squeeze(image), cmap='gray') plt.axis('off') kernel = tf.constant([ [-1, -1, -1], [-1, 8, -1], [-1, -1, -1], ]) plt.figure(figsize=(3, 3)) show_kernel(kernel) # 显示卷积核 # Reformat for batch compatibility. image = tf.image.convert_image_dtype(image, dtype=tf.float32) image = tf.expand_dims(image, axis=0) kernel = tf.reshape(kernel, [*kernel.shape, 1, 1]) kernel = tf.cast(kernel, dtype=tf.float32) image_filter = tf.nn.conv2d( input=image, filters=kernel, strides=1, padding='SAME', ) plt.figure(figsize=(6, 6)) plt.imshow(tf.squeeze(image_filter), cmap='gray') plt.axis('off') plt.show();
内容的提问来源于stack exchange,提问作者Ratmir
相关产品推荐
相关产品推荐

