Tensorflow模型在GCP上 – 将JSON预测请求转换为正确的模型输入

我使用Wild ML实现的CNN模型进行了训练,该模型可以在这里找到,并已将其部署到Google Cloud Platform。现在我尝试向模型发送JSON预测请求,但遇到了以下错误:

Traceback (most recent call last):  File "C:/Users/XXX/PycharmProjects/CNN-Prediction/prediction.py", line 73, in <module>    print(predict_json(project, model, [json_request], version="TestV2"))  File "C:/Users/XXX/PycharmProjects/CNN-Prediction/prediction.py", line 63, in predict_json    raise RuntimeError(response['error'])RuntimeError: Prediction failed: Error during model execution: AbortionError(code=StatusCode.INVALID_ARGUMENT, details="Shape [-1,11] has negative dimensions     [[Node: input_y = Placeholder[_output_shapes=[[-1,11]], dtype=DT_FLOAT, shape=[?,11], _device="/job:localhost/replica:0/task:0/cpu:0"]()]]")

我发现理解这个错误有一定的挑战,但我认为这可能是因为我向模型发送了JSON数据,而模型需要接受一个整数数组,这一点可以在下面的TextCNN类中看到。

问题:在代码的哪个位置以及如何实现修改,以便将JSON输入请求转换为模型可以操作的格式?

  class TextCNN(object):"""用于文本分类的CNN。使用嵌入层,后跟卷积、最大池化和softmax层。"""# 构造函数 - sequence length = 投诉中的gram数量, num_classes = 类别数量, vocab_size, embedding_size = 嵌入的维度def __init__(        self, sequence_length, num_classes, vocab_size,        embedding_size, filter_sizes, num_filters, l2_reg_lambda=0.0):    # 输入、输出和dropout的占位符    self.input_x = tf.placeholder(tf.int32, [None, sequence_length],                                  name="input_x")  # 神经网络接口用于接受投诉    self.input_y = tf.placeholder(tf.float32, [None, num_classes],                                  name="input_y")  # 神经网络接口用于接受投诉标签    self.dropout_keep_prob = tf.placeholder(tf.float32, name="dropout_keep_prob")    # 跟踪l2正则化损失(可选)    l2_loss = tf.constant(0.0)    # 嵌入层 - 将词汇表中的词索引映射到低维向量表示(基本上是查找表)    # name_scope - 将所有操作添加到顶级节点'embedding'中 - 在TensorBoard中可视化时有很好的层次结构    # 嵌入层    with tf.device('/cpu:0'), tf.name_scope("embedding"):        self.W = tf.Variable(            tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0), trainable=False,            name="W")        self.embedded_chars = tf.nn.embedding_lookup(self.W,                                                     self.input_x)  # 使用权重矩阵将投诉中的词索引映射    self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars,                                                      -1)  # 扩展张量的维度,以便使用conv2d    # 为每个滤波器大小创建一个卷积 + 最大池化层    # 由于我们有不同大小的滤波器,每个卷积产生不同形状的张量,因此我们需要迭代它们,    pooled_outputs = []    for i, filter_size in enumerate(filter_sizes):        with tf.name_scope("conv-maxpool-%s" % filter_size):            # 卷积层            filter_shape = [filter_size, embedding_size, 1, num_filters]            W = tf.Variable(tf.truncated_normal(filter_shape, stddev=0.1), name="W")            b = tf.Variable(tf.constant(0.1, shape=[num_filters]), name="b")            conv = tf.nn.conv2d(                self.embedded_chars_expanded,                W,                strides=[1, 1, 1, 1],                padding="VALID",                name="conv")            # 应用非线性            h = tf.nn.relu(tf.nn.bias_add(conv, b), name="relu")            # 在输出上进行最大池化            pooled = tf.nn.max_pool(                h,                ksize=[1, sequence_length - filter_size + 1, 1, 1],                strides=[1, 1, 1, 1],                padding='VALID',                name="pool")            pooled_outputs.append(pooled)    # 组合所有池化特征    num_filters_total = num_filters * len(filter_sizes)    print(pooled_outputs)    self.h_pool = tf.concat(pooled_outputs, axis=3)    self.h_pool_flat = tf.reshape(self.h_pool, [-1, num_filters_total])    # 添加dropout    with tf.name_scope("dropout"):        self.h_drop = tf.nn.dropout(self.h_pool_flat, self.dropout_keep_prob)    # 最终(未归一化)的分数和预测    with tf.name_scope("output"):        W = tf.get_variable(            "W",            shape=[num_filters_total, num_classes],            initializer=tf.contrib.layers.xavier_initializer())        b = tf.Variable(tf.constant(0.1, shape=[num_classes]), name="b")        l2_loss += tf.nn.l2_loss(W)        l2_loss += tf.nn.l2_loss(b)        self.scores = tf.nn.xw_plus_b(self.h_drop, W, b, name="scores")        self.predictions = tf.argmax(self.scores, 1, name="predictions")    # 计算平均交叉熵损失    with tf.name_scope("loss"):        print(self.scores)        print(self.input_y)        losses = tf.nn.softmax_cross_entropy_with_logits(logits=self.scores, labels=self.input_y)        self.loss = tf.reduce_mean(losses) + l2_reg_lambda * l2_loss    # 准确率    with tf.name_scope("accuracy"):        correct_predictions = tf.equal(self.predictions, tf.argmax(self.input_y, 1))        self.accuracy = tf.reduce_mean(tf.cast(correct_predictions, "float"), name="accuracy")

回答:

这个问题与train.pytext_cnn.py无关。它们用于构建您的模型。在构建模型后,请在eval.py代码中进行以下修改。

首先,您可以使用参数库来获取您的JSON文件。

import argparseparser  = argparser.ArgumentParser()# 输入参数parser.add_argument(      '--eval-file',      help='本地评估数据路径',      nargs='+',      required=True  )args = parser.parse_args()

然后您可以按以下方式执行您的代码:

python eval.py --eval-file 您的JSON文件

然后使用,

import jsonjson.loads(Data) 

args中获取您的数据,或者使用字典库将您的数据转换为以下数组格式:

x_raw = ["key", "Value"] x_test = np.array(list(vocab_processor.transform(x_raw)))

将您的数据转换为x_raw后,上述代码会将您的数据转换为TensorFlow适用的格式。

Related Posts

为什么我们在K-means聚类方法中使用kmeans.fit函数?

我在一个视频中使用K-means聚类技术,但我不明白为…

如何获取Keras中ImageDataGenerator的.flow_from_directory函数扫描的类名?

我想制作一个用户友好的GUI图像分类器,用户只需指向数…

如何查看每个词的tf-idf得分

我试图了解文档中每个词的tf-idf得分。然而,它只返…

如何修复 ‘ValueError: Found input variables with inconsistent numbers of samples: [32979, 21602]’?

我在制作一个用于情感分析的逻辑回归模型时遇到了这个问题…

如何向神经网络输入两个不同大小的输入?

我想向神经网络输入两个数据集。第一个数据集(元素)具有…

逻辑回归与机器学习有何关联

我们正在开会讨论聘请一位我们信任的顾问来做机器学习。一…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注