Tensorflow中将字符串tensor转换为普通的字符串以及遇到的坑

最近遇到个需求,在使用tensoflow.data.Dataset加载dicom文件时,需要先根据文件名字划分训练集和测试集,然后再使用map函数分别将训练集和测试集逐一加载进tensorflow,其中踩了很多坑。

大体思路是使用tensor实例的numpy()函数将tensor转化为numpy数组,这个时候得到的是byte类型法的东西,再使用str函数得到字符串,但是这个字符串相比于真实字符串又会在开头和结尾多一些东西,使用[start:end]这个slice操作就可以截取出原始字符串,真正的坑在下面。

1 在map传进的实参函数提示tensor没有numpy()属性

这个坑一上网查都说是没有开启eager模式,针对tf1这个可能是完全正确的,网上很多的解决办法是开启eager模式,但是tf2.0里面默认是开启了eager模式的,又如何再去开启eager模式呢?这个问题的主要坑在于tf.data.Dataset.map函数。因为它默认走的是graph模式。Tensorflow2.x中有两种tensor:特殊的tensor和一般的EagerTensor,一般的EagerTensor是有numpy()属性的,而另一种特殊的tensor则没有。所以为了达到我们的目的(即:让map实参函数里的tensor具有numpy()属性),需要使用tf.py_functiom()函数包裹,具体代码如下:

# 定义处理函数,即我博客里说的实参函数,不加包裹函数的时候,这个函数才是map函数的实际参数,所以我这么叫它
def process(path):
    path = str(path.numpy())[2:-1]
    x = INPUT_DIRS + '/' + path # INPUT_DIR是我自定义的一个绝对路径
    # tf.print(x)
    X = dicom_process.process_single(x)
    tf.print(X.shape, "*****", x)
    X = tf.cast(X, dtype=tf.float32)

    # tf.print(y)
    return X


# 包裹函数
def wrap_process(path, y):
    # tf.py_function()包裹实参函数,注意py_function函数的写法,返回值要用[]括起来,Tout是X的元素类型,无论是二维还是三维矩阵,都应该是矩阵元素的类型
    [X, ] = tf.py_function(process, inp=[path], Tout=[tf.float32])
    X = tf.expand_dims(X, -1) # 三维向量X*Y*Z转成X*Y*Z*1
    y = tf.one_hot(y, depth=Classes, dtype=tf.int32) # 这里的Classes是我的自定义整型变量
    return X, y


#sklearn里面的划分测试集和训练集的函数,这里patients是一些代表相对路径的字符串,labels是一组数字标签
train_x, test_x, train_y, test_y = train_test_split(patient_files, labels, test_size=0.2, shuffle=True)

train_data = tf.data.Dataset.from_tensor_slices((train_x, train_y))
test_data = tf.data.Dataset.from_tensor_slices((test_x, test_y))

# map函数的实参函数变成了包裹函数,不再是真正的处理函数了
train_db = train_data.map(wrap_process).batch(Batch_Size) # map函数
test_db = test_data.map(wrap_process).batch(Batch_Size)

2 劝退tensorflow

tensorflow很难调试,不支持python的断点操作,对于初学者难以上手,建议pytorch。为了搭一个三D卷积神经网络进行医学图像分类,我抄代码抄了将近一星期还没成功,总是各种报错(还有自己太菜的原因)以及无法定位报错原因。然后用pytorch去搭网络:网上抄了份代码,逐步的运行和打断点调试,基本用了两天就搭好了三维卷积模型(速度提升了这么多可能也还有之前前几天的积累),还是pytorch对新手友好点

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值