5

我正在尝试使用 TensorFlow 和 TensorFlow Probability 实现期望最大化算法。在我尝试实现缺失数据(数据可以包含某些随机维度的 NaN 值)之前,它运行良好。

问题是,使用缺失数据我不能再将所有操作作为向量操作,我必须使用索引和 for 循环,如下所示:

    # Here we iterate through all the data samples
    for i in range(n):
        # x_i is the sample i
        x_i = tf.expand_dims(x[:, i], 1)
        gamma.append(estimate_gamma(x_i, pi, norm, ber))
        est_x_n_i = []
        est_xx_n_i = []
        est_x_b_i = []
        for j in range(k):
            mu_k = norm.mean()[j, :]
            sigma_k = norm.covariance()[j, :, :]
            rho_k = ber.mean()[j, :]
            est_x_n_i.append(estimate_x_norm(x_i[:d, :], mu_k, sigma_k))
            est_xx_n_i.append(estimate_xx_norm(x_i[:d, :], mu_k, sigma_k))
            est_x_b_i.append(estimate_x_ber(x_i[d:, :], rho_k))
        est_x_n.append(tf.convert_to_tensor(est_x_n_i))
        est_xx_n.append(tf.convert_to_tensor(est_xx_n_i))
        est_x_b.append(tf.convert_to_tensor(est_x_b_i))

我发现这些操作效率不高。虽然第一个样本每个样本大约需要不到 1 秒,但在 50 个样本之后,每个样本大约需要 3 秒。我猜这是因为我在会话中创建了不同的张量,这会弄乱内存或其他东西。

我对使用 TensorFlow 很陌生,很多人只将 TensorFlow 用于深度学习和神经网络,所以我找不到解决方案。

然后我尝试仅使用 numpy 数组和 numpy 操作来实现前面的 for 循环和在该循环内调用的函数。但这返回了以下错误:

您必须使用 dtype double 和 shape [8,18] 为占位符张量“Placeholder_4”提供一个值

发生此错误是因为当它尝试在循环内执行 numpy 函数时,尚未输入占位符。

pi_k, mu_k, sigma_k, rho_k, gamma_ik, exp_loglik = exp_max_iter(x, pi, dist_norm, dist_ber)
pi, mu, sigma, rho, responsability, NLL[i + 1] = sess.run([pi_k, mu_k, sigma_k, rho_k, gamma_ik, exp_loglik],{x: samples})

有没有办法解决这个问题?谢谢。

4

2 回答 2

1

为了回答您的标题问题“有没有办法在 TensorFlow 会话中调用 Numpy 函数?”,我在一些示例代码下方放置了一些示例代码,sklearn.mixture.GaussianMixture通过直接调用函数或在给定缺失数据的情况下执行“numpy 函数”()通过 TensorFlow 的py_function. 我感觉这可能不是 100% 是你正在寻找的......如果你只是想实现 EM..?Tensorflow 中现有的高斯混合模型实现可能会有所帮助:

文档tf.contrib.factorization.gmmhttps ://www.tensorflow.org/api_docs/python/tf/contrib/factorization/gmm

实现: https ://github.com/tensorflow/tensorflow/blob/r1.14/tensorflow/contrib/factorization/python/ops/gmm_ops.py#L462-L506

直接在 Tensorflow 图中调用“numpy 函数”的示例代码:

import numpy as np
np.set_printoptions(2)
import tensorflow as tf
from sklearn.mixture import GaussianMixture as GMM

def myfunc(x,istf=True):
    #strip nans
    if istf:
        mask = ~tf.is_nan(x)
        x = tf.boolean_mask(x,mask)
    else:
        ind=np.where(~np.isnan(x))
        x = x[ind]
    x = np.expand_dims(x,axis=-1)
    gmm = GMM(n_components=2)
    gmm.fit(x)
    m0,m1 = gmm.means_[:,0]    
    return np.array([m0,m1])
# create data with nans
np.random.seed(42)
x = np.random.rand(5,28,1)
c = 5
x.ravel()[np.random.choice(x.size, c, replace=False)] = np.nan

# directly call "numpy function"
for ind in range(x.shape[0]):
    val = myfunc(x[ind,:],istf=False)
    print(val)
    [0.7  0.26]
    [0.15 0.72]
    [0.77 0.2 ]
    [0.65 0.23]
    [0.35 0.87]
# initialization
sess = tf.InteractiveSession()
tf.global_variables_initializer().run()

# create graph
X = tf.placeholder(tf.float32, [28,1])
Y = tf.py_function(myfunc,[X],[tf.float32],name='myfunc')

# call "numpy function" in tensorflow graph
for ind in range(x.shape[0]):
    val = sess.run(Y, feed_dict={X: x[ind,:],})
    print(val)
    [array([0.29, 0.76], dtype=float32)]
    [array([0.72, 0.15], dtype=float32)]
    [array([0.77, 0.2 ], dtype=float32)]
    [array([0.23, 0.65], dtype=float32)]
    [array([0.35, 0.87], dtype=float32)]
于 2019-07-28T16:37:57.940 回答
1

You can convert your numpy function into tensorflow function then it might not create problem when calling inside a session a simple function is following. Make an IOU function in numpy and then call it via tf.numpy_functionhere

def IOU(Pred, GT, NumClasses, ClassNames):
    ClassIOU=np.zeros(NumClasses)#Vector that Contain IOU per class
    ClassWeight=np.zeros(NumClasses)#Vector that Contain Number of pixel per class Predicted U Ground true (Union for this class)
    for i in range(NumClasses): # Go over all classes
        Intersection=np.float32(np.sum((Pred==GT)*(GT==i)))# Calculate class intersection
        Union=np.sum(GT==i)+np.sum(Pred==i)-Intersection # Calculate class Union
        if Union>0:
            ClassIOU[i]=Intersection/Union# Calculate intesection over union
            ClassWeight[i]=Union
            
    # b/c we will only take the mean over classes that are actually present in the GT
    present_classes = np.unique(GT) 
    mean_IOU = np.mean(ClassIOU[present_classes])
    # append it in final results
    ClassNames = np.append(ClassNames, 'Mean')
    ClassIOU = np.append(ClassIOU, mean_IOU)
    ClassWeight = np.append(ClassWeight, np.sum(ClassWeight))
    
    return mean_IOU
# an now call as
NumClasses=6
ClassNames=['Background', 'Class_1', 'Class_1',
            'Class_1 ', 'Class_1', 'Class_1 ']
x = tf.numpy_function(Strict_IOU, [y_pred, y_true, NumClasses, ClassNames], 
                        tf.float64, name=None)
于 2021-04-09T06:35:15.513 回答