在具有多gpu环境的Keras中使用tf.image.resize_双线性时,获取InvalidArgumentError

在具有多gpu环境的Keras中使用tf.image.resize_双线性时,获取InvalidArgumentError,keras,Keras,我在分割网络中使用了tf.image.resize_双线性,似乎这个函数不支持多gpu模型。下面的代码显示了简化的情况:(可以直接运行) 导入操作系统 os.environ[“CUDA_可视设备”]=“0,1” 从keras.backend.tensorflow_后端导入集_会话 从keras导入后端为K 从keras.utils导入多个gpu模型 从keras.applications.mobilenet_v2导入预处理输入 导入tensorflow作为tf 将numpy作为np导入 conf

我在分割网络中使用了tf.image.resize_双线性,似乎这个函数不支持多gpu模型。下面的代码显示了简化的情况:(可以直接运行)

导入操作系统
os.environ[“CUDA_可视设备”]=“0,1”
从keras.backend.tensorflow_后端导入集_会话
从keras导入后端为K
从keras.utils导入多个gpu模型
从keras.applications.mobilenet_v2导入预处理输入
导入tensorflow作为tf
将numpy作为np导入
config=tf.ConfigProto()
config.gpu\u options.allow\u growth=True
config.allow_soft_placement=True
sess=tf.Session(config=config)
设置会话(sess)
批次=4
num_classes=2
尺寸=128
K.清除会话()
def_GetRandomImg():
形状=(批次、大小、大小,3)
img=np.random.randint(低=0,高=256,大小=shape)
返回预处理输入(img)
def_GetRandomLabel():
形状=(批次、大小、大小、数量类)
label=np.random.randint(低=0,高=num\u类,大小=shape)
label=np.exp(label)
label=label/np.sum(label,axis=-1,keepdims=True)
退货标签
def DataGen():
尽管如此:
x=_GetRandomImg()
y=_GetRandomLabel()
产量x,y
从keras.layers导入输入,Conv2D,Lambda
从keras导入模型
def GetModel():
输入=输入(形状=(大小,大小,3))
f=lambda x:tf.image.resize\u双线性(输入,(大小,大小),对齐\u角=真)
x=Lambda(f,输出_形状=(大小,大小,3))(输入)
输出=Conv2D(num\u类,内核大小=3,padding='same')(x)
模型=模型(输入=[输入],输出=[输出])
回归模型
gen=DataGen()
使用tf.device('/cpu:0'):
model=GetModel()
模型=多gpu模型(模型,gpu=2)
编译(loss='classifical\u crossentropy',optimizer='sgd')
结果=模型拟合生成器(gen,历元=2,详细=1,每历元步数=100)
它在单gpu环境下工作正常,但在多gpu环境下,我得到以下错误:

InvalidArgumentError: Incompatible shapes: [3,128,128,2] vs. [6,128,128,2]
     [[{{node loss/conv2d_1_loss/categorical_crossentropy/mul}}]]
     [[{{node training/SGD/gradients/conv2d_1_1/concat_grad/Slice_1}}]]

问题解决了。如果tensorflow函数用于自定义Lambda层,则需要显式使用set_shape()函数:

def MyResize线性(x、高度、宽度):
行,cols=1,2
原始形状=K.int形状(x)
new_shape=tf.constant(np.array([height,width],dtype='int32'))
x=tf.image.resize\u双线性(x,新形状,对齐角=True)
如果原始形状[行]不是其他高度,则新建高度=无
如果原始_形状[cols]不是其他宽度,则新_宽度=无
输出形状=(无,新高度,新宽度,无)
x、 设置形状(输出形状)
返回x

问题解决了。如果tensorflow函数用于自定义Lambda层,则需要显式使用set_shape()函数:

def MyResize线性(x、高度、宽度):
行,cols=1,2
原始形状=K.int形状(x)
new_shape=tf.constant(np.array([height,width],dtype='int32'))
x=tf.image.resize\u双线性(x,新形状,对齐角=True)
如果原始形状[行]不是其他高度,则新建高度=无
如果原始_形状[cols]不是其他宽度,则新_宽度=无
输出形状=(无,新高度,新宽度,无)
x、 设置形状(输出形状)
返回x